From: Alejandro Colomar <alx@kernel.org>
To: phillip.wood@dunelm.org.uk
Cc: Patrick Steinhardt <ps@pks.im>,
git@vger.kernel.org, Nico Williams <nico@cryptonector.com>
Subject: Re: git-rebase-walk
Date: Mon, 5 Oct 2026 15:28:21 +0200 [thread overview]
Message-ID: <asOaLyiJUmINFFFH@debian> (raw)
In-Reply-To: <95796d0d-5928-4108-bc27-b7ace4459d2a@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 18337 bytes --]
Hi Phillip,
> Date: 2026-10-04 11:03:39+0100
> From: Phillip Wood <phillip.wood123@gmail.com>
>
> On 02/10/2026 07:46, Patrick Steinhardt wrote:
> > On Thu, Oct 01, 2026 at 05:51:58PM +0200, Alejandro Colomar wrote:
> > >
> > > My script I use it in shadow-utils and in the Linux man-pages project,
> > > and is in use today. I was wondering if there was interest in
> > > integrating it to git(1).
> >
> > I guess the answer is "maybe". The fact that multiple folks have solved
> > similar issues over the course of many years is an indicator that the
> > funcitonality may be more generally useful. But it probably shouldn't be
> > a separate script, so if we wanted to integrate it I'd think the best
> > way forward would be to integrate it into git-rebase(1) directly.
>
> I agree that would be the best way forward. Adding an "--incremental", or
> "--progressive" option to rebase would be useful I think. For ease of use, I
> have a strong preference for an implementation where "rebase --continue"
> handles rebasing onto progressively more recent bases, rather than the multi
> shot approach where the user has to run "git rebase --incremental" multiple
> times. Having a multi-shot approach makes it much less clear when we've
> successfully rebased onto the desired base.
For rebasing a single branch, having --continue do what you suggest
wouldn't be too problematic.
However, for when rebasing a tree of branches, I really need a
multi-shot operation, since I want to advance branches in a very
specific order.
Below is a shell session performing such a rebase, which hopefully shows
why I need this to be multi-shot.
On the simpler case of a single branch, I'd still prefer a multi-shot
approach where --continue only advances one rebase operation, because at
the end of it I want to stop, and check git-range-diff(1) to make sure
it all makes sense.
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
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>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2026-10-05 13:28 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 11:58 git-rebase-walk Alejandro Colomar
2026-10-01 13:22 ` git-rebase-walk Patrick Steinhardt
2026-10-01 15:51 ` git-rebase-walk Alejandro Colomar
2026-10-02 6:46 ` git-rebase-walk Patrick Steinhardt
2026-10-02 7:19 ` git-rebase-walk Alejandro Colomar
2026-10-03 19:37 ` git-rebase-walk Nico Williams
2026-10-04 10:03 ` git-rebase-walk Phillip Wood
2026-10-05 13:28 ` Alejandro Colomar [this message]
2026-10-05 13:37 ` git-rebase-walk Alejandro Colomar
2026-10-06 14:01 ` git-rebase-walk Phillip Wood
2026-10-06 14:58 ` git-rebase-walk Nico Williams
2026-10-06 16:45 ` git-rebase-walk Alejandro Colomar
2026-10-08 22:05 ` git-rebase-walk Alejandro Colomar
2026-10-08 22:07 ` git-rebase-walk Alejandro Colomar
2026-10-01 17:31 ` git-rebase-walk Junio C Hamano
2026-10-01 16:10 ` git-rebase-walk Nico Williams
2026-10-01 16:50 ` git-rebase-walk Alejandro Colomar
2026-10-01 17:40 ` git-rebase-walk Nico Williams
2026-10-01 20:29 ` git-rebase-walk Alejandro Colomar
2026-10-01 21:01 ` git-rebase-walk Nico Williams
2026-10-01 21:35 ` git-rebase-walk Nico Williams
2026-10-02 2:49 ` git-rebase-walk Simon Richter
2026-10-02 3:19 ` git-rebase-walk Nico Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=asOaLyiJUmINFFFH@debian \
--to=alx@kernel.org \
--cc=git@vger.kernel.org \
--cc=nico@cryptonector.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.