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

2020-06-26 Thread 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.

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?

> 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?

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

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.

James
___
darcs-users mailing list
darcs-users@osuosl.org
https://lists.osuosl.org/mailman/listinfo/darcs-users


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

2020-06-26 Thread Ben Franksen
Am 26.06.20 um 05:03 schrieb James Cook:
>>> What I'd like to do is create a repository R1 with patches A and B,
>>> and then look at the patches that result if A and B get
>>> force-commuted.
>>>
>>> E.g. if I could pull just patch B and not A to a new repository, I
>>> think that would do the trick, but of course darcs pull won't let me
>>> do that because B depends on A.
>>
>> The main question here is: What do you expect the result of such a
>> force-commute would be?
> 
> 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.

> However, that doesn't seem to be what happened (see below).

No, indeed. The procedure I described /edits/ the patch history,
assigning new identities to both patches.

> Even if that were correct, it still doesn't leave me with a complete
> picture of what darcs actually does, so I wanted to experiment.
> 
> 
>>> Question 1: Is there a simple way to make darcs do this?
>>
>> Not exactly simple, but it is possible:
>>
>> darcs clone . ../saved
>> darcs rebase suspend # select B and A
>> darcs rebase obliterate # select A
>> darcs rebase unsuspend # select B
>> darcs pull ../saved # select A
>>
>> You should expect to get conflicts first when you unsuspend B (after
>> obliterating A) and then also when you re-pull A from the clone. You
>> will probably want to amend the conflict resolution into the conflicted
>> patch.
> 
> Thanks, that seems to have worked. (I only got the first conflict, not
> the second.) But now I'm confused.
> 
> Based on, for example, the "Forced commutation" section of
> https://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory_and_conflicts
> , I expected B' to add the file "foo", and A' to add "some text" (so,
> B' has the effect of A and A' has the effect of B).
> 
> Instead of that, I get this:
> 
> (a) If I follow your advice and amend the conflict resolution into B'
> before pulling, then (the amended) B' has the effect of AB, and A' has
> no effect.
> 
> (b) If I run "darcs revert" instead of amending the conflict
> resolution into B', then B' has the effect of A and A' still has no
> effect.
> 
> Confusingly, darcs offers to pull B from ../saved --- I thought darcs
> should consider it to already be present (as B').
> 
> I also noticed that if I run the swap a second time, I don't exactly
> get A and B back. (In the (a) case, I get patches with the same
> effects, but the new B starts with "duplicate"). I thought commutation
> was always supposed to be symmetric. Does that not apply when
> conflictors are involved?

You can rest assured that proper commutation is symmetric. The procedure
I described is *not* a commutation! The 'rebase' and 'amend' commands
create completely new patches that are unrelated to the original ones.
It's more like 'darcs unrecord', fiddle around with the changes, then
again 'darcs record' in a different order.

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.

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.

I know that Judah Jacobsen in his inverse semigroup paper writes that
adding conflictors makes any two patches commutable. This is wrong. He
derived this from the square commute law. But when you add conflictors,
this law is no longer valid. Indeed, the existence of the square-commute
law is precisely what distinguishes primitive patches from (potentially)
conflicted ones. Another way to see the contradiction here is that if
you can commute any two patches, then there is no longer any way to
define (or calculate) which patches are in conflict: if A^;B always
commutes, then A\/B always merges