struct hashmap_entry e;
const char *diff, *patch;
- int i;
+ int i, shown;
int diffsize;
size_t diff_offset;
/* the index of the matching item in the other branch, or -1 */
static void output(struct string_list *a, struct string_list *b)
{
- int i;
-
- for (i = 0; i < b->nr; i++) {
- struct patch_util *util = b->items[i].util, *prev;
+ int i = 0, j = 0;
+
+ /*
+ * We assume the user is really more interested in the second argument
+ * ("newer" version). To that end, we print the output in the order of
+ * the RHS (the `b` parameter). To put the LHS (the `a` parameter)
+ * commits that are no longer in the RHS into a good place, we place
+ * them once we have shown all of their predecessors in the LHS.
+ */
+
+ while (i < a->nr || j < b->nr) {
+ struct patch_util *a_util, *b_util;
+ a_util = i < a->nr ? a->items[i].util : NULL;
+ b_util = j < b->nr ? b->items[j].util : NULL;
+
+ /* Skip all the already-shown commits from the LHS. */
+ while (i < a->nr && a_util->shown)
+ a_util = ++i < a->nr ? a->items[i].util : NULL;
+
+ /* Show unmatched LHS commit whose predecessors were shown. */
+ if (i < a->nr && a_util->matching < 0) {
+ printf("%d: %s < -: --------\n",
+ i + 1, short_oid(a_util));
+ i++;
+ continue;
+ }
- if (util->matching < 0)
+ /* Show unmatched RHS commits. */
+ while (j < b->nr && b_util->matching < 0) {
printf("-: -------- > %d: %s\n",
- i + 1, short_oid(util));
- else {
- prev = a->items[util->matching].util;
- printf("%d: %s ! %d: %s\n",
- util->matching + 1, short_oid(prev),
- i + 1, short_oid(util));
+ j + 1, short_oid(b_util));
+ b_util = ++j < b->nr ? b->items[j].util : NULL;
}
- }
-
- for (i = 0; i < a->nr; i++) {
- struct patch_util *util = a->items[i].util;
- if (util->matching < 0)
- printf("%d: %s < -: --------\n",
- i + 1, short_oid(util));
+ /* Show matching LHS/RHS pair. */
+ if (j < b->nr) {
+ a_util = a->items[b_util->matching].util;
+ printf("%d: %s ! %d: %s\n",
+ b_util->matching + 1, short_oid(a_util),
+ j + 1, short_oid(b_util));
+ a_util->shown = 1;
+ j++;
+ }
}
}