To me it shows that we need to improve "git rebase --update-refs" so that it can rebase a tree of branches automatically. Doing it manually is labor intensive and error-prone (your example output shows it is easy to forget when you're meant to be resolving a conflict instead aborting the rebase and checking out another branch). In the example below
git rebase --update-refs --rebase-merges main B
will rebase A and B, but we don't have a way of including C.
Show 518 quoted lines
>> I've indented the output of commands, so that they are easier to
>> distinguish.
>>
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * G ada8aff4f08a (r/B, B) foo j
>> * G d6163efdc2db bar i
>> | * G 450f3a7f4f25 (r/HEAD, r/C, C) bar l
>> | * G f7309b21ebfa bar k
>> |/
>> * G e949e24ba457 (HEAD -> A, r/A) bar h
>> * G 607b450498be bar g
>> |\
>> | * G b787bcd373d9 bar e
>> * | G c496b325576f baz f
>> |/
>> | * G dfd9156d099a (r/main, main) foo d
>> | * G 4940c7d739be bar c
>> | * G cebc8fde25bb foo b
>> |/
>> * G 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git brebase --rebase-merges main
>> Rebase: conflict
>> Bisecting: 0 revisions left to test after this (roughly 1 step)
>> [4940c7d739be44c0ca32c1d610b85fd5650e1528] bar c
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: conflict
>> Bisecting: 0 revisions left to test after this (roughly 0 steps)
>> [cebc8fde25bbe16c0f5f48e39642b3551f4f56e6] foo b
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: success
>> 4940c7d739be44c0ca32c1d610b85fd5650e1528 is the first 'bad' commit
>> commit 4940c7d739be44c0ca32c1d610b85fd5650e1528
>> Author: Alejandro Colomar <alx@kernel.org>
>> Date: 2026-10-05 14:42:32 +0200
>>
>> bar c
>>
>> bar | 1 +
>> 1 file changed, 1 insertion(+)
>> create mode 100644 bar
>> bisect found first 'bad' commit
>> Auto-merging bar
>> CONFLICT (add/add): Merge conflict in bar
>> error: could not apply 899eeb5c4e32... bar e
>> hint: Resolve all conflicts manually, mark them as resolved with
>> hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
>> hint: You can instead skip this commit: run "git rebase --skip".
>> hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
>> hint: Disable this message with "git config set advice.mergeConflict false"
>> Could not apply 899eeb5c4e32... # bar e
>> alx@debian:~/tmp/brebase$ git rebase --abort
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 655c38e3cee8 (HEAD -> A) bar h
>> * 1ababced193d bar g
>> |\
>> | * 899eeb5c4e32 bar e
>> * | 761c9dbcfa5b baz f
>> |/
>> | * ada8aff4f08a (r/B, B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C, C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | * | c496b325576f baz f
>> | |/
>> | | * dfd9156d099a (r/main, main) foo d
>> | | * 4940c7d739be bar c
>> | |/
>> |/|
>> * | cebc8fde25bb foo b
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git switch B
>> Switched to branch 'B'
>> Your branch is up to date with 'r/B'.
>> alx@debian:~/tmp/brebase$ git brebase A
>> Rebase: conflict
>> Bisecting: 2 revisions left to test after this (roughly 1 step)
>> [899eeb5c4e32397f0fe138c5b9f486d4682939cb] bar e
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: conflict
>> Bisecting: 0 revisions left to test after this (roughly 0 steps)
>> [cebc8fde25bbe16c0f5f48e39642b3551f4f56e6] foo b
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: conflict
>> cebc8fde25bbe16c0f5f48e39642b3551f4f56e6 is the first 'bad' commit
>> commit cebc8fde25bbe16c0f5f48e39642b3551f4f56e6
>> Author: Alejandro Colomar <alx@kernel.org>
>> Date: 2026-10-05 14:42:04 +0200
>>
>> foo b
>>
>> foo | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> bisect found first 'bad' commit
>> Auto-merging foo
>> CONFLICT (content): Merge conflict in foo
>> error: could not apply ada8aff4f08a... foo j
>> hint: Resolve all conflicts manually, mark them as resolved with
>> hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
>> hint: You can instead skip this commit: run "git rebase --skip".
>> hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
>> hint: Disable this message with "git config set advice.mergeConflict false"
>> Could not apply ada8aff4f08a... # foo j
>> alx@debian:~/tmp/brebase$ echo j >foo
>> alx@debian:~/tmp/brebase$ git add foo
>> alx@debian:~/tmp/brebase$ git rebase --continue
>> [detached HEAD 2e0b72e7440a] foo j
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> Successfully rebased and updated refs/heads/B.
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 2e0b72e7440a (HEAD -> B) foo j
>> * a1c6c1fb7ca2 bar i
>> * d8fa6c4da463 bar h
>> * bef9f1c4da4d bar e
>> * 0bac26895b94 baz f
>> | * 655c38e3cee8 (A) bar h
>> | * 1ababced193d bar g
>> | |\
>> | | * 899eeb5c4e32 bar e
>> | |/
>> |/|
>> | * 761c9dbcfa5b baz f
>> |/
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C, C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | * | c496b325576f baz f
>> | |/
>> | | * dfd9156d099a (r/main, main) foo d
>> | | * 4940c7d739be bar c
>> | |/
>> |/|
>> * | cebc8fde25bb foo b
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git brebase A
>> Rebase: success
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 5ff93a00f9f2 (HEAD -> B) foo j
>> * 01522206a7bc bar i
>> * 655c38e3cee8 (A) bar h
>> * 1ababced193d bar g
>> |\
>> | * 899eeb5c4e32 bar e
>> * | 761c9dbcfa5b baz f
>> |/
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C, C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | * | c496b325576f baz f
>> | |/
>> | | * dfd9156d099a (r/main, main) foo d
>> | | * 4940c7d739be bar c
>> | |/
>> |/|
>> * | cebc8fde25bb foo b
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git switch C
>> Switched to branch 'C'
>> alx@debian:~/tmp/brebase$ git brebase A
>> Rebase: success
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 06d462903420 (HEAD -> C) bar l
>> * 20f0a887b83b bar k
>> | * 5ff93a00f9f2 (B) foo j
>> | * 01522206a7bc bar i
>> |/
>> * 655c38e3cee8 (A) bar h
>> * 1ababced193d bar g
>> |\
>> | * 899eeb5c4e32 bar e
>> * | 761c9dbcfa5b baz f
>> |/
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | * | c496b325576f baz f
>> | |/
>> | | * dfd9156d099a (r/main, main) foo d
>> | | * 4940c7d739be bar c
>> | |/
>> |/|
>> * | cebc8fde25bb foo b
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git switch A
>> Switched to branch 'A'
>> alx@debian:~/tmp/brebase$ git brebase --rebase-merges main
>> Rebase: conflict
>> Bisecting: 0 revisions left to test after this (roughly 0 steps)
>> [4940c7d739be44c0ca32c1d610b85fd5650e1528] bar c
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: conflict
>> 4940c7d739be44c0ca32c1d610b85fd5650e1528 is the first 'bad' commit
>> commit 4940c7d739be44c0ca32c1d610b85fd5650e1528
>> Author: Alejandro Colomar <alx@kernel.org>
>> Date: 2026-10-05 14:42:32 +0200
>>
>> bar c
>>
>> bar | 1 +
>> 1 file changed, 1 insertion(+)
>> create mode 100644 bar
>> bisect found first 'bad' commit
>> Auto-merging bar
>> CONFLICT (add/add): Merge conflict in bar
>> error: could not apply 899eeb5c4e32... bar e
>> hint: Resolve all conflicts manually, mark them as resolved with
>> hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
>> hint: You can instead skip this commit: run "git rebase --skip".
>> hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
>> hint: Disable this message with "git config set advice.mergeConflict false"
>> Could not apply 899eeb5c4e32... # bar e
>> alx@debian:~/tmp/brebase$ echo e >bar
>> alx@debian:~/tmp/brebase$ git add bar
>> alx@debian:~/tmp/brebase$ git rebase --continue
>> [detached HEAD 2a4fa7fe2f44] bar e
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> Successfully rebased and updated refs/heads/A.
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 0954f3d9b9e1 (HEAD -> A) bar h
>> * 4f09c21bf2ca bar g
>> |\
>> | * 2a4fa7fe2f44 bar e
>> * | e42246e75159 baz f
>> |/
>> | * 06d462903420 (C) bar l
>> | * 20f0a887b83b bar k
>> | | * 5ff93a00f9f2 (B) foo j
>> | | * 01522206a7bc bar i
>> | |/
>> | * 655c38e3cee8 bar h
>> | * 1ababced193d bar g
>> | |\
>> | | * 899eeb5c4e32 bar e
>> | * | 761c9dbcfa5b baz f
>> | |/
>> | | * ada8aff4f08a (r/B) foo j
>> | | * d6163efdc2db bar i
>> | | | * 450f3a7f4f25 (r/HEAD, r/C) bar l
>> | | | * f7309b21ebfa bar k
>> | | |/
>> | | * e949e24ba457 (r/A) bar h
>> | | * 607b450498be bar g
>> | | |\
>> | | | * b787bcd373d9 bar e
>> | | * | c496b325576f baz f
>> | | |/
>> | | | * dfd9156d099a (r/main, main) foo d
>> | |_|/
>> |/| |
>> * | | 4940c7d739be bar c
>> |/ /
>> * / cebc8fde25bb foo b
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git rebase --onto A 655c38e3cee8 B
>> Successfully rebased and updated refs/heads/B.
>> alx@debian:~/tmp/brebase$ git rebase --onto A 655c38e3cee8 C
>> Successfully rebased and updated refs/heads/C.
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 4a4ba76f55a4 (HEAD -> C) bar l
>> * 86350e1490f3 bar k
>> | * 4b6b40b14255 (B) foo j
>> | * ba5a233ee4bc bar i
>> |/
>> * 0954f3d9b9e1 (A) bar h
>> * 4f09c21bf2ca bar g
>> |\
>> | * 2a4fa7fe2f44 bar e
>> * | e42246e75159 baz f
>> |/
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | * | c496b325576f baz f
>> | |/
>> | | * dfd9156d099a (r/main, main) foo d
>> | |/
>> |/|
>> * | 4940c7d739be bar c
>> * | cebc8fde25bb foo b
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git switch A
>> Switched to branch 'A'
>> alx@debian:~/tmp/brebase$ git brebase --rebase-merges main
>> Rebase: success
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 30e2d96b3da5 (HEAD -> A) bar h
>> * 01702a5b5d6b bar g
>> |\
>> | * c961883d543a bar e
>> * | e17aadb725c4 baz f
>> |/
>> * dfd9156d099a (r/main, main) foo d
>> | * 4a4ba76f55a4 (C) bar l
>> | * 86350e1490f3 bar k
>> | | * 4b6b40b14255 (B) foo j
>> | | * ba5a233ee4bc bar i
>> | |/
>> | * 0954f3d9b9e1 bar h
>> | * 4f09c21bf2ca bar g
>> | |\
>> | | * 2a4fa7fe2f44 bar e
>> | |/
>> |/|
>> | * e42246e75159 baz f
>> |/
>> * 4940c7d739be bar c
>> * cebc8fde25bb foo b
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | |/
>> |/|
>> | * c496b325576f baz f
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git rebase --onto A 0954f3d9b9e1 C
>> Successfully rebased and updated refs/heads/C.
>> alx@debian:~/tmp/brebase$ git rebase --onto A 0954f3d9b9e1 B
>> Auto-merging foo
>> CONFLICT (content): Merge conflict in foo
>> error: could not apply 4b6b40b14255... foo j
>> hint: Resolve all conflicts manually, mark them as resolved with
>> hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
>> hint: You can instead skip this commit: run "git rebase --skip".
>> hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
>> hint: Disable this message with "git config set advice.mergeConflict false"
>> Could not apply 4b6b40b14255... # foo j
>> alx@debian:~/tmp/brebase$ git rebase --abort
> > Oh, this was a mistake; I should have resolved the conflict here
> instead of using brebase below. (brebase produced the same exact
> conflict). :)
> > > Cheers,
> Alex
> >> alx@debian:~/tmp/brebase$ git switch B
>> Already on 'B'
>> Your branch and 'r/B' have diverged,
>> and have 8 and 6 different commits each, respectively.
>> (use "git pull" if you want to integrate the remote branch with yours)
>> alx@debian:~/tmp/brebase$ git brebase A
>> Rebase: conflict
>> Bisecting: 2 revisions left to test after this (roughly 1 step)
>> [c961883d543a2393aacfd6a8345e1d29e6857f7f] bar e
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: conflict
>> Bisecting: 0 revisions left to test after this (roughly 0 steps)
>> [dfd9156d099ad3507a2850294c7a584b80712f04] foo d
>> running '.git/bisect-rebase/git-bisect-run-callback'
>> Rebase: conflict
>> dfd9156d099ad3507a2850294c7a584b80712f04 is the first 'bad' commit
>> commit dfd9156d099ad3507a2850294c7a584b80712f04
>> Author: Alejandro Colomar <alx@kernel.org>
>> Date: 2026-10-05 14:42:50 +0200
>>
>> foo d
>>
>> foo | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> bisect found first 'bad' commit
>> Auto-merging foo
>> CONFLICT (content): Merge conflict in foo
>> error: could not apply 4b6b40b14255... foo j
>> hint: Resolve all conflicts manually, mark them as resolved with
>> hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
>> hint: You can instead skip this commit: run "git rebase --skip".
>> hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
>> hint: Disable this message with "git config set advice.mergeConflict false"
>> Could not apply 4b6b40b14255... # foo j
>> alx@debian:~/tmp/brebase$ echo j >foo
>> alx@debian:~/tmp/brebase$ git add foo
>> alx@debian:~/tmp/brebase$ git rebase --continue
>> [detached HEAD e7fdf07fd077] foo j
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> Successfully rebased and updated refs/heads/B.
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * e7fdf07fd077 (HEAD -> B) foo j
>> * dddf632a735f bar i
>> * 7ac284de12ba bar h
>> * e4541508ab3e bar e
>> * cefec5878c67 baz f
>> | * 6c7952d6fec5 (C) bar l
>> | * bd43684f73c8 bar k
>> | * 30e2d96b3da5 (A) bar h
>> | * 01702a5b5d6b bar g
>> | |\
>> | | * c961883d543a bar e
>> | |/
>> |/|
>> | * e17aadb725c4 baz f
>> |/
>> * dfd9156d099a (r/main, main) foo d
>> * 4940c7d739be bar c
>> * cebc8fde25bb foo b
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | |/
>> |/|
>> | * c496b325576f baz f
>> |/
>> * 1dcb901ebf60 foo a
>> alx@debian:~/tmp/brebase$ git brebase A
>> Rebase: success
>> alx@debian:~/tmp/brebase$ git log --all --graph --oneline
>> * 1201c4f20b19 (HEAD -> B) foo j
>> * 44103f51a783 bar i
>> | * 6c7952d6fec5 (C) bar l
>> | * bd43684f73c8 bar k
>> |/
>> * 30e2d96b3da5 (A) bar h
>> * 01702a5b5d6b bar g
>> |\
>> | * c961883d543a bar e
>> * | e17aadb725c4 baz f
>> |/
>> * dfd9156d099a (r/main, main) foo d
>> * 4940c7d739be bar c
>> * cebc8fde25bb foo b
>> | * ada8aff4f08a (r/B) foo j
>> | * d6163efdc2db bar i
>> | | * 450f3a7f4f25 (r/HEAD, r/C) bar l
>> | | * f7309b21ebfa bar k
>> | |/
>> | * e949e24ba457 (r/A) bar h
>> | * 607b450498be bar g
>> | |\
>> | | * b787bcd373d9 bar e
>> | |/
>> |/|
>> | * c496b325576f baz f
>> |/
>> * 1dcb901ebf60 foo a
>>
>> This would be impossible with an approach that handles all the way until
>> the end. I need to be able to stop a bisect-rebase operation on one
>> branch in the middle, then do a bisect-rebase on its descendants, then
>> come back to bisect-rebase the parent branch. Does this make sense?
>>
>>
>> Have a lovely day!
>> Alex
>>
>>
>>>
>>> Thanks
>>>
>>> Phillip
>>>
>>>
>>>> That's of course more involved though, so I understand in case you're
>>>> not interested in doing that.
>>>>
>>>>> If not, I will likely provide it in the man-pages repository as a help
>>>>> tool (which might end up packed by distros as part of manpages-utils).
>>>>> Is that okay to you? (I ask mainly because it's using the git-
>>>>> namespace for commands, so you should at lease be aware of it.)
>>>>
>>>> I mean overall this is our primary way of extension, by picking up
>>>> utilities that have the "git-" prefix. So arguably you don't have to ask
>>>> us for permission to do that.
>>>>
>>>> Whether it makes sense to distribute such a tool as part of
>>>> manpages-utils is a different question, and one where I myself am of a
>>>> split mind. But that feels more like a question for distributors rather
>>>> than for us in the Git project.
>>>>
>>>> Thanks!
>>>>
>>>> Patrick
>>>
>>
>> -- >> <https://www.alejandro-colomar.es>
> > >