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

Re: Feature request: rebase -i inside of rebase -i

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 25, 2020, 19:26 UTC
Message-ID
<nycvar.QRO.7.76.6.2003252008490.46@tvgsbejvaqbjf.bet>
In-Reply-To
<20200321175612.GC19579@SDF.ORG>
Hi George,
On Sat, 21 Mar 2020, George Spelvin wrote:
Show 9 quoted lines
> On Sat, Mar 21, 2020 at 11:51:10AM +0100, Johannes Schindelin wrote:
> > My biggest caveat is that I had to force-exit the rebase at some stage
> > due to reasons I only vaguely remember. It had something to do with the
> > replacement cache not being updated when an `exec` is executed that adds a
> > replacement object via `git replace` [*1*]. This issue might have
> > _nothing_ to do with nested rebases, but as I said, my recollection is
> > vague.
>
> This is the sort of internal implementation gotcha I worry about.
There's plenty more gotchas like that ;-)
Show 7 quoted lines
> > There are a couple more concerns, of course, such as: what to do if the
> > user deletes the entire todo list (which is traditionally the only way to
> > abort a rebase)? My gut feeling is that it should go back to the
> > _previous_ version of the todo list.
>
> My assumption has been that, for simplicity, there would only be one
> commit in progress, and aborting it aborts everything.

But that does not necessarily make sense. Imagine that you rebase the latest three commits, interactively. Then a merge conflict in the third makes you realize that the first commit is no longer needed.

Enter the nested rebase. You manually re-schedule the failed `pick` via `git rebase --edit-todo` and then run the nested rebase: `git reset --hard && git rebase -i --nested HEAD~2`.

Except that you made a typo and said `HEAD~3` instead of `HEAD~2`. You delete the entire todo list to get a chance to restart the nested rebase.

But now the entire rebase gets aborted?

If that would happen to me, I would unleash a whole slew of rarely used words in the vague direction of whoever implemented the nested rebase feature...

Show 11 quoted lines
> > Another big concern is what to do about `rebase.missingCommitsCheck`: with
> > nested rebases, this will get increasingly tricky. Like, imagine you are
> > rebasing 5 commits, the third of them results in merge conflicts, you
> > realize that it is obsolete and so is now the first, already rebased
> > commit. You do a nested rebase of the latest two commits to drop them, but
> > they don't have their original commit hashes any longer. So it gets a bit
> > finicky to keep track of what commit has been dropped on purpose and what
> > was forgotten to pick instead.
>
> This doesn't *seem* difficult, but I don't know how the current mechanism
> works.

The implementation details do not matter at this stage. You have to get the design of the feature right.

I am unfamiliar with the design of the feature as it is implemented right now, but I imagine that it needs to be adjusted for nested rebases, as we no longer have a single original todo list to roll back to.

Show 30 quoted lines
> It just checks that all commits that were on the to-do list when the
> editor started are still listed (possibly marked "drop") when it exits.
>
> When you do a nested commit, additional commits are prepended to the to-do
> list, you're dropped into the editor, and the same check is made when the
> editor returns.
>
> If rebase.missingCommitsCheck = error is triggered, you end up with the
> <upstream> tree state with nothing applied and may either --continue to
> ignore the error or --edit-todo to put back the missing commits.
>
>
> Let me give an example.  Suppose I have commits a-b-c-d-e, and start
> with rebase -i b.
>
> My to-do list starts out as c-d-e, but suppose I decide to cherry-pick
> z and add it to the list, so it's now z-c-d-e.
>
> So I start rebasing, and it turns out that d creates a merge conflict
> because I forgot a prerequisite patch y.  And I really want y and z before
> b, anyway.
>
> So the tree state is currently a-b-z'-c', with d in progress and e yet to
> do.  In my simple model, I have to resolve and commit d, so the tree
> state is a-b-z'-c'-d'.  Then I can rebase -i a, and am presented with
> a to-do list of b-z'-c'-d'-e.
>
> If I delete any of those five commits, then rebase.missingCommitsCheck
> will trigger.  If I put y in the list, save it, then change my mind and
> --edit-todo and delete y, it will also trigger.

As I said, I am not using that feature myself, so I do not even know what "trigger" means in this context. It might totally be okay to use the existing code as-is in the context of a nested rebase. That remains to be verified, though, I think.

Show 5 quoted lines
> Now, it sould be nice if there were a way to say "screw this mess; just
> check out HEAD and put d back on the to-do list", but that could
> create a bit of a mess if I've split d and already committed half of
> it.  If I used that after doung that, I'd have a to-do list of
> b-z'-c'-d'-d-e which might be awkward, but maybe it wouldn't be too bad.
There is all kind of opportunity for messes, all right.

Ciao, Johannes

Previous: George SpelvinNext: George Spelvin
Message 6 of 25 in “Feature request: rebase -i inside of rebase -i”
  1. George SpelvinMar 20, 2020
  2. Junio C HamanoMar 20, 2020
  3. George SpelvinMar 20, 2020
  4. Johannes SchindelinMar 21, 2020
  5. George SpelvinMar 21, 2020
  6. Johannes SchindelinMar 25, 2020
  7. George SpelvinMar 26, 2020
  8. Johannes SchindelinMar 28, 2020
  9. George SpelvinMar 28, 2020
  10. George SpelvinMar 31, 2020
  11. Philip OakleyMar 31, 2020
  12. Phillip WoodMar 31, 2020
  13. Philip OakleyApr 1, 2020
  14. Phillip WoodApr 7, 2020
  15. Johannes SchindelinApr 4, 2020
  16. Johannes SchindelinApr 4, 2020
  17. George SpelvinApr 4, 2020
  18. Sebastien BruckertApr 6, 2020
  19. George SpelvinApr 6, 2020
  20. Sebastien BruckertApr 7, 2020
  21. George SpelvinApr 7, 2020
  22. Philip OakleyMar 30, 2020
  23. George SpelvinMar 30, 2020
  24. Philip OakleyMar 30, 2020
  25. Johannes SixtMar 21, 2020

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.