Re: [RFC PATCH] rebase: implement --rewind
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Apr 5, 2023, 12:07 UTC
- Message-ID
- <4fa6d2da-4885-09d9-dddb-6f19efda6398@gmx.de>
- In-Reply-To
- <ZCMRpnS9gzN1Rlbh@ugly>
Hi Oswald,
please do reply-to-all on this list.
On Tue, 28 Mar 2023, Oswald Buddenhagen wrote:
Show 10 quoted lines
> On Tue, Mar 28, 2023 at 04:53:52PM +0200, Johannes Schindelin wrote: > >I do not think that the concept in its > >current form mixes well with being in the middle of a `--rebase-merges` > >run. > > fundamentally, it shouldn't pose a problem: the already done part leads up to > a single commit, from which a complete todo with merges up to that point can > be built again, while the remainder of the pre-existing todo should be unfazed > by the fact that you're repeatedly messing with whatever branch you stopped > in.
I guess the most important question is: What problem is the proposed `--rewind` option supposed to solve?
If the idea is to let the user re-start the rebase (for whatever reason), throwing away the current state, then the proposed code really does not handle the `--rebase-merges` case at all. Instead, it would implicitly restart the rebase with `--no-rebase-merges`, i.e. the opposite of what the user asked for.
But a more important concern is: Is this `--rewind` idea even a good one? This question brings me back to the initial question: What problem do we try to solve here? (This is a question that try as I might, I cannot see answered in the proposed commit message.)
Since I do not want to speculate about your motivation, let me explain the challenges I would like to see addressed with those rewound-or-nested rebases.
I frequently find myself in _large_ rebases (we're talking about several thousand commits, with some 100-200 merge commits), where I notice in the middle that I should have resolved a previous merge conflict in a different way.
Do I want to start over and redo the whole rebase? Sometimes I do, and `git rebase --abort` and the Bash history (Ctrl+R -i will get me back to the start of the interactive rebase) are my friend. No `--rewind` required. (Which makes me wonder why that same strategy is not good enough for your scenarios, too.)
However, that's what I need only in a few, rare instances.
What I need much, much, much more often is a way to redo only _part_ of the rebase. Like, the last 3 commits. And not from scratch, oh no! I do not want the original commits to be cherry-picked, but the ones that were already rebased.
In other words, I need a nested rebase.
Now, why do I keep bringing up this idea of a nested rebase, when such a nested rebase would not be able to perform a rewind as you asked?
The reason is that I am still very much unconvinced that `--rewind` can do anything that `git rebase --abort` and starting over cannot do. So: no patches required, right?
However, the use case that _immediately_ comes to mind when you talk about these rewinds is when a part of a rebase needs to be redone, in the middle of said rebase. And that _does_ require a nested rebase, and the `--rewind` would in most cases only throw away too much work.
Ciao, Johannes
P.S.: Yes, yes, I know, a nested rebase can be simulated via
git worktree add --detach /tmp/throw-away && git -C /tmp/throw-away rebase -i HEAD~3 && git reset --hard $(git -C /tmp/throw-away rev-parse HEAD) && git worktree remove /tmp/throw-away
but that is of course not only inconvenient, but leaves too much book-keeping and safe-guarding up to the human user, e.g. to make sure that the `git reset --hard` does not overwrite uncommitted changes/files.
FWIW I simulate nested rebases in the illustrated way _a lot_.