~jan0sch/darcs-book
Showing details for patch 0b942e025ca4fe8b06a8e7310b24f78576880b03.
diff -rN -u old-darcs-book/en/06-conflict-management.md new-darcs-book/en/06-conflict-management.md --- old-darcs-book/en/06-conflict-management.md 1970-01-01 00:00:00.000000000 +0000 +++ new-darcs-book/en/06-conflict-management.md 2024-11-24 01:28:12.311712203 +0000 @@ -0,0 +1,321 @@ +Conflict Management +=================== + +Conflicts are bound to happen when more than one person is working on something. +Two people might end up editing the same portion of text with different results. +When you have two people creating changes that change the same part of a project +and you pull them into your repository you will and up with a so called +**conflict**. `darcs` does not know what change you prefer, so it will inform +you that a **conflict** has occurred and asks you to resolve it. + +A working example +----------------- + +I have created a fairly simple piece of code that simply prints out `This is a +test!`. + +``` +$ darcs log -v +patch 7561a52b319ae52ddd1bd321d53cc01fb14fa94c +Author: raichoo@example.com +Date: Sun Jul 1 19:32:26 CEST 2018 + * initial record + addfile ./Main.hs + hunk ./Main.hs 1 + +main = putStrLn "This is a test!" +``` + +Sandra and xanderio both clone my repository and make their own changes +to the message that this program is supposed to print out. + +xanderio is rather excited about the project and creates the following change. + +``` +$ darcs log -v --last 1 +patch b769c1ae2bc57d0b8254deff9bb83c9c1000b93e +Author: xanderio@example.com +Date: Sun Jul 1 19:50:24 CEST 2018 + * change message + hunk ./Main.hs 1 + -main = putStrLn "This is a test!" + +main = putStrLn "This is the best test!" +``` + +Sandra has seen better things and thinks that the message should be a bit more +modest, so she is creating a change that looks like this. + +``` +$ darcs log -v --last 1 +patch 1891536411e86f9666219cc1a95f89587da08de3 +Author: sandra@example.com +Date: Sun Jul 1 19:52:12 CEST 2018 + * change message + hunk ./Main.hs 1 + -main = putStrLn "This is a test!" + +main = putStrLn "This is a quite okay test!" +``` + +Obviously both have changed the same line of the project so when I pull in those +changes `darcs` won't just decide on its own but rather ask me to do the +conflict resolution. That's a good thing, you don't want some random program +making decisions regarding your project, who knows what it might come up with! + +Before we are going to pull in our changes let's check the status of our working +tree. It'll become clear why I'm doing this, for now just roll along. + +``` +$ darcs status +No changes! +``` + +Okay, there are no unrecorded changes present so let's pull in xanderio's and +Sandra's changes. I can give `pull` multiple repositories to `pull` from. This +makes it quite convenient if you want to pull in changes from your entire team +all that once. + +``` +$ ls +Main.hs _darcs +$ darcs pull \ + https://hub.darcs.net/xanderio/project \ + https://hub.darcs.net/sandra/project +patch b769c1ae2bc57d0b8254deff9bb83c9c1000b93e +Author: xanderio@example.com +Date: Sun Jul 1 19:50:24 CEST 2018 + * change message +Shall I pull this patch? (1/2) [ynW...], or ? for more options: y +patch 1891536411e86f9666219cc1a95f89587da08de3 +Author: sandra@example.com +Date: Sun Jul 1 19:52:12 CEST 2018 + * change message +Shall I pull this patch? (2/2) [ynW...], or ? for more options: y +Do you want to Pull these patches? [Yglqk...], or ? for more options: y +Backing up ./Main.hs(.~0~) +We have conflicts in the following files: +./Main.hs + +Finished pulling. +$ ls +Main.hs Main.hs.~0~ _darcs +``` + +As we anticipated, we ended up with a conflict in `Main.hs`. Also +another mysterious file by the name of `Main.hs.~0~` appeared in our working +tree, we will take a look at that one later. First, let's take a look at what +that our repository looks like. + +``` +$ darcs log -s +patch 1891536411e86f9666219cc1a95f89587da08de3 +Author: sandra@example.com +Date: Sun Jul 1 19:52:12 CEST 2018 + * change message + + M! ./Main.hs -1 +1 + +patch b769c1ae2bc57d0b8254deff9bb83c9c1000b93e +Author: xanderio@example.com +Date: Sun Jul 1 19:50:24 CEST 2018 + * change message + + M ./Main.hs -1 +1 + +patch 7561a52b319ae52ddd1bd321d53cc01fb14fa94c +Author: raichoo@example.com +Date: Sun Jul 1 19:32:26 CEST 2018 + * initial record + + A ./Main.hs +``` + +In the summary of Sandra's patch we can see an exclamation point. This tells us +that there are changes in our repository that conflict with the changes that +patch introduces. To see what line actually causes that problem let's take a +look at the verbose output of `log`. + +``` +$ darcs log -v +patch 1891536411e86f9666219cc1a95f89587da08de3 +Author: sandra@example.com +Date: Sun Jul 1 19:52:12 CEST 2018 + * change message + conflictor [ + hunk ./Main.hs 1 + -main = putStrLn "This is a test!" + +main = putStrLn "This is the best test!" + ] + |: + hunk ./Main.hs 1 + -main = putStrLn "This is a test!" + +main = putStrLn "This is a quite okay test!" + +patch b769c1ae2bc57d0b8254deff9bb83c9c1000b93e +Author: xanderio@example.com +Date: Sun Jul 1 19:50:24 CEST 2018 + * change message + hunk ./Main.hs 1 + -main = putStrLn "This is a test!" + +main = putStrLn "This is the best test!" + +patch 7561a52b319ae52ddd1bd321d53cc01fb14fa94c +Author: raichoo@example.com +Date: Sun Jul 1 19:32:26 CEST 2018 + * initial record + addfile ./Main.hs + hunk ./Main.hs 1 + +main = putStrLn "This is a test!" +``` + +Here we can see that the conflict is marked with a **conflictor** which tells us +which changes are in conflict with one another. The line that xanderio's patch +changed is in direct conflict with Sandra's change and therefore that line is +marked with a conflictor. But what happened to your `Main.hs`? + +Conflict Markers +---------------- + +When a conflict occurs `darcs` will mark these conflicts in our working tree. +Remember that is checked for unrecorded changed in the working tree before +pulling in the changes? Let's check again. + +``` +$ darcs status +M ./Main.hs +6 +``` + +Interesting, `darcs` seems to have changed something in our `Main.hs`. If we +take a look at the file it's now going to look like this. + +``` +$ cat Main.hs +v v v v v v v +main = putStrLn "This is a test!" +============= +main = putStrLn "This is a quite okay test!" +************* +main = putStrLn "This is the best test!" +^ ^ ^ ^ ^ ^ ^ +``` + +These are so called **conflict markers**. These markers consist out of multiple +parts and there are a different delimiters separating those parts. + +* `v v v v v v v` + + Marks the beginning of a conflict, it is followed by the initial state of our + file, which is its state before the conflict occurred. + +* `=============` + + Marks the end of the initial state, it is followed by a list of conflicting + changes. + +* `*************` + + This marker separates conflicting changes. Depending on how many changes we + have pulled in that conflict with one other there can be multiple changes + listed here. Each of them is separated by a marker like this. In our + example we just have those two conflicting changes but if we happen to `pull` + in from more repositories there might potentially be more. + +* `^ ^ ^ ^ ^ ^ ^` + + Marks the end of a conflict. + +`darcs` also created a file called `Main.hs.~0~` the captures the state of our +conflicting file before the we pulled in the changes. + +``` +$ cat Main.hs.~0~ +main = putStrLn "This is a test!" +``` + +You can get rid of the conflict markers be simply issuing `darcs revert`, +this does not solve your conflict but it takes you back to the state if the file +before the conflicting changes were applied. In our situation our `Main.hs` +would look like this. + +``` +$ darcs revert -a +Finished reverting. +$ cat Main.hs +main = putStrLn "This is a test!" +``` + +To get our conflict markers back we can always issue `mark-conflicts`. + +``` +$ darcs mark-conflicts +Marking conflicts in: "Main.hs". +Finished marking conflicts. +$ cat Main.hs +v v v v v v v +main = putStrLn "This is a test!" +============= +main = putStrLn "This is a quite okay test!" +************* +main = putStrLn "This is the best test!" +^ ^ ^ ^ ^ ^ ^ +``` + +Solving the issue at hand +------------------------- + +Okay, now we know what the problem is but what's the solution? It's actually +pretty simple. We just record a patch that resolves our conflict. The situation +above calls a change that somewhat takes the two conflicting patches into +account to resolve the issue. + +``` +$ echo 'main = putStrLn "This is a good test, Bront!"' > Main.hs +$ darcs record -m 'resolve "change message" conflict' +hunk ./Main.hs 1 +-main = putStrLn "This is a test!" ++main = putStrLn "This is a good test, Bront!" +Shall I record this change? (1/1) [ynW...], or ? for more options: y +Do you want to Record these changes? [Yglqk...], or ? for more options: y +Finished recording patch 'resolve "change message" conflict' +``` + +Never skip a beat, `--skip-conflicts`! +-------------------------------------- + +As you can see, conflicts can cause quite a lot of work, but when we pull in +work from others not every patch contained in the remote repository might cause +a conflict. So how about just pulling in those that don't cause any trouble for +now and continue working with those before tackling the task of resolving any +issues? Sounds nice and `darcs pull` offers a flag that does exactly that, +`--skip-conflicts`. + +Let's pretend that we didn't `pull` in any changes yet and now we are carefully +pulling them in from our other example repositories. + +``` shell +$ darcs pull https://hub.darcs.net/xanderio/project +patch b769c1ae2bc57d0b8254deff9bb83c9c1000b93e +Author: xanderio@example.com +Date: Sun Jul 1 19:50:24 CEST 2018 + * change message +Shall I pull this patch? (1/1) [ynW...], or ? for more options: y +Do you want to Pull these patches? [Yglqk...], or ? for more options: y +Finished pulling. +$ darcs pull --skip-conflicts https://hub.darcs.net/sandra/project +Skipping some patches which would cause conflicts. +No remote patches to pull in! +$ darcs log +patch b769c1ae2bc57d0b8254deff9bb83c9c1000b93e +Author: xanderio@example.com +Date: Sun Jul 1 19:50:24 CEST 2018 + * change message + +patch 7561a52b319ae52ddd1bd321d53cc01fb14fa94c +Author: raichoo@example.com +Date: Sun Jul 1 19:32:26 CEST 2018 + * initial record +``` + +As you can see we didn't pull in Sandra's patch that would have conflicted +with xanderio's. On the other hand if Sandra would have had other changes that +would not conflict we would have pulled them in only leaving out the culprit. +This is one of the nice and powerful properties of **patch based** version +control systems like `darcs`.