Skip to content

Commit 9dc46e0

Browse files
dschogitster
authored andcommitted
range-diff: improve the order of the shown commits
This patch lets `git range-diff` use the same order as tbdiff. The idea is simple: for left-to-right readers, it is natural to assume that the `git range-diff` is performed between an older vs a newer version of the branch. As such, the user is probably more interested in the question "where did this come from?" rather than "where did that one go?". To that end, we list the commits in the order of the second commit range ("the newer version"), inserting the unmatched commits of the first commit range as soon as all their predecessors have been shown. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d9c66f0 commit 9dc46e0

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

range-diff.c

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct patch_util {
1212
struct hashmap_entry e;
1313
const char *diff, *patch;
1414

15-
int i;
15+
int i, shown;
1616
int diffsize;
1717
size_t diff_offset;
1818
/* the index of the matching item in the other branch, or -1 */
@@ -260,28 +260,49 @@ static const char *short_oid(struct patch_util *util)
260260

261261
static void output(struct string_list *a, struct string_list *b)
262262
{
263-
int i;
264-
265-
for (i = 0; i < b->nr; i++) {
266-
struct patch_util *util = b->items[i].util, *prev;
263+
int i = 0, j = 0;
264+
265+
/*
266+
* We assume the user is really more interested in the second argument
267+
* ("newer" version). To that end, we print the output in the order of
268+
* the RHS (the `b` parameter). To put the LHS (the `a` parameter)
269+
* commits that are no longer in the RHS into a good place, we place
270+
* them once we have shown all of their predecessors in the LHS.
271+
*/
272+
273+
while (i < a->nr || j < b->nr) {
274+
struct patch_util *a_util, *b_util;
275+
a_util = i < a->nr ? a->items[i].util : NULL;
276+
b_util = j < b->nr ? b->items[j].util : NULL;
277+
278+
/* Skip all the already-shown commits from the LHS. */
279+
while (i < a->nr && a_util->shown)
280+
a_util = ++i < a->nr ? a->items[i].util : NULL;
281+
282+
/* Show unmatched LHS commit whose predecessors were shown. */
283+
if (i < a->nr && a_util->matching < 0) {
284+
printf("%d: %s < -: --------\n",
285+
i + 1, short_oid(a_util));
286+
i++;
287+
continue;
288+
}
267289

268-
if (util->matching < 0)
290+
/* Show unmatched RHS commits. */
291+
while (j < b->nr && b_util->matching < 0) {
269292
printf("-: -------- > %d: %s\n",
270-
i + 1, short_oid(util));
271-
else {
272-
prev = a->items[util->matching].util;
273-
printf("%d: %s ! %d: %s\n",
274-
util->matching + 1, short_oid(prev),
275-
i + 1, short_oid(util));
293+
j + 1, short_oid(b_util));
294+
b_util = ++j < b->nr ? b->items[j].util : NULL;
276295
}
277-
}
278-
279-
for (i = 0; i < a->nr; i++) {
280-
struct patch_util *util = a->items[i].util;
281296

282-
if (util->matching < 0)
283-
printf("%d: %s < -: --------\n",
284-
i + 1, short_oid(util));
297+
/* Show matching LHS/RHS pair. */
298+
if (j < b->nr) {
299+
a_util = a->items[b_util->matching].util;
300+
printf("%d: %s ! %d: %s\n",
301+
b_util->matching + 1, short_oid(a_util),
302+
j + 1, short_oid(b_util));
303+
a_util->shown = 1;
304+
j++;
305+
}
285306
}
286307
}
287308

0 commit comments

Comments
 (0)