[darcs-devel] splitting and merging patches

Ganesh Sittampalam ganesh at earth.li
Thu Mar 14 18:49:52 UTC 2013


Hi Sebastian,

On 11/03/2013 22:09, Sebastian Fischer wrote:
> Hello,
> 
> factis research would like to be able to split and merge patches that
> other patches depend on. To explain why is a bit complicated so I have
> put a motivating dialog online: https://gist.github.com/sebfisch/5136973
>
> Would you be willing to include split and/or merge commands into Darcs
> if I implement them? Are there better ways to achieve the desired
> effect? Can rebase be used for this?

If I understand correctly (and as described on factis' Trello at
https://trello.com/card/split-patches/51098501825caeb428000288/3), the
"trick" used for the split case in the dialog is that if we want to
split patch X is as follows:

 - make a fresh repo with anything that depends on X removed
 - unrecord and rerecord X as two patches XA and XB
 - then repull X and anything that depends on X
 - obliterate X

This works because in darcs-2 patch semantics, "duplicates" are not
conflicts, and the individual primitives of X are duplicates of those of
Y+Z. So if W depends on X, it also works fine in a repo with X *and* XA
and XB, and you can effectively confuse darcs into accepting that X can
be obliterated leaving just XA and XB.

As the Trello ticket notes, this doesn't work all that well in the darcs
UI and it's really an accident that it works at all. Ignoring duplicates
is somewhat controversial and causes problems for the conflicts
algorithm, so it's not really ideal to be relying on this long-term.

So...on to the alternative :-)

Rebase does let you do pretty much the same thing, but with the
important caveat that the identity of W will change in the process. So
the original repo had X and W, and the new repo will have XA, XB and W',
where W' has the same changes and the same visible commit message as W
(unless you deliberately change anything), but will be treated by darcs
as a different patch.

The workflow for this is also a bit simpler than the duplicates hack,
and doesn't involve a separate repo:

darcs rebase suspend <W>
darcs unrecord <X>
darcs record <XA>
darcs record <XB>
(or use darcs amend-unrecord and darcs amend-record to morph X into XA
and then darcs record for XB).
darcs rebase unsuspend # W becomes W' at this point

Clearly there's a possibility for a 'split' command to achieve the X ->
XA+XB step, though I'm not sure either way if it's worth the extra
command or not - definitely one for a "skeptical review"
(http://darcs.net/Development/NewFeature)

Again, rebase helps with the merge case - suppose we were undoing the
above split:

darcs rebase suspend <W'>
darcs unrecord <XB>
darcs amend-record --edit <XA> # convert it into X'
darcs rebase unsuspend # now it's W''

so again the question is whether it's worth a command specifically to
wrap up the re-recording elements.

Relatedly, the 'rebase suspend' operation ought to be invokable in other
commands - e.g. amend-record, or to support the examples above, unrecord
(and of course for split/merge if they were added).

So then the workflow for split might become something like

darcs unrecord --rebase <X> # automatically suspends/offers to suspend W
(...)

or perhaps the --rebase option should be automatically offered in
interactive selection - not really sure of the right design here yet
which is one reason I haven't done it.

So - overall I think rebase does help quite a bit with the scenarios
described, but there may still be a case for split/merge. It might also
be that for example helping out with adding auto-suspend to existing
commands is the best way to improve the workflow for factis.

Cheers,

Ganesh


More information about the darcs-devel mailing list