Conflict confusing confusion when deleting a deleted file with gifts

My confusion arises from the following statement taken from here :

When deleting patches that conflict with each other (for example, changing the same part of a file), Darcs detects a conflict and places it in the contents of the repository. Then it allows the user to solve the problem.

This seemed incompatible with what I saw, so I created the following workflow using darcs 2.5.2:

  • Create repo foo;
  • Create a non-empty file in foo and write it down;
  • Clone foo to bar;
  • Delete the file in foo and write it down;
  • Add one more line to the file in the panel and write it down;
  • Pull from foo to bar, get a conflict notification;

After completing these steps, I ran darcs whatsnew on the line, and two “patch primitives” were shown:

  • A tail that removes the entire "non-empty file in foo", but without mentioning the line added and written to the line;
  • The rmfile file that deletes the file.

My question is: why is there no mention of a line added and recorded in a bar?

If I ran darcs revert on a line, then everything makes sense: I see a "non-empty file" that is not affected by any conflicting patch, according to this statement, taken from here :

The darcs revert command will remove the conflict mark and return to the state before the conflicting fixes.

But if I run darcs mark-conflicts , I will return to the same state as after pull, with the two “primitives of patches” mentioned above and did not mention the added and recorded line in the bar.


For reference / playback here is my full workflow from the command line:

 $ mkdir foo $ cd foo/ foo$ darcs initialize foo$ touch shopping foo$ vi shopping <-- add a couple of lines foo$ darcs add shopping foo$ darcs record addfile ./shopping Shall I record this change? (1/2) [ynW...], or ? for more options: y hunk ./shopping 1 +cake +pie Shall I record this change? (2/2) [ynW...], or ? for more options: y What is the patch name? Added shopping Do you want to add a long comment? [yn]n Finished recording patch 'Added shopping' foo$ cd .. $ darcs get foo/ bar $ cd bar/ bar$ vi shopping <-- add another line bar$ darcs record hunk ./shopping 2 +beer Shall I record this change? (1/1) [ynW...], or ? for more options: y What is the patch name? Added beer Do you want to add a long comment? [yn]n Finished recording patch 'Added beer' bar$ cd ../foo foo$ rm shopping foo$ darcs record hunk ./shopping 1 -cake -pie Shall I record this change? (1/2) [ynW...], or ? for more options: y rmfile ./shopping Shall I record this change? (2/2) [ynW...], or ? for more options: y What is the patch name? Removed shopping Do you want to add a long comment? [yn]n Finished recording patch 'Removed shopping' foo$ cd ../bar bar$ darcs pull Pulling from "../foo"... Mon Nov 14 19:26:44 GMT 2011 dukedave@gmail.com * Removed shopping Shall I pull this patch? (1/1) [ynW...], or ? for more options: y Backing up ./shopping(-darcs-backup0) We have conflicts in the following files: ./shopping Finished pulling and applying. bar$ darcs whatsnew hunk ./shopping 1 -cake -pie rmfile ./shopping 
+4
source share
1 answer

If you run darcs changes -v inside the panel, you will see the history of your change, including the conflict introduced by pulling conflicting patches.

I brought your example to something a little shorter:

 DARCS=/usr/bin/darcs $DARCS init --repo foo cd foo echo 'a' > myfile $DARCS add myfile && $DARCS record -am 'Add myfile' $DARCS get . ../bar rm myfile $DARCS record -am 'Remove myfile' cd ../bar echo 'b' >> myfile $DARCS record -am 'Change myfile' $DARCS pull -a ../foo $DARCS changes -v 

Now, after that, I see this output from darcs changes -v

 Tue Nov 15 19:44:38 GMT 2011 Owen Stephens < darcs@owenstephens.co.uk > * Remove myfile conflictor [ hunk ./myfile 2 +b ] |: hunk ./myfile 1 -a conflictor {{ |: hunk ./myfile 2 +b |: hunk ./myfile 1 -a }} [] |hunk ./myfile 1 |-a |: rmfile ./myfile Tue Nov 15 19:44:38 GMT 2011 Owen Stephens < darcs@owenstephens.co.uk > * Change myfile hunk ./myfile 2 +b Tue Nov 15 19:44:38 GMT 2011 Owen Stephens < darcs@owenstephens.co.uk > * Add myfile addfile ./myfile hunk ./myfile 1 +a 

So let me explain the crazy output of "Remove myfile". "Delete myfile" exists as in foo:

 Tue Nov 15 19:44:38 GMT 2011 Owen Stephens < darcs@owenstephens.co.uk > * Remove myfile hunk ./myfile 1 -a rmfile ./myfile 

So hunk on line 1 and deleting the file.

Pulling “remove myfile” into the panel, we modify the patch contents by introducing special “conflicting” primitives that represent primitives in “Remove myfile” that conflict with other primitives in the bar. But there is no loss of information here - we can always return to the original primitives by removing the conflicting changes - in this case, undoing the "myfile change".

Conflictors are confusing, but AFAICT essentially divides the changes that conflict with the current patch, x into 2 sets: "ix", which is a set of fixes that includes: i) fixes that conflict with x and some other fixes in repo ii) fixes, conflicting with a patch that conflicts with x "xx", which is a sequence of patches that only conflict with patch x. I think the reason this is done is because Conflictors are "annihilating" primitives that cause conflicts, but only those that were not canceled by another Conflictor.

The result we see looks something like this:

 "conflictor" ix "[" xx "]" x 

I abuse the notation, but I hope you can decrypt it somewhat (see src / Darcs / Patch / V2 / (Real.hs | Non.hs) in the darcs.net registry for the full version)

In this case, "Remove myfile" has 2 primitive patches and (in this case) 2 corresponding conflicting parties when they are pulled into the bar.

The first primitive (delete line 1 from myfile) only conflicts with the primitive in "Change myfile" (add 'b' to line 2 myfile), and so the first conflict:

 conflictor [ <--- The start of xx (no ix here) hunk ./myfile 2 +b ] <--- The end of xx |: hunk ./myfile 1 <--- x -a 

NB ("|:" is a marker that limits the context of the "Non" primitive from primitive - I will not try and explain it further, just read below :: to see the primitive in question)

The second primitive (delete myfile) is a bit more complicated: (rmfile myfile) conflicts with (adds 'b' to line 2 of myfile), which, as we know, conflicts with (remove line 1 from myfile), so they both go in "ix" , without patches in "xx". I will remove the unnecessary "|:" delimiters and spaces:

 conflictor {{ hunk ./myfile 2 +b hunk ./myfile 1 -a }} [] <--- no xx |hunk ./myfile 1 <--- start of x |-a |: rmfile ./myfile <--- end of x 

The final (rmfile myfile) has some context for determining the exact primitive that we have in mind (I'm not quite sure why / how it is required, but we are), which is marked by the leading '| and is limited to the "|:" character.

Finally, try to explain the output of darcs whatsnew to foo; when I think that the actual effect of the conflict "cancel" any conflicting spots, giving no effect to either one or the other; gives a start to some explanations: http://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory_and_conflicts .

I think that what you see is the result of the forced switching of "Change myfile" and "Remove myfile" calls them A and B respectively. Then, to merge the two, Darcs creates A^-1 and commutes A^-1 and B to give B' and (A^-1)' , where B' has the effect A^-1 (since we force the commutation to work) , which means that the B' effect (i.e. the combined "remove myfile") actually just cancels the addition of the line made by "Change myfile".

I did not have time to see how darcs mark-conflicts works, so I can not yet explain the working changes that you see with the darcs changes in the panel.

+7
source

Source: https://habr.com/ru/post/1381356/


All Articles