~jan0sch/darcs-book

Showing details for patch 0b942e025ca4fe8b06a8e7310b24f78576880b03.
2018-07-02 (Mon), 3:49 PM - - 0b942e025ca4fe8b06a8e7310b24f78576880b03

add chapter 6

Summary of changes
1 files added
  • en/06-conflict-management.md
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`.