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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi George,

On Thu, 26 Mar 2020, George Spelvin wrote:

> On Wed, Mar 25, 2020 at 08:26:48PM +0100, Johannes Schindelin wrote:
> > On Sat, 21 Mar 2020, George Spelvin wrote:
> >> 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?
>
> Um, this example is not persuasive.  If I just leave the excess commit at
> the front of the to-do list, then it will be recreated without change.

There are _many_ ways to mess up a nested rebase, including (but not
limited to) `--onto`, forgetting `-r`, editing the todo list too much in
an editor without undo.

If you are suggesting that a nested `git rebase -i` would not need a way
to abort _just_ the nested rebase, then I fear we must stop the
conversation right here. That's not going to fly.

> (Note that if I choose too *small* a nubmer by accident, I can insert a
> "break" at the front of the list and then rebase --nested starting from
> there.)

There are many ways how a savvy user would be able to work around the
absence of a proper way to abort a nested rebase. The common theme for all
of those is:

- they are all quite involved and require knowledge of internals

- they won't change the fact that it would be seriously negligent for us
  to _not_ offer a way to abort nested rebases.

> Okay, but what if I screw up worse and type HEAD^55 instead of HEAD^5?
> nd that includes multiple merges and other messy stuff?

And Ctrl+C while the nested rebase tries to generate the todo list.

> Well, perhaps a general-purpose optimization could be applied: for the
> first, mandatory, edit-todo, don't actually check out the tree until the
> edit is complete.  When it is, chop off any prefix of unaltered commits
> and start the rebase at the first change.
>
> That would make inadvertently specifying a start point too far back
> reasonably harmless.
>
> It would also provide one level of nested abort in the case of a nested
> rebase.  Until you save the initial todo, the rebase doesn't do anything
> except some bookkeeping.  So you could have that be a special case,
> without providing a more general nested --abort.
>
> The main problem with a full nested rebase is that you need to define when
> the inner rebase completes and the outer rebase resumes.  I very much
> want the ability to move commits around between the outer rebase and the
> inner one, which makes that distinction ill-defined.

That probably means that we have not thought through the problem, at least
not enough. If we have nested levels, then we might need to record those
nested levels, including the equivalent of `ORIG_HEAD`, `onto` and the
todo list. And of course make them accessible to the user.

By default, we can still work on the "inner-most" rebase. The output of
`git status` can hint at the nested level, to give an indication, as can
the prompt.

We should strive to make this as easy to use as possible, while still
supporting more involved use cases (for power users such as myself, at the
least).

Mind you: I do not necessarily request a perfect design. I just don't want
to slam the door shut when it comes to more sophisticated use cases. I
_really_ would like to have a way to "just redo the latest 5 commands",
for example, but I have no illusion about getting that any time soon.

> > 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...
>
> The thing is, it's already quite possible to make a mess of a rebase
> halfway through and need to abort after you've put a lot of work in.

Tell me about it!

> I think a more general-purpose recovery mechanism might be more
> useful.
>
> For example, if the --edit-todo included a (commented-out) list of what
> had already been done, then after realizing that you screwed up
> conflict resolve b' and have now committed bad resolutions c' and d'
> on top of it, you could easily rebase --nested and replace b', c' and d'
> with the original b, c and d.
>
> Without aborting and throwing away a' as well, which was perhaps a lot of
> work.

We do have the `done` file, but that does not discern between commands
in the todo list that have been there in the first place and commands that
have been added by the user _during_ the rebase. And of course it does not
reflect any commands that have been removed/changed by the user during the
rebase.

So yeah, something like a journal, maybe.

> >> 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.
>
> What I mean by "trigger" is thatthe check would notice a missing commit
> and produce a warning or error, as configured.

I guess `missingCOmmitsCheck` really only kicks in right before/after the
user edits the todo list. So maybe I was worried for nothing in this
instance.

Thank you for thinking about this feature, and for discussing it with me.
I think it will be a really nice feature to have, and I want to avoid
problems with a design that simply won't allow for certain use cases
(remember how `git rebase --preserve-merges` does not allow for reordering
commits, and how the design of that feature simply made this bug
unfixable? I _dearly_ regret not thinking that through).

Ciao,
Dscho




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux