From: Johannes Schindelin <johannes.schinde...@gmx.de>

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 <ava...@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
---
 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

Reply via email to