Hello Ian,

Your explanations in the e-mail to which I'm replying helped me a lot --
thanks.

On Tue, Aug 22 2017, Ian Jackson wrote:

>> debrebase needs to warn the user that they should expect to see non-ff
>> push errors from git until they finish the debrebase.  It might even
>> leave behind a hook so that after the non-ff push error, there could be
>> a hint about finishing the debrebase, but that might be too unpleasant
>> to implement.
>
> By `finish the debrebase' you mean `turn the branch from Stripped to
> Pushed or Pushable by adding a psuedomerge'.

Yes.

> By `during push' I meant `during dgit push'.  But of course in a
> post-dsc world, there would only be `git push' so there would have to
> be an invocation of `git-debrebase'.  The most natural implementation
> seems to me to be `git-debrebase push'.
>
> I don't know what potential hook you are talking about.  I don't think
> there is a facility for extending `git push' in this way.

.git/hooks/pre-push.sample seems to be the place.

>> > I think you are proposing to expose A, B and D to the user and to
>> > hide C by somehow always reattaching a pseudomerge after each
>> > rebase.  But I don't think git-rebase can do that.
>> 
>> Why not?
>
> Suppose we are in state Rebasing.  Ie we are in the middle of
> `git-rebase' (whether stopped due to -i or a conflict or something).
> The user deals with whatever it is, and runs `git-rebase --continue'.
>
> Suppose there are no further reasons to stop.  git-rebase will
> generate the linear branch appropriately.  But I am not aware of any
> way to cause git-rebase to make an appropriate pseudomerge before
> returning control to the user.
>
> git-rebase --preserve-merges is no good, because even aside from the
> weirdness mentioned in the BUGS section of git-rebase(1), there is no
> way to tell git how the pseudomerge should be generated.
>
> (thoughts)
>
> Hrm.  I guess we could feed git-rebase an `exec' thing in its
> instruction list.  This might work, but there is another problem with
> the model which tries to hide the state Stripped from the user.
>
>> > Ie, the user might do
>> >   git-debrebase -i --autosquash
>> 
>> I don't understand this command.  In my head, debrebase performs two
>> atomic operations: (i) laundering the branch; and (ii) reattaching the
>> pseudomerge before push.
>
> I think you mean, it performs, in any one invocation, one of those two
> operations.  (i) takes the branch from most states I discuss above to
> Stripped and (ii) takes the branch from Stripped to Pushed or
> Pushable.
>
> But this is asking the user to do extra typing: they have to run
> `git-debrebase launder' before running `git-rebase -i'.  Worse, if
> they forget to do so they will get some kind of strange mess where
> git-rebase tries to reapply the pseudomerge as a cherry pick.
>
> Better to let the user get into the habit of always saying
> `git-debrebase'.  Additionally, `git-debrebase' knows what the correct
> rebase point is.  (Assuming the user does not want to rewrite changes
> to debian/; if they do they need to take more manual control.)
>
> So in my imagination, git-debrebase is usually a wrapper around
> git-rebse which magically knows the right base.
> [...]
>> If I'm on the right lines, it might be unwise to wrap `git rebase`.  Git
>> users are pretty good at that command; if we leave them to invoke it,
>> they stand a better chance of understanding the whole workflow.  But I'm
>> not sure.
>
> That is a plausible argument.  The problem is that git-rebase is a
> bit of a footgun - more so in the presence of pseudomerges.

I think that my concerns about failing to leverage user's existing
understanding of git-rebase(1) can be answered by doing the following:

  - state that git-debrebase(1) is ONLY: a wrapper around git-rebase(1)
    that magically knows the base
  - have ALL arguments to git-debrebase(1) get passed straight to
    git-rebase(1), i.e., no subsubcommands
  - move the other functionality (`git debrebase push`, new upstream
    version command) to other subcommands of `git`, e.g. `git
    debpush`, `git debnewupstream` etc.

The point of this is to make it much easier to get a grip on exactly
what `git debrebase` does.  That is a foundational piece of
understanding of the workflows surrouding these tools.

It might seem inelegant to have multiple subcommands (especially `git
debpush` which sounds almost like `dgit push`) but I think that it's a
price worth paying.  There's also a mnemonic at work: "ah, `git
debrebase` is a wrapper around `git rebase`, and `git debpush` is a
wrapper around `git push`".

>> I'm also confused about what `git debrebase --continue` could mean.
>> (ii) will always end the debrebase, but `git rebase --continue` doesn't
>> always end the rebase.  Is this another case where debrebase is wrapping
>> a plain rebase?
>
> `git-debrebase --continue' is a hypothetical wrapper around
> `git-rebase --continue' which arranges to reattach the psuedomerge.
> It is (perhaps) needed if we are trying to hide the Stripped state
> from the user.

Okay.

> There is another reason why I think it is probably a good idea to keep
> the state Stripped as long as possible, and to turn it into
> Pushed/Pushable only at the last minute:
>
> Ideally we do not want to generate a complete record of all the user's
> rebases in the permanent history.  If we generate one pseudomerge for
> each rebase, that is what would happen.
>
> We could try to avoid that by looking to see "whether the previous
> branch had been pushed".  But we don't know, of course, where it might
> have been pushed.  It might even have been pushed using an ad-hoc rune
> to a remote ref without a local tracking branch.  Conversely, it might
> have been deliberately pushed, in Stripped state, to a rebasing public
> branch.

Right.  I was thinking it could be avoided but the ad-hoc pushes make
that impossible, as you say.

-- 
Sean Whitton

Attachment: signature.asc
Description: PGP signature

Reply via email to