Skip to content

Commit 8797f0f

Browse files
dschogitster
authored andcommitted
rebase --stat: fix when rebasing to an unrelated history
When rebasing to a commit history that has no common commits with the current branch, there is no merge base. In diffstat mode, this means that we cannot compare to the merge base, but we have to compare to the empty tree instead. Also, if running in verbose diffstat mode, we should not output Changes from <merge-base> to <onto> as that does not make sense without any merge base. Note: neither scripted nor built-in versoin of `git rebase` were prepared for this situation well. We use this opportunity not only to fix the bug(s), but also to make both versions' output consistent in this instance. And add a regression test to keep this working in all eternity. Reported-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7068cbc commit 8797f0f

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

builtin/rebase.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,10 +1481,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
14811481
if (options.flags & REBASE_DIFFSTAT) {
14821482
struct diff_options opts;
14831483

1484-
if (options.flags & REBASE_VERBOSE)
1485-
printf(_("Changes from %s to %s:\n"),
1486-
oid_to_hex(&merge_base),
1487-
oid_to_hex(&options.onto->object.oid));
1484+
if (options.flags & REBASE_VERBOSE) {
1485+
if (is_null_oid(&merge_base))
1486+
printf(_("Changes to %s:\n"),
1487+
oid_to_hex(&options.onto->object.oid));
1488+
else
1489+
printf(_("Changes from %s to %s:\n"),
1490+
oid_to_hex(&merge_base),
1491+
oid_to_hex(&options.onto->object.oid));
1492+
}
14881493

14891494
/* We want color (if set), but no pager */
14901495
diff_setup(&opts);
@@ -1494,8 +1499,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
14941499
DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
14951500
opts.detect_rename = DIFF_DETECT_RENAME;
14961501
diff_setup_done(&opts);
1497-
diff_tree_oid(&merge_base, &options.onto->object.oid,
1498-
"", &opts);
1502+
diff_tree_oid(is_null_oid(&merge_base) ?
1503+
the_hash_algo->empty_tree : &merge_base,
1504+
&options.onto->object.oid, "", &opts);
14991505
diffcore_std(&opts);
15001506
diff_flush(&opts);
15011507
}

git-legacy-rebase.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,10 +718,16 @@ if test -n "$diffstat"
718718
then
719719
if test -n "$verbose"
720720
then
721-
echo "$(eval_gettext "Changes from \$mb to \$onto:")"
721+
if test -z "$mb"
722+
then
723+
echo "$(eval_gettext "Changes to \$onto:")"
724+
else
725+
echo "$(eval_gettext "Changes from \$mb to \$onto:")"
726+
fi
722727
fi
728+
mb_tree="${mb:-$(git hash-object -t tree /dev/null)}"
723729
# We want color (if set), but no pager
724-
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
730+
GIT_PAGER='' git diff --stat --summary "$mb_tree" "$onto"
725731
fi
726732

727733
test -n "$interactive_rebase" && run_specific_rebase

t/t3406-rebase-message.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,14 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
9191
test_i18ngrep "Invalid whitespace option" err
9292
'
9393

94+
test_expect_success 'rebase -i onto unrelated history' '
95+
git init unrelated &&
96+
test_commit -C unrelated 1 &&
97+
git -C unrelated remote add -f origin "$PWD" &&
98+
git -C unrelated branch --set-upstream-to=origin/master &&
99+
git -C unrelated -c core.editor=true rebase -i -v --stat >actual &&
100+
test_i18ngrep "Changes to " actual &&
101+
test_i18ngrep "5 files changed" actual
102+
'
103+
94104
test_done

0 commit comments

Comments
 (0)