git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/1] Fix git rebase --stat -i <unrelated-history>

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Nov 29, 2018, 13:01 UTC
Message-ID
<pull.88.v2.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.88.git.gitgitgadget@gmail.com>
We're really entering obscure territory here, I would say.

To trigger the bug, two things have to come together: the user must have asked for a diffstat afterwards, and the commits need to have been rebased onto a completely unrelated commit history (i.e. there must exist no merge base between the pre-rebase HEAD and the post-rebase HEAD).

Please note that this bug existed already in the scripted rebase, but it was never detected because the scripted version would not even perform any error checking.

It will make Junio very happy that I squashed the regression test in to the patch that fixes it. The reason, however, was not to make Junio happy (I hope to make him happy by fixing bugs), but simply that an earlier iteration of test would only fail with the built-in rebase, but not with the scripted version. The current version would fail with the scripted version, but I'll save the time to split the patch again now.

Changes since v1:
 * The commit message now talks more about what we should do in case that
   there is no merge base, rather than stressing the differences between the
   way scripted vs built-in rebase handled it (both buggy, and fixed by this
   patch).
 * In case that there is no merge base, it no longer reports "Changes from
   (empty) to ..." but "Changes to ...", which should be a lot less
   controversial.
Johannes Schindelin (1):
  rebase --stat: fix when rebasing to an unrelated history
 builtin/rebase.c          | 18 ++++++++++++------
 git-legacy-rebase.sh      | 10 ++++++++--
 t/t3406-rebase-message.sh | 10 ++++++++++
 3 files changed, 30 insertions(+), 8 deletions(-)
base-commit: a1598010f775d82b5adf12c29d0f5bc9b41434c6
Published-As: https://github.com/gitgitgadget/git/releases/tags/pr-88%2Fdscho%2Frebase-stat-fix-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-88/dscho/rebase-stat-fix-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/88
Range-diff vs v1:
 1:  680385e4bd ! 1:  190c7856ad rebase --stat: fix when rebasing to an unrelated history
     @@ -3,22 +3,21 @@
          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. The scripted version of the `git
     -    rebase` command was not prepared for that and spewed out
     +    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.
      
     -            fatal: ambiguous argument '': unknown revision or path not in
     -            the working tree.
     +    Also, if running in verbose diffstat mode, we should not output
      
     -    but then continued (due to lack of error checking).
     +            Changes from <merge-base> to <onto>
      
     -    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).
     +    as that does not make sense without any merge base.
      
     -    Fix both scripted and built-in versions to output something sensibly,
     -    and add a regression test to keep this working in all eternity.
     +    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 <avarab@gmail.com>
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
     @@ -27,15 +26,25 @@
      --- a/builtin/rebase.c
      +++ b/builtin/rebase.c
      @@
     + 	if (options.flags & REBASE_DIFFSTAT) {
     + 		struct diff_options opts;
       
     - 		if (options.flags & REBASE_VERBOSE)
     - 			printf(_("Changes from %s to %s:\n"),
     +-		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));
     +-				oid_to_hex(&options.onto->object.oid));
     ++		if (options.flags & REBASE_VERBOSE) {
     ++			if (is_null_oid(&merge_base))
     ++				printf(_("Changes to %s:\n"),
     ++				       oid_to_hex(&options.onto->object.oid));
     ++			else
     ++				printf(_("Changes from %s to %s:\n"),
     ++				       oid_to_hex(&merge_base),
     ++				       oid_to_hex(&options.onto->object.oid));
     ++		}
       
       		/* We want color (if set), but no pager */
     + 		diff_setup(&opts);
      @@
       			DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
       		opts.detect_rename = DIFF_DETECT_RENAME;
     @@ -57,8 +66,12 @@
       	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:")"
     ++		if test -z "$mb"
     ++		then
     ++			echo "$(eval_gettext "Changes to \$onto:")"
     ++		else
     ++			echo "$(eval_gettext "Changes from \$mb to \$onto:")"
     ++		fi
       	fi
      +	mb_tree="${mb:-$(git hash-object -t tree /dev/null)}"
       	# We want color (if set), but no pager
     @@ -81,7 +94,7 @@
      +	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 "Changes to " actual &&
      +	test_i18ngrep "5 files changed" actual
      +'
      +
-- 
gitgitgadget
Previous: Junio C HamanoNext: Johannes Schindelin via GitGitGadget
Message 6 of 7 in “Fix git rebase --stat -i <unrelated-history>”
  1. 0/1 Fix git rebase --stat -i <unrelated-history>Johannes Schindelin via GitGitGadget, Nov 27, 2018
  2. 1/1 rebase --stat: fix when rebasing to an unrelated historyJohannes Schindelin via GitGitGadget, Nov 27, 2018
  3. Junio C HamanoNov 29, 2018
  4. Johannes SchindelinNov 29, 2018
  5. Junio C HamanoNov 30, 2018
  6. 0/1 Fix git rebase --stat -i <unrelated-history>Johannes Schindelin via GitGitGadget, Nov 29, 2018
  7. 1/1 rebase --stat: fix when rebasing to an unrelated historyJohannes Schindelin via GitGitGadget, Nov 29, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.