Thread (309 messages) flat view 309 messages, 17 authors, 2018-10-02
STALE2916d

Revision v1 of 2 in this series.

Revisions (2)
  1. v1 current
  2. v2 [diff vs current]

[PATCH 05/18] branch-diff: also show the diff between patches

From: Johannes Schindelin <hidden>
Date: 2018-05-03 15:30:53
Subsystem: the rest · Maintainer: Linus Torvalds

Just like tbdiff, we now show the diff between matching patches. This is
a "diff of two diffs", so it can be a bit daunting to read for the
beginnger.

This brings branch-diff closer to be feature-complete with regard to
tbdiff.

An alternative would be to display an interdiff, i.e. the hypothetical
diff which is the result of first reverting the old diff and then
applying the new diff.

Especially when rebasing often, an interdiff is often not feasible,
though: if the old diff cannot be applied in reverse (due to a moving
upstream), an interdiff can simply not be inferred.

Note: while we now parse diff options such as --color, the effect is not
yet the same as in tbdiff, where also the commit pairs would be colored.
This is left for a later commit.

Signed-off-by: Johannes Schindelin <redacted>
---
 builtin/branch-diff.c | 56 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 7 deletions(-)
diff --git a/builtin/branch-diff.c b/builtin/branch-diff.c
index 59423498194..3b565a37492 100644
--- a/builtin/branch-diff.c
+++ b/builtin/branch-diff.c
@@ -6,6 +6,8 @@
 #include "hashmap.h"
 #include "xdiff-interface.h"
 #include "hungarian.h"
+#include "diff.h"
+#include "diffcore.h"
 
 static const char * const builtin_branch_diff_usage[] = {
 	N_("git rebase--helper [<options>] ( A..B C..D | A...B | base A B )"),
@@ -269,7 +271,31 @@ static const char *short_oid(struct patch_util *util)
 	return find_unique_abbrev(&util->oid, DEFAULT_ABBREV);
 }
 
-static void output(struct string_list *a, struct string_list *b)
+static struct diff_filespec *get_filespec(const char *name, const char *p)
+{
+	struct diff_filespec *spec = alloc_filespec(name);
+
+	fill_filespec(spec, &null_oid, 0, 0644);
+	spec->data = (char *)p;
+	spec->size = strlen(p);
+	spec->should_munmap = 0;
+	spec->is_stdin = 1;
+
+	return spec;
+}
+
+static void patch_diff(const char *a, const char *b,
+			      struct diff_options *diffopt)
+{
+	diff_queue(&diff_queued_diff,
+		   get_filespec("a", a), get_filespec("b", b));
+
+	diffcore_std(diffopt);
+	diff_flush(diffopt);
+}
+
+static void output(struct string_list *a, struct string_list *b,
+		   struct diff_options *diffopt)
 {
 	int i = 0, j = 0;
 
@@ -311,6 +337,9 @@ static void output(struct string_list *a, struct string_list *b)
 			printf("%d: %s ! %d: %s\n",
 			       b_util->matching + 1, short_oid(a_util),
 			       j + 1, short_oid(b_util));
+			if (!(diffopt->output_format & DIFF_FORMAT_NO_OUTPUT))
+				patch_diff(a->items[b_util->matching].string,
+					   b->items[j].string, diffopt);
 			a_util->shown = 1;
 			j++;
 		}
@@ -319,24 +348,37 @@ static void output(struct string_list *a, struct string_list *b)
 
 int cmd_branch_diff(int argc, const char **argv, const char *prefix)
 {
-	int no_patches = 0;
+	struct diff_options diffopt = { 0 };
 	double creation_weight = 0.6;
 	struct option options[] = {
-		OPT_BOOL(0, "no-patches", &no_patches,
-			 N_("short format (no diffs)")),
+		OPT_SET_INT(0, "no-patches", &diffopt.output_format,
+			    N_("short format (no diffs)"),
+			    DIFF_FORMAT_NO_OUTPUT),
 		{ OPTION_CALLBACK,
 			0, "creation-weight", &creation_weight, N_("factor"),
 			N_("Fudge factor by which creation is weighted [0.6]"),
 			0, parse_creation_weight },
 		OPT_END()
 	};
-	int res = 0;
+	int i, j, res = 0;
 	struct strbuf range1 = STRBUF_INIT, range2 = STRBUF_INIT;
 	struct string_list branch1 = STRING_LIST_INIT_DUP;
 	struct string_list branch2 = STRING_LIST_INIT_DUP;
 
+	diff_setup(&diffopt);
+	diffopt.output_format = DIFF_FORMAT_PATCH;
+
 	argc = parse_options(argc, argv, NULL, options,
-			builtin_branch_diff_usage, 0);
+			builtin_branch_diff_usage, PARSE_OPT_KEEP_UNKNOWN);
+
+	for (i = j = 0; i < argc; i++) {
+		int c = diff_opt_parse(&diffopt, argv + i, argc - i, prefix);
+
+		if (!c)
+			argv[j++] = argv[i];
+	}
+	argc = j;
+	diff_setup_done(&diffopt);
 
 	if (argc == 2) {
 		if (!strstr(argv[0], ".."))
@@ -380,7 +422,7 @@ int cmd_branch_diff(int argc, const char **argv, const char *prefix)
 		find_exact_matches(&branch1, &branch2);
 		res = get_correspondences(&branch1, &branch2, creation_weight);
 		if (!res)
-			output(&branch1, &branch2);
+			output(&branch1, &branch2, &diffopt);
 	}
 
 	strbuf_release(&range1);
-- 
2.17.0.395.g6a618d6010f.dirty

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help