From: Johannes Schindelin <johannes.schindelin@xxxxxx> When rebasing to a commit history that has no common commits with the current branch, there is no merge base. The scripted version of the `git rebase` command was not prepared for that and spewed out fatal: ambiguous argument '': unknown revision or path not in the working tree. but then continued (due to lack of error checking). The built-in version of the `git rebase` command blindly translated that shell script code, assuming that there is no need to test whether there *was* a merge base, and due to its better error checking, exited with a fatal error (because it tried to read the object with hash 00000000... as a tree). Fix both scripted and built-in versions to output something sensibly, and add a regression test to keep this working in all eternity. Reported-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- builtin/rebase.c | 8 +++++--- git-legacy-rebase.sh | 6 ++++-- t/t3406-rebase-message.sh | 10 ++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index 5b3e5baec8..9e4b0b564f 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1483,7 +1483,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.flags & REBASE_VERBOSE) printf(_("Changes from %s to %s:\n"), - oid_to_hex(&merge_base), + is_null_oid(&merge_base) ? + "(empty)" : oid_to_hex(&merge_base), oid_to_hex(&options.onto->object.oid)); /* We want color (if set), but no pager */ @@ -1494,8 +1495,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT; opts.detect_rename = DIFF_DETECT_RENAME; diff_setup_done(&opts); - diff_tree_oid(&merge_base, &options.onto->object.oid, - "", &opts); + diff_tree_oid(is_null_oid(&merge_base) ? + the_hash_algo->empty_tree : &merge_base, + &options.onto->object.oid, "", &opts); diffcore_std(&opts); diff_flush(&opts); } diff --git a/git-legacy-rebase.sh b/git-legacy-rebase.sh index b97ffdc9dd..be3b241676 100755 --- a/git-legacy-rebase.sh +++ b/git-legacy-rebase.sh @@ -718,10 +718,12 @@ if test -n "$diffstat" then if test -n "$verbose" then - echo "$(eval_gettext "Changes from \$mb to \$onto:")" + mb_display="${mb:-(empty)}" + echo "$(eval_gettext "Changes from \$mb_display to \$onto:")" fi + mb_tree="${mb:-$(git hash-object -t tree /dev/null)}" # We want color (if set), but no pager - GIT_PAGER='' git diff --stat --summary "$mb" "$onto" + GIT_PAGER='' git diff --stat --summary "$mb_tree" "$onto" fi test -n "$interactive_rebase" && run_specific_rebase diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index 38bd876cab..a1ee912118 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -91,4 +91,14 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' ' test_i18ngrep "Invalid whitespace option" err ' +test_expect_success 'rebase -i onto unrelated history' ' + git init unrelated && + test_commit -C unrelated 1 && + git -C unrelated remote add -f origin "$PWD" && + git -C unrelated branch --set-upstream-to=origin/master && + git -C unrelated -c core.editor=true rebase -i -v --stat >actual && + test_i18ngrep "Changes from (empty)" actual && + test_i18ngrep "5 files changed" actual +' + test_done -- gitgitgadget