summaryrefslogtreecommitdiff
path: root/submodule.c
diff options
context:
space:
mode:
authorJacob Keller <jacob.keller@gmail.com>2016-08-31 23:27:25 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-09-01 01:07:10 (GMT)
commitfd47ae6a5b9cc0cfc56c1f7c43db612d26ca4b75 (patch)
tree87f05e2e08d728def4944fdd4914b7c9001583f9 /submodule.c
parent8e6df65015f9a947d9ccca8950c2d60a4600cba2 (diff)
downloadgit-fd47ae6a5b9cc0cfc56c1f7c43db612d26ca4b75.zip
git-fd47ae6a5b9cc0cfc56c1f7c43db612d26ca4b75.tar.gz
git-fd47ae6a5b9cc0cfc56c1f7c43db612d26ca4b75.tar.bz2
diff: teach diff to display submodule difference with an inline diff
Teach git-diff and friends a new format for displaying the difference of a submodule. The new format is an inline diff of the contents of the submodule between the commit range of the update. This allows the user to see the actual code change caused by a submodule update. Add tests for the new format and option. Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'submodule.c')
-rw-r--r--submodule.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/submodule.c b/submodule.c
index 2d88c55..5a62aa2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -442,6 +442,75 @@ out:
clear_commit_marks(right, ~0);
}
+void show_submodule_inline_diff(FILE *f, const char *path,
+ const char *line_prefix,
+ struct object_id *one, struct object_id *two,
+ unsigned dirty_submodule, const char *meta,
+ const char *del, const char *add, const char *reset,
+ const struct diff_options *o)
+{
+ const struct object_id *old = &empty_tree_oid, *new = &empty_tree_oid;
+ struct commit *left = NULL, *right = NULL;
+ struct commit_list *merge_bases = NULL;
+ struct strbuf submodule_dir = STRBUF_INIT;
+ struct child_process cp = CHILD_PROCESS_INIT;
+
+ show_submodule_header(f, path, line_prefix, one, two, dirty_submodule,
+ meta, reset, &left, &right, &merge_bases);
+
+ /* We need a valid left and right commit to display a difference */
+ if (!(left || is_null_oid(one)) ||
+ !(right || is_null_oid(two)))
+ goto done;
+
+ if (left)
+ old = one;
+ if (right)
+ new = two;
+
+ fflush(f);
+ cp.git_cmd = 1;
+ cp.dir = path;
+ cp.out = dup(fileno(f));
+ cp.no_stdin = 1;
+
+ /* TODO: other options may need to be passed here. */
+ argv_array_push(&cp.args, "diff");
+ argv_array_pushf(&cp.args, "--line-prefix=%s", line_prefix);
+ if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
+ argv_array_pushf(&cp.args, "--src-prefix=%s%s/",
+ o->b_prefix, path);
+ argv_array_pushf(&cp.args, "--dst-prefix=%s%s/",
+ o->a_prefix, path);
+ } else {
+ argv_array_pushf(&cp.args, "--src-prefix=%s%s/",
+ o->a_prefix, path);
+ argv_array_pushf(&cp.args, "--dst-prefix=%s%s/",
+ o->b_prefix, path);
+ }
+ argv_array_push(&cp.args, oid_to_hex(old));
+ /*
+ * If the submodule has modified content, we will diff against the
+ * work tree, under the assumption that the user has asked for the
+ * diff format and wishes to actually see all differences even if they
+ * haven't yet been committed to the submodule yet.
+ */
+ if (!(dirty_submodule & DIRTY_SUBMODULE_MODIFIED))
+ argv_array_push(&cp.args, oid_to_hex(new));
+
+ if (run_command(&cp))
+ fprintf(f, "(diff failed)\n");
+
+done:
+ strbuf_release(&submodule_dir);
+ if (merge_bases)
+ free_commit_list(merge_bases);
+ if (left)
+ clear_commit_marks(left, ~0);
+ if (right)
+ clear_commit_marks(right, ~0);
+}
+
void set_config_fetch_recurse_submodules(int value)
{
config_fetch_recurse_submodules = value;