On 07/21, Johannes Schindelin via GitGitGadget wrote: > The incredibly useful [`git-tbdiff`](https://github.com/trast/tbdiff) tool to > compare patch series (say, to see what changed between two iterations sent to > the Git mailing list) is slightly less useful for this developer due to the > fact that it requires the `hungarian` and `numpy` Python packages which are > for some reason really hard to build in MSYS2. So hard that I even had to > give up, because it was simply easier to re-implement the whole shebang as a > builtin command.
Thanks for your work making this a built-in! I finally found some time to go through the series, and overall it makes sense to me. I left a few comments here and there, and fwiw I didn't think there's anything major that needs to be addressed. Hope it helps! > The project at https://github.com/trast/tbdiff seems to be dormant, anyway. > Funny (and true) story: I looked at the open Pull Requests to see how active > that project is, only to find to my surprise that I had submitted one in > August 2015, and that it was still unanswered let alone merged. > > While at it, I forward-ported AEvar's patch to force `--decorate=no` because > `git -p tbdiff` would fail otherwise. > > Side note: I work on implementing range-diff not only to make life easier for > reviewers who have to suffer through v2, v3, ... of my patch series, but also > to verify my changes before submitting a new iteration. And also, maybe even > more importantly, I plan to use it to verify my merging-rebases of Git for > Windows (for which I previously used to redirect the pre-rebase/post-rebase > diffs vs upstream and then compare them using `git diff --no-index`). And of > course any interested person can see what changes were necessary e.g. in the > merging-rebase of Git for Windows onto v2.17.0 by running a command like: > > ```sh > base=^{/Start.the.merging-rebase} > tag=v2.17.0.windows.1 > pre=$tag$base^2 > git range-diff $pre$base..$pre $tag$base..$tag > ``` > > The command uses what it calls the "dual color mode" (can be disabled via > `--no-dual-color`) which helps identifying what *actually* changed: it > prefixes lines with a `-` (and red background) that correspond to the first > commit range, and with a `+` (and green background) that correspond to the > second range. The rest of the lines will be colored according to the original > diffs. > > Changes since v3: > > - The cover letter was adjusted to reflect the new reality (the command is > called `range-diff` now, not `branch-diff`, and `--dual-color` is the > default). > - The documentation was adjusted a bit more in the patch that makes > `--dual-color` the default. > - Clarified the calculation of the cost matrix, as per Stefan Beller's > request. > - The man page now spells out that merge *commits* are ignored in the commit > ranges (not merges per se). > - The code in `linear-assignment.c` was adjusted to use the `SWAP()` macro. > - The commit message of the patch introducing the first rudimentary > implementation no longer talks about the "Hungarian" algorithm, but about the > "linear assignment algorithm" instead. > - A bogus indentation change was backed out from the patch introducing the > first rudimentary implementation. > - Instead of merely warning about missing `..` in the 2-parameter invocation, > we now exit with the error message. > - The `diff_opt_parse()` function is allowed to return a value larger than 1, > indicating that more than just one command-line parameter was parsed. We now > advance by the indicated value instead of always advancing exactly 1 (which > is still correct much of the time). > - A lengthy `if...else if...else if...else` was simplified (from a logical > point of view) by reordering it. > - The unnecessarily `static` variable `dashes` was turned into a local > variable of the caller. > - The commit message talking about the new man page still referred to `git > branch --diff`, which has been fixed. > - A forgotten t7910 reference was changed to t3206. > - An unbalanced double-tick was fixed in the man page. > - Fixed grammar both of the commit message and the description of the > `--no-dual-color` option. > - To fix the build, a blank man page is now introduced together with the new > `range-diff` command, even if it is populated for real only at a later patch > (i.e. at the same time as before). > - The headaches Junio fears would be incurred by that simple workaround to > avoid bogus white-space error reporting are fended off: a more complex patch > is now in place that adds (and uses) a new white-space flag. Sadly, as is all > too common when Junio "encourages" me to replace a simple workaround by > something "proper", it caused all kinds of headaches to get this right, so I > am rather less certain that the "proper" fix will cause us less headaches > than the simple workaround would have done. But whatever. > - The dual color mode now also dims the changes that are exclusively in the > first specified commit range, and uses bold face on the changes exclusively > in the second one. This matches the intuition when using `range-diff` to > compare an older iteration of a patch series to a newer one: the changes from > the previous iteration that were replaced by new ones "fade", while the > changes that replace them are "shiny new". > > Changes since v2: > > - Right-aligned the patch numbers in the commit pairs. > - Used ALLOC_ARRAY() in hungarian.c instead of xmalloc(sizeof()*size). > - Changed compute_assignment()s return type from int to void, as it always > succeeds. > - Changed the Hungarian Algorithm to use an integer cost matrix. > - Changed the --creation-weight <double> option to --creation-factor > <percent> where <percent> is an integer. > - Retitled 1/19 and 2/19 to better conform with the current conventions, as > pointed out (and suggested) by Junio. > - Shut up Coverity, and at the same time avoided passing the unnecessary `i` > and `j` parameters to output_pair_header(). > - Removed support for the `--no-patches` option: we inherit diff_options' > support for `-s` already (and much more). > - Removed the ugly `_INV` enum values, and introduced a beautiful > GIT_COLOR_REVERSE instead. This way, whatever the user configured as > color.diff.new (or .old) will be used in reverse in the dual color mode. > - Instead of overriding the fragment header color, the dual color mode will > now reverse the "outer" fragment headers, too. > - Turned the stand-alone branch-diff command into the `--diff` option of `git > branch`. Adjusted pretty much *all* commit messages to account for this. This > change should no longer be visible: see below. > - Pretty much re-wrote the completion, to support the new --diff mode of > git-branch. See below: it was reverted for range-diff. > - Renamed t7910 to t3206, to be closer to the git-branch tests. > - Ensured that git_diff_ui_config() gets called, and therefore color.diff.* > respected. > - Avoided leaking `four_spaces`. > - Fixed a declaration in a for (;;) statement (which Junio had as a fixup! > that I almost missed). > - Renamed `branch --diff`, which had been renamed from `branch-diff` (which > was picked to avoid re-using `tbdiff`) to `range-diff`. > - Renamed `hungarian.c` and its header to `linear-assignment.c` > - Made `--dual-color` the default, and changed it to still auto-detect > whether color should be used rather than forcing it > > Johannes Schindelin (20): > linear-assignment: a function to solve least-cost assignment problems > Introduce `range-diff` to compare iterations of a topic branch > range-diff: first rudimentary implementation > range-diff: improve the order of the shown commits > range-diff: also show the diff between patches > range-diff: right-trim commit messages > range-diff: indent the diffs just like tbdiff > range-diff: suppress the diff headers > range-diff: adjust the output of the commit pairs > range-diff: do not show "function names" in hunk headers > range-diff: use color for the commit pairs > color: add the meta color GIT_COLOR_REVERSE > diff: add an internal option to dual-color diffs of diffs > range-diff: offer to dual-color the diffs > range-diff --dual-color: fix bogus white-space warning > range-diff: populate the man page > completion: support `git range-diff` > range-diff: left-pad patch numbers > range-diff: make --dual-color the default mode > range-diff: use dim/bold cues to improve dual color mode > > Thomas Rast (1): > range-diff: add tests > > .gitignore | 1 + > Documentation/config.txt | 6 +- > Documentation/git-range-diff.txt | 252 +++++++++++ > Makefile | 3 + > builtin.h | 1 + > builtin/range-diff.c | 106 +++++ > cache.h | 3 +- > color.h | 7 + > command-list.txt | 1 + > contrib/completion/git-completion.bash | 14 + > diff.c | 119 ++++- > diff.h | 16 +- > git.c | 1 + > linear-assignment.c | 201 ++++++++ > linear-assignment.h | 22 + > range-diff.c | 440 ++++++++++++++++++ > range-diff.h | 9 + > t/.gitattributes | 1 + > t/t3206-range-diff.sh | 145 ++++++ > t/t3206/history.export | 604 +++++++++++++++++++++++++ > ws.c | 11 +- > 21 files changed, 1932 insertions(+), 31 deletions(-) > create mode 100644 Documentation/git-range-diff.txt > create mode 100644 builtin/range-diff.c > create mode 100644 linear-assignment.c > create mode 100644 linear-assignment.h > create mode 100644 range-diff.c > create mode 100644 range-diff.h > create mode 100755 t/t3206-range-diff.sh > create mode 100644 t/t3206/history.export > > > base-commit: b7bd9486b055c3f967a870311e704e3bb0654e4f > Published-As: > https://github.com/gitgitgadget/git/releases/tags/pr-1%2Fdscho%2Fbranch-diff-v4 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git > pr-1/dscho/branch-diff-v4 > Pull-Request: https://github.com/gitgitgadget/git/pull/1 > > Range-diff vs v3: > > 1: 39272eefc ! 1: f7e70689e linear-assignment: a function to solve > least-cost assignment problems > @@ -223,9 +223,7 @@ > + BUG("negative j: %d", j); > + i = pred[j]; > + column2row[j] = i; > -+ k = j; > -+ j = row2column[i]; > -+ row2column[i] = k; > ++ SWAP(j, row2column[i]); > + } while (i1 != i); > + } > + > 2: 7f15b26d4 ! 2: 88134121d Introduce `range-diff` to compare iterations > of a topic branch > @@ -10,6 +10,10 @@ > At this point, we ignore tbdiff's color options, as they will all be > implemented later using diff_options. > > + Since f318d739159 (generate-cmds.sh: export all commands to > + command-list.h, 2018-05-10), every new command *requires* a man > page to > + build right away, so let's also add a blank man page, too. > + > Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de> > > diff --git a/.gitignore b/.gitignore > @@ -24,6 +28,22 @@ > /git-rebase > /git-rebase--am > > +diff --git a/Documentation/git-range-diff.txt > b/Documentation/git-range-diff.txt > +new file mode 100644 > +--- /dev/null > ++++ b/Documentation/git-range-diff.txt > +@@ > ++git-range-diff(1) > ++================== > ++ > ++NAME > ++---- > ++git-range-diff - Compare two commit ranges (e.g. two versions of a > branch) > ++ > ++GIT > ++--- > ++Part of the linkgit:git[1] suite > + > diff --git a/Makefile b/Makefile > --- a/Makefile > +++ b/Makefile > 3: 076e1192d ! 3: 4e3fb47a1 range-diff: first rudimentary implementation > @@ -4,7 +4,7 @@ > > At this stage, `git range-diff` can determine corresponding commits > of two related commit ranges. This makes use of the recently > introduced > - implementation of the Hungarian algorithm. > + implementation of the linear assignment algorithm. > > The core of this patch is a straight port of the ideas of tbdiff, > the > apparently dormant project at https://github.com/trast/tbdiff. > @@ -51,19 +51,17 @@ > + int res = 0; > + struct strbuf range1 = STRBUF_INIT, range2 = STRBUF_INIT; > > -- argc = parse_options(argc, argv, NULL, options, > -- builtin_range_diff_usage, 0); > -+ argc = parse_options(argc, argv, NULL, options, > builtin_range_diff_usage, > -+ 0); > + argc = parse_options(argc, argv, NULL, options, > + builtin_range_diff_usage, 0); > > - return 0; > + if (argc == 2) { > + if (!strstr(argv[0], "..")) > -+ warning(_("no .. in range: '%s'"), argv[0]); > ++ die(_("no .. in range: '%s'"), argv[0]); > + strbuf_addstr(&range1, argv[0]); > + > + if (!strstr(argv[1], "..")) > -+ warning(_("no .. in range: '%s'"), argv[1]); > ++ die(_("no .. in range: '%s'"), argv[1]); > + strbuf_addstr(&range2, argv[1]); > + } else if (argc == 3) { > + strbuf_addf(&range1, "%s..%s", argv[0], argv[1]); > @@ -195,17 +193,21 @@ > + continue; > + } else if (starts_with(line.buf, "@@ ")) > + strbuf_addstr(&buf, "@@"); > -+ else if (line.buf[0] && !starts_with(line.buf, "index > ")) > ++ else if (!line.buf[0] || starts_with(line.buf, "index > ")) > + /* > + * A completely blank (not ' \n', which is > context) > + * line is not valid in a diff. We skip it > + * silently, because this neatly handles the > blank > + * separator line between commits in git-log > + * output. > ++ * > ++ * We also want to ignore the diff's `index` > lines > ++ * because they contain exact blob hashes in > which > ++ * we are not interested. > + */ > -+ strbuf_addbuf(&buf, &line); > -+ else > + continue; > ++ else > ++ strbuf_addbuf(&buf, &line); > + > + strbuf_addch(&buf, '\n'); > + util->diffsize++; > 4: e98489c8c = 4: 47bee09b0 range-diff: improve the order of the shown > commits > 5: 935cad180 ! 5: 94afaeaf2 range-diff: also show the diff between > patches > @@ -55,21 +55,22 @@ > + int i, j, res = 0; > struct strbuf range1 = STRBUF_INIT, range2 = STRBUF_INIT; > > -- argc = parse_options(argc, argv, NULL, options, > builtin_range_diff_usage, > -- 0); > + git_config(git_diff_ui_config, NULL); > + > + diff_setup(&diffopt); > + diffopt.output_format = DIFF_FORMAT_PATCH; > + > -+ argc = parse_options(argc, argv, NULL, options, > -+ builtin_range_diff_usage, > PARSE_OPT_KEEP_UNKNOWN); > + argc = parse_options(argc, argv, NULL, options, > +- builtin_range_diff_usage, 0); > ++ builtin_range_diff_usage, > PARSE_OPT_KEEP_UNKNOWN); > + > -+ for (i = j = 0; i < argc; i++) { > ++ for (i = j = 0; i < argc; ) { > + int c = diff_opt_parse(&diffopt, argv + i, argc - i, > prefix); > + > + if (!c) > -+ argv[j++] = argv[i]; > ++ argv[j++] = argv[i++]; > ++ else > ++ i += c; > + } > + argc = j; > + diff_setup_done(&diffopt); > 6: 93ac1931d = 6: 41ab875a3 range-diff: right-trim commit messages > 7: ca5282815 ! 7: a3dd99509 range-diff: indent the diffs just like tbdiff > @@ -39,7 +39,7 @@ > + diffopt.output_prefix_data = &four_spaces; > > argc = parse_options(argc, argv, NULL, options, > - builtin_range_diff_usage, > PARSE_OPT_KEEP_UNKNOWN); > + builtin_range_diff_usage, > PARSE_OPT_KEEP_UNKNOWN); > @@ > > strbuf_release(&range1); > 8: 80622685f = 8: 61b2ff2f7 range-diff: suppress the diff headers > 9: 6b31cbf72 ! 9: 9641ab5c0 range-diff: adjust the output of the commit > pairs > @@ -26,25 +26,22 @@ > > -static const char *short_oid(struct patch_util *util) > +static void output_pair_header(struct strbuf *buf, > ++ struct strbuf *dashes, > + struct patch_util *a_util, > + struct patch_util *b_util) > { > - return find_unique_abbrev(&util->oid, DEFAULT_ABBREV); > -+ static char *dashes; > + struct object_id *oid = a_util ? &a_util->oid : &b_util->oid; > + struct commit *commit; > + > -+ if (!dashes) { > -+ char *p; > -+ > -+ dashes = xstrdup(find_unique_abbrev(oid, > DEFAULT_ABBREV)); > -+ for (p = dashes; *p; p++) > -+ *p = '-'; > -+ } > ++ if (!dashes->len) > ++ strbuf_addchars(dashes, '-', > ++ strlen(find_unique_abbrev(oid, > ++ > DEFAULT_ABBREV))); > + > + strbuf_reset(buf); > + if (!a_util) > -+ strbuf_addf(buf, "-: %s ", dashes); > ++ strbuf_addf(buf, "-: %s ", dashes->buf); > + else > + strbuf_addf(buf, "%d: %s ", a_util->i + 1, > + find_unique_abbrev(&a_util->oid, > DEFAULT_ABBREV)); > @@ -59,7 +56,7 @@ > + strbuf_addch(buf, '='); > + > + if (!b_util) > -+ strbuf_addf(buf, " -: %s", dashes); > ++ strbuf_addf(buf, " -: %s", dashes->buf); > + else > + strbuf_addf(buf, " %d: %s", b_util->i + 1, > + find_unique_abbrev(&b_util->oid, > DEFAULT_ABBREV)); > @@ -84,7 +81,7 @@ > static void output(struct string_list *a, struct string_list *b, > struct diff_options *diffopt) > { > -+ struct strbuf buf = STRBUF_INIT; > ++ struct strbuf buf = STRBUF_INIT, dashes = STRBUF_INIT; > int i = 0, j = 0; > > /* > @@ -94,7 +91,7 @@ > if (i < a->nr && a_util->matching < 0) { > - printf("%d: %s < -: --------\n", > - i + 1, short_oid(a_util)); > -+ output_pair_header(&buf, a_util, NULL); > ++ output_pair_header(&buf, &dashes, a_util, NULL); > i++; > continue; > } > @@ -103,7 +100,7 @@ > while (j < b->nr && b_util->matching < 0) { > - printf("-: -------- > %d: %s\n", > - j + 1, short_oid(b_util)); > -+ output_pair_header(&buf, NULL, b_util); > ++ output_pair_header(&buf, &dashes, NULL, b_util); > b_util = ++j < b->nr ? b->items[j].util : NULL; > } > > @@ -113,7 +110,7 @@ > - printf("%d: %s ! %d: %s\n", > - b_util->matching + 1, short_oid(a_util), > - j + 1, short_oid(b_util)); > -+ output_pair_header(&buf, a_util, b_util); > ++ output_pair_header(&buf, &dashes, a_util, > b_util); > if (!(diffopt->output_format & > DIFF_FORMAT_NO_OUTPUT)) > > patch_diff(a->items[b_util->matching].string, > b->items[j].string, diffopt); > @@ -122,6 +119,7 @@ > } > } > + strbuf_release(&buf); > ++ strbuf_release(&dashes); > } > > int show_range_diff(const char *range1, const char *range2, > 10: ef997bb8b = 10: 0a52f8878 range-diff: do not show "function names" in > hunk headers > 11: 3d9e5b0ba ! 11: 2b8d09020 range-diff: add tests > @@ -3,8 +3,8 @@ > range-diff: add tests > > These are essentially lifted from https://github.com/trast/tbdiff, > with > - light touch-ups to account for the command now being an option of > `git > - branch`. > + light touch-ups to account for the command now being names `git > + range-diff`. > > Apart from renaming `tbdiff` to `range-diff`, only one test case > needed > to be adjusted: 11 - 'changed message'. > @@ -22,12 +22,13 @@ > --- a/t/.gitattributes > +++ b/t/.gitattributes > @@ > - /t5515/* eol=lf > - /t556x_common eol=lf > - /t7500/* eol=lf > -+/t7910/* eol=lf > - /t8005/*.txt eol=lf > - /t9*/*.dump eol=lf > + t[0-9][0-9][0-9][0-9]/* -whitespace > + /diff-lib/* eol=lf > + /t0110/url-* binary > ++/t3206/* eol=lf > + /t3900/*.txt eol=lf > + /t3901/*.txt eol=lf > + /t4034/*/* eol=lf > > diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh > new file mode 100755 > 12: 7273cc647 ! 12: fb83ce71a range-diff: use color for the commit pairs > @@ -20,11 +20,12 @@ > } > > -static void output_pair_header(struct strbuf *buf, > -+static void output_pair_header(struct diff_options *diffopt, struct > strbuf *buf, > ++static void output_pair_header(struct diff_options *diffopt, > ++ struct strbuf *buf, > + struct strbuf *dashes, > struct patch_util *a_util, > struct patch_util *b_util) > { > - static char *dashes; > struct object_id *oid = a_util ? &a_util->oid : &b_util->oid; > struct commit *commit; > + char status; > @@ -34,11 +35,10 @@ > + const char *color_commit = diff_get_color_opt(diffopt, > DIFF_COMMIT); > + const char *color; > > - if (!dashes) { > - char *p; > -@@ > - *p = '-'; > - } > + if (!dashes->len) > + strbuf_addchars(dashes, '-', > + strlen(find_unique_abbrev(oid, > + > DEFAULT_ABBREV))); > > + if (!b_util) { > + color = color_old; > @@ -57,7 +57,7 @@ > strbuf_reset(buf); > + strbuf_addstr(buf, status == '!' ? color_old : color); > if (!a_util) > - strbuf_addf(buf, "-: %s ", dashes); > + strbuf_addf(buf, "-: %s ", dashes->buf); > else > strbuf_addf(buf, "%d: %s ", a_util->i + 1, > find_unique_abbrev(&a_util->oid, > DEFAULT_ABBREV)); > @@ -77,7 +77,7 @@ > + strbuf_addf(buf, "%s%s", color_reset, color_new); > > if (!b_util) > - strbuf_addf(buf, " -: %s", dashes); > + strbuf_addf(buf, " -: %s", dashes->buf); > @@ > const char *commit_buffer = get_commit_buffer(commit, > NULL); > const char *subject; > @@ -99,24 +99,27 @@ > > /* Show unmatched LHS commit whose predecessors were > shown. */ > if (i < a->nr && a_util->matching < 0) { > -- output_pair_header(&buf, a_util, NULL); > -+ output_pair_header(diffopt, &buf, a_util, NULL); > +- output_pair_header(&buf, &dashes, a_util, NULL); > ++ output_pair_header(diffopt, > ++ &buf, &dashes, a_util, NULL); > i++; > continue; > } > > /* Show unmatched RHS commits. */ > while (j < b->nr && b_util->matching < 0) { > -- output_pair_header(&buf, NULL, b_util); > -+ output_pair_header(diffopt, &buf, NULL, b_util); > +- output_pair_header(&buf, &dashes, NULL, b_util); > ++ output_pair_header(diffopt, > ++ &buf, &dashes, NULL, b_util); > b_util = ++j < b->nr ? b->items[j].util : NULL; > } > > /* Show matching LHS/RHS pair. */ > if (j < b->nr) { > a_util = a->items[b_util->matching].util; > -- output_pair_header(&buf, a_util, b_util); > -+ output_pair_header(diffopt, &buf, a_util, > b_util); > +- output_pair_header(&buf, &dashes, a_util, > b_util); > ++ output_pair_header(diffopt, > ++ &buf, &dashes, a_util, > b_util); > if (!(diffopt->output_format & > DIFF_FORMAT_NO_OUTPUT)) > > patch_diff(a->items[b_util->matching].string, > b->items[j].string, diffopt); > 13: 96a3073fb = 13: 9ccb9516a color: add the meta color GIT_COLOR_REVERSE > 14: 6be4baf60 = 14: 9de5bd229 diff: add an internal option to dual-color > diffs of diffs > 15: 02e13c0c6 ! 15: 21b2f9e4b range-diff: offer to dual-color the diffs > @@ -40,4 +40,4 @@ > + > if (argc == 2) { > if (!strstr(argv[0], "..")) > - warning(_("no .. in range: '%s'"), argv[0]); > + die(_("no .. in range: '%s'"), argv[0]); > 16: dfa7b1e71 < -: --------- range-diff --dual-color: work around bogus > white-space warning > -: --------- > 16: f4252f2b2 range-diff --dual-color: fix bogus > white-space warning > 17: 799da25ef ! 17: 9e09c6be6 range-diff: add a man page > @@ -1,6 +1,6 @@ > Author: Johannes Schindelin <johannes.schinde...@gmx.de> > > - range-diff: add a man page > + range-diff: populate the man page > > The bulk of this patch consists of a heavily butchered version of > tbdiff's README written by Thomas Rast and Thomas Gummerer, lifted > from > @@ -9,17 +9,12 @@ > Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de> > > diff --git a/Documentation/git-range-diff.txt > b/Documentation/git-range-diff.txt > -new file mode 100644 > ---- /dev/null > +--- a/Documentation/git-range-diff.txt > +++ b/Documentation/git-range-diff.txt > @@ > -+git-range-diff(1) > -+================== > -+ > -+NAME > -+---- > -+git-range-diff - Compare two commit ranges (e.g. two versions of a > branch) > -+ > + ---- > + git-range-diff - Compare two commit ranges (e.g. two versions of a > branch) > + > +SYNOPSIS > +-------- > +[verse] > @@ -31,13 +26,13 @@ > +----------- > + > +This command shows the differences between two versions of a patch > -+series, or more generally, two commit ranges (ignoring merges). > ++series, or more generally, two commit ranges (ignoring merge commits). > + > +To that end, it first finds pairs of commits from both commit ranges > +that correspond with each other. Two commits are said to correspond > when > +the diff between their patches (i.e. the author information, the commit > +message and the commit diff) is reasonably small compared to the > -+patches' size. See ``Algorithm` below for details. > ++patches' size. See ``Algorithm`` below for details. > + > +Finally, the list of matching commits is shown in the order of the > +second commit range, with unmatched commits being inserted just after > @@ -150,6 +145,10 @@ > +The general idea is this: we generate a cost matrix between the commits > +in both commit ranges, then solve the least-cost assignment. > + > ++The cost matrix is populated thusly: for each pair of commits, both > ++diffs are generated and the "diff of diffs" is generated, with 3 > context > ++lines, then the number of lines in that diff is used as cost. > ++ > +To avoid false positives (e.g. when a patch has been removed, and an > +unrelated patch has been added between two iterations of the same patch > +series), the cost matrix is extended to allow for that, by adding > @@ -245,6 +244,6 @@ > +-------- > +linkgit:git-log[1] > + > -+GIT > -+--- > -+Part of the linkgit:git[1] suite > + GIT > + --- > + Part of the linkgit:git[1] suite > 18: d05b54c60 ! 18: 9b3632324 completion: support `git range-diff` > @@ -4,17 +4,11 @@ > > Tab completion of `git range-diff` is very convenient, especially > given that the revision arguments to specify the commit ranges to > - compare are typically more complex than, say, your grandfather's > `git > - log` arguments. > + compare are typically more complex than, say, what is normally > passed > + to `git log`. > > Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de> > > - squash! WIP completion: support `git range-diff` > - > - Revert "WIP completion: support `git range-diff`" > - > - This reverts commit 2e7af652af9e53a19fd947f8ebe37a78043afa49. > - > diff --git a/contrib/completion/git-completion.bash > b/contrib/completion/git-completion.bash > --- a/contrib/completion/git-completion.bash > +++ b/contrib/completion/git-completion.bash > 19: 144363006 < -: --------- range-diff: left-pad patch numbers > -: --------- > 19: 07ec215e8 range-diff: left-pad patch numbers > 20: 4a68b95ce ! 20: b370468e7 range-diff: make --dual-color the default > mode > @@ -4,7 +4,7 @@ > > After using this command extensively for the last two months, this > developer came to the conclusion that even if the dual color mode > still > - leaves a lot of room for confusion what was actually changed, the > + leaves a lot of room for confusion about what was actually changed, > the > non-dual color mode is substantially worse in that regard. > > Therefore, we really want to make the dual color mode the default. > @@ -14,6 +14,15 @@ > diff --git a/Documentation/git-range-diff.txt > b/Documentation/git-range-diff.txt > --- a/Documentation/git-range-diff.txt > +++ b/Documentation/git-range-diff.txt > +@@ > + -------- > + [verse] > + 'git range-diff' [--color=[<when>]] [--no-color] [<diff-options>] > +- [--dual-color] [--creation-factor=<factor>] > ++ [--no-dual-color] [--creation-factor=<factor>] > + ( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> ) > + > + DESCRIPTION > @@ > > OPTIONS > @@ -25,7 +34,7 @@ > - change in what exact lines were added. > +--no-dual-color:: > + When the commit diffs differ, `git range-diff` recreates the > -+ original diffs' coloring, and add outer -/+ diff markers with > ++ original diffs' coloring, and adds outer -/+ diff markers with > + the *background* being red/green to make it easier to see e.g. > + when there was a change in what exact lines were added. This is > + known to `range-diff` as "dual coloring". Use `--no-dual-color` > @@ -34,6 +43,31 @@ > > --creation-factor=<percent>:: > Set the creation/deletion cost fudge factor to `<percent>`. > +@@ > + show`'s output, and the third line colors the old commit red, the new > + one green and the rest like `git show`'s commit header. > + > +-The color-coded diff is actually a bit hard to read, though, as it > +-colors the entire lines red or green. The line that added "What is > +-unexpected" in the old commit, for example, is completely red, even if > +-the intent of the old commit was to add something. > ++A naive color-coded diff of diffs is actually a bit hard to read, > ++though, as it colors the entire lines red or green. The line that added > ++"What is unexpected" in the old commit, for example, is completely red, > ++even if the intent of the old commit was to add something. > + > +-To help with that, use the `--dual-color` mode. In this mode, the diff > +-of diffs will retain the original diff colors, and prefix the lines > with > +--/+ markers that have their *background* red or green, to make it more > +-obvious that they describe how the diff itself changed. > ++To help with that, `range` uses the `--dual-color` mode by default. In > ++this mode, the diff of diffs will retain the original diff colors, and > ++prefix the lines with -/+ markers that have their *background* red or > ++green, to make it more obvious that they describe how the diff itself > ++changed. > + > + > + Algorithm > > diff --git a/builtin/range-diff.c b/builtin/range-diff.c > --- a/builtin/range-diff.c > -: --------- > 21: d8498fb32 range-diff: use dim/bold cues to improve > dual color mode > > -- > gitgitgadget