[darcs-users] Make darcs force-commute patches from CLI, to learn about darcs?

Ben Franksen ben.franksen at online.de
Sat Jun 27 08:03:27 UTC 2020

Am 26.06.20 um 20:55 schrieb James Cook:
>>> I've been reading about patch theory [0]. I *thought* what's supposed
>>> to happen is this:
>>> * The effect of B' is the same as the effect of A. (i.e. create the file)
>>> * The effect of A' is the same as the effect of B. (i.e. add "some text")
>>> * Therefore, B'A' does the same thing as AB.
>>> * B' and A' include some information about the conflict, in addition
>>> to their effects described above. (They are "conflictor" patches.)
>>> * If I commute B' and A' again, I get back AB, since <-> is a
>>> symmetric relation.
>> I understand. However, there is no patch theory I am aware of that is
>> able to make this work, except those where *any* two patches commute, so
>> there are no dependencies and patches never conflict.
> Thank you. I've learned a lot from your reply.

You are welcome.

> I have an idea for a patch theory that would satisfy these properties,
> and may have other advantages and might even be backward-compatible with
> darcs. I am not confident that it works, but I would love to have some
> feedback, if someone finds the time to read it. Is this list a good
> place to post something like that?

Sure, I wouldn't know of any better one.

>> As I said in the beginning, there is no force-commute command in darcs
>> because that would be unsound. By definition, if B depends on A this
>> means A;B does /not/ commute. In the theory, one starts with primitive
>> patches for which there is no total merge operation, only a partial
>> clean-merge that may fail. If you have two independently recorded
>> patches A and B in the same context (we write this as A\/B), then
>> clean-merge succeeds iff A^;B commutes (where ^ means inversion). If
>> clean-merge(A\/B) does not succeed, then A\/B are said to be in conflict.
> Does darcs satisfy the property that if I merge two arbitrary
> repositories R and S to produce a new repository M, then separate out
> the patches again (i.e. pull just R's patches or just S's patches from
> M to a fresh repo) then I get back R and S?


That said, you should be advised that both patch theory implementations
("formats") currently in use, namely darcs-1 and darcs-2, have bugs. In
practice that means you may not be able to do such a separation for
complicated conflict scenarios, though I think if it succeeds then the
resulting repos should be equivalent. We have implemented a new one,
darcs-3, which closely follows the camp paper and does not have any of
these bugs. But that is not yet released. You can play with it using our
development version at http://darcs.net/screened, but please don't use
it for serious work, because the on-disk format may still change.

> I hope the question makes sense. I can write a concrete sequence of
> commands if it doesn't.

It makes perfectly good sense.

> I had assumed this property was true because I thought force-commuting
> satisfied the magical properties in my previous email. I hope it is
> still true despite me being wrong about force-commuting.


>> When we add conflictors, we extend the set/type of primitive patches to
>> a larger set, such that now any two patches can be merged. However, we
>> must require that this extension preserves commutation behavior. In
>> particular, if A;B does not commute, then their embeddings in the larger
>> set of patches must commute neither.
> Ah, I had a different picture in mind. I thought that after adding in
> conflictors, then technically you end up with a universe of patches
> where everything commutes, but the patches end up looking ugly and
> unintuitive if you commute things that aren't "supposed" to. I thought a
> "force-commute" was simply a commute that wouldn't have been possible
> before adding conflictors to your universe of patches. This is what I
> hope my patch theory accomplishes.

I'd be interested to hear more about your patch theory.

BTW, the property you asked about above is a consequence of the so
called merge-commute law. If you have a forking pair A\/B and merge it,
you end up with

      / \
     B'  A'
    /     \
   o       o
    \     /
     A   B
      \ /

where by convention patches are applied bottom to top i.e. you should
imagine the patches as arrows pointing upward; arrow heads are hard to
paint in ascii ;-).

The merge-commute law says that the two "branches" of this merge, i.e.
A;B' and B;A' commute to each other. This ensures that it does not
matter whether you pull from R into S or vice versa. It also implies
that you can get back to the original state A\/B by commuting either A
or B to the end and then obliterating it.

This must remain true if the merge is conflicted and then it implies
that any individual conflicted patch (here: A' or B') can be made
unconflicted by commuting with those it conflicts with.


More information about the darcs-users mailing list