Volume XXII, number 279Tuesday, October 6, 2026Latest message 1 hour ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

[BUG] git-history in the middle of rebase leads to a broken state

1 messages between Sep 25, 2026 and Sep 25, 2026, from Nikita Bobko.

Plain Markdown or JSON for tools and agents.

Nikita BobkoSep 25, 2026, 14:12 UTC on lore

git-history by default updates all branches that are descendants of the original commit to point to the rewritten commit. That also includes the branch that is *currently being rebased* (if such a branch exists), which leads to a broken state. Even `git branch --force` doesn't allow changing the currently being rebased branch.

I'm cc'ing Patrick Steinhardt, the original author of the git-history command -- I hope that's fine.

I searched the mailing list and, to my knowledge, these types of bugs haven't been reported yet (feature interactions between git-history and git-rebase/git-cherry-pick).

## Full reproducer
    $ git init # CMD_1
    Initialized empty Git repository in /Users/bobko/git-history-bug/.git/
    $ bash -c 'for i in 1 2 3 4 5; do echo $i > $i.txt; git add .; git commit -m $i; done' # CMD_2: Populate git history
    [main (root-commit) edff563] 1
     1 file changed, 1 insertion(+)
     create mode 100644 1.txt
    [main 106a0da] 2
     1 file changed, 1 insertion(+)
     create mode 100644 2.txt
    [main a36b6d5] 3
     1 file changed, 1 insertion(+)
     create mode 100644 3.txt
    [main fd8f39c] 4
     1 file changed, 1 insertion(+)
     create mode 100644 4.txt
    [main e641e3f] 5
     1 file changed, 1 insertion(+)
     create mode 100644 5.txt
    $ git log --oneline # CMD_3
    e641e3f (HEAD -> main) 5
    fd8f39c 4
    a36b6d5 3
    106a0da 2
    edff563 1
    $ GIT_SEQUENCE_EDITOR='perl -i -pe '\''print "break\n" if $. == 1'\''' git rebase -i a36b6d5 # CMD_4: Prepend 'break'. Stop the rebase
    Stopped at a36b6d5 (3)
    $ git log --oneline # CMD_5
    a36b6d5 (HEAD) 3
    106a0da 2
    edff563 1
    $ git log --oneline -1 main # CMD_6: main still points to the original commit - good
    e641e3f (main) 5
    $ echo 3 > 2.txt && git add . && git history fixup HEAD~ # CMD_7: The command that breaks everything
    $ git log --oneline -1 main # CMD_8: Oops, main has been overwritten by git-history - bad
    24fe5b2 (main) 5
    $ git rebase --continue # CMD_9: Now, git-rebase is broken
    error: update_ref failed for ref 'refs/heads/main': cannot lock ref 'refs/heads/main': is at 24fe5b2e2c697c43bc77fde0cfd25022cf5eadba but expected e641e3f7f50d0c07650e47b31c8198d57d5598db
    error: could not update refs/heads/main
    $ git log --oneline # CMD_10
    b5f15a4 (HEAD) 5
    50c2673 4
    2c1ed1a 3
    83f595c 2
    edff563 1
    $ git status # CMD_11
    interactive rebase in progress; onto a36b6d5
    Last commands done (3 commands done):
       pick fd8f39c # 2026-09-25 Nikita Bobko/Nikita Bobko 4
       pick e641e3f # 2026-09-25 Nikita Bobko/Nikita Bobko (HEAD -> main) 5
      (see more in file .git/rebase-merge/done)
    No commands remaining.
    You are currently editing a commit while rebasing branch 'main' on 'a36b6d5'.
      (use "git commit --amend" to amend the current commit)
      (use "git rebase --continue" once you are satisfied with your changes)
    nothing to commit, working tree clean
    $ git branch --force main # CMD_12
    fatal: cannot force update the branch 'main' used by worktree at '/Users/bobko/git-history-bug'
    $ pwd # CMD_13: Yep, we are broken
    /Users/bobko/git-history-bug
## What goes wrong
CMD_4 starts the rebase; CMD_7 runs git-history in the middle of it.

CMD_9 and CMD_12 demonstrate the broken state (`git rebase --continue` cannot finish anymore).

## Solutions that I thought of
1. The obvious one is to just forbid git-history during
   rebase/cherry-pick. Probably fine for an experimental command, but
   I believe it would forbid valid workflows.
2. Require using the explicit `--update-refs=head` flag when we are in
   git rebase state. (Forbids valid workflows when combined with
   `git rebase --update-refs`.)
3. Implicitly use `--update-refs=head` flag when we are in git rebase
   state. (Not something that users might expect. Certainly must be
   documented in the git-history(1) man page.)
4. Update all branches but the one currently being rebased. Sounds
   complicated, but I haven't managed to think of a counter-example.
   I was thinking that graphs like this might be problematic:
      * 9cc305f (main) 5
      | * 5d8f3d2 (b-4.5) 4.5
      |/
      * fbb1ec7 4
      * b47bb7e (HEAD) 3 # stop interactive rebase here, and play with git-history
      | * b052adc (b-2.5) 2.5
      |/
      * 106a0da 2
      * edff563 1
   But it looks like the end result is surprisingly "self-consistent"
   even for such graphs. The user is certainly doing something weird,
   but, what's important, the end result doesn't lead to the broken
   state described in this bug report.
   My intuition tells me something is off with the suggested
   solution, though.
5. Something else?
## Environment

git version 2.55.0 (Homebrew), cpu: arm64 Darwin 27.0.0 arm64 (macOS)

## Related notes
1. git-cherry-pick doesn't do a final ref update pass the way
   git-rebase does, so it's not affected by this specific bug (please
   correct me if I'm wrong), but it is affected by another kind of
   interaction (see point 3 below).
2. Even `git branch --force` refuses to change the ref that is
   currently being rebased (see CMD_12). git-history must not be
   allowed to do that either.
3. What if we run git-history on one of the commits mentioned in the
   git-rebase-todo file (descendants of the original HEAD) while we
   are in rebase/cherry-pick state?
   Should git-history update the git-rebase-todo file as well in such
   a case or not? git-history tries too hard to update the branches, so
   updating git-rebase-todo fits this model, but it definitely feels
   "invasive".
   (Currently, it doesn't. And it leads to the same sort of bug as in
   the current bug report anyway: CMD_9)
   (Some people might claim that this specific bug also applies to
   git-cherry-pick but has a different symptom: the result of
   git-history is silently ignored by git-cherry-pick)
4. What about feature interaction with `git rebase --update-refs`?
   (I have just learnt about `git rebase --update-refs` while writing
   this bug report so I didn't think this interaction through)

-- Nikita Bobko

Back to recent threads

[BUG] git-history in the middle of rebase leads to a broken state | The Git List