~jan0sch/darcs-book

Showing details for patch 6d8f39d0fd8914a33203c18d9426cfce66e133c6.
2018-06-29 (Fri), 3:20 PM - - 6d8f39d0fd8914a33203c18d9426cfce66e133c6

add chapter 5

Summary of changes
1 files added
  • en/05-a-little-help-from-my-friends.md
diff -rN -u old-darcs-book/en/05-a-little-help-from-my-friends.md new-darcs-book/en/05-a-little-help-from-my-friends.md
--- old-darcs-book/en/05-a-little-help-from-my-friends.md	1970-01-01 00:00:00.000000000 +0000
+++ new-darcs-book/en/05-a-little-help-from-my-friends.md	2024-11-24 04:54:24.884670040 +0000
@@ -0,0 +1,283 @@
+A little help from my friends
+=============================
+
+In chapter 1 we have learned about `darcs` being a **distributed** version
+control system, but until now we basically just worked with one local instance
+of our project. No other parties were involved. But whenever we are working on
+something big it's a good thing when people participate. In this chapter I am
+going to introduce you how to work together with others.
+
+Cloning
+-------
+
+Until now we only used repositories that were freshly created by ourselves. But
+sometimes we want to start participating on a project that has already started,
+so initializing something new is not what we want. This is where cloning comes
+in. With cloning we can take a repository and make our own copy from it.
+
+Let's say you want to `clone` the source of this book, which is hosted on [darcs
+hub](https://hub.darcs.net/raichoo/darcs-book). To `clone` this repository you
+simply issue `darcs `clone` https://hub.darcs.net/raichoo/darcs-book` and
+`darcs` will start copying the repository into a directory called `darcs-book`..
+
+```
+$ darcs clone https://hub.darcs.net/raichoo/darcs-book
+Copying patches, to get lazy repository hit ctrl-C...
+Finished cloning.
+```
+
+Huh, that's an interesting messageā€¦ I can hit `CTRL-C` to get a lazy repository.
+What does that mean? Well, quite simple. Repositories can get **REALLY** big and
+therefore it takes a lot of time to `clone` them, but what if you only wanted
+the newest changes and pull in everything else on demand? No need to pull in the
+entire history of a project all at once. A lazy repository does just that, and
+this reduces cloning time drastically. Cloning the entire history is only useful
+if you might not be able to access the internet for some time and you really
+need to have access to the entire evolution of the project. So if you happen to
+get stuck on a particularly long `clone`, just hit `CTRL-C` and you are good to
+go, most of the time you will be interested in the current state of the
+repository anyways. Of course you can instruct `darcs` to do a lazy clone right
+away by add the `--lazy` flag.
+
+```
+$ darcs clone --lazy https://hub.darcs.net/raichoo/darcs-book
+Finished cloning.
+```
+
+It's a simple as that.
+
+Using `clone` locally.
+----------------------
+
+`clone` is useful for more than just copying data from a remote location.
+Sometime you might just want to have another copy of your project to record a
+entirely different set of patches in. This becomes especially interesting once
+we are able to modify the history of our project, but more on that in a later
+chapter.
+
+In the section before we saw that the `clone` command takes a location from
+where you want to `clone`. This does not have to be a remote server, it can also
+be a directory. So let's say I decided to work on the second edition of this
+book and I wanted to do that inside of a separate repository and pull patches
+from there in the future.
+
+```
+$ ls
+darcs-book
+$ darcs clone darcs-book darcs-book-2nd-edition
+Copying patches, to get lazy repository hit ctrl-C...
+Finished cloning.
+$ ls
+darcs-book darcs-book-2nd-edition
+```
+
+So, `clone` can take 2 arguments, one being the source repository and another
+one being the destination directory. So a source does not necessarily need to be
+a remote location, it can be a directory as well.
+
+Pu-Push it real good!
+---------------------
+
+Great, now we can have multiple copies of a repository and they can either be
+remote or local. We are slowly stepping up our game! Now, let's start to
+exchange patches between those different copies. For this purpose `darcs` offers
+the `push` and `pull` commands. We are going to take a look at `push` first. To
+do this in a somewhat realistic example let's setup simple scenario first. I'm
+going to do this locally but all of the upcoming examples also work with remote
+sources.
+
+```
+$ darcs init new-project
+$ darcs clone new-project new-project-work
+Copying patches, to get lazy repository hit ctrl-C...
+Finished cloning.
+$ cd new-project-work
+$ touch some-file.txt
+$ darcs add some-file.txt
+Adding 'some-file.txt'
+$ darcs record -a -m 'added some file'
+Finished recording patch 'added some file'
+$ darcs log
+patch cfaa89a2b431c0642687d9bfa0bbb721015cc775
+Author: raichoo@example.com
+Date:   Fri Jun 29 13:02:03 CEST 2018
+  * added some file
+```
+
+Here we have a repository called `new-project` and a copy of it which we call
+`new-project-work`, here we are going to do some actual work and once we are
+done we are going to push that to our project repository for publishing or
+whatever we choose to do with it.
+
+In out `new-project-work` repository we have recorded a patch that is not
+present in our `new-project` repository which we consider as our main
+repository, everything in here is meant to be published to a larger audience. At
+some point we have decided that our new patch is ready to go and we want to
+publish it to the main repository.
+
+Currently we are in the working tree of our `new-project-work` repository and we
+want to push to the `new-project` repository, this is how we would do that.
+
+```
+$ darcs push ../new-project
+Pushing to "/tmp/darcs/new-project"...
+patch cfaa89a2b431c0642687d9bfa0bbb721015cc775
+Author: raichoo@example.com
+Date:   Fri Jun 29 13:02:03 CEST 2018
+  * added some file
+Shall I push this patch? (1/1)  [ynW...], or ? for more options: y
+Do you want to Push these patches? [Yglqk...], or ? for more options: y
+Finished applying.
+Push successful.
+```
+
+`darcs` first figures out which patches are not present in the destination
+repository and prompts us for each one of them if we really want to push that
+patch. Once we are done it asks us if we really want to push these patches and
+after confirming all our selected patches are being transfered to the
+destination repository.
+
+Let's take a quick look at the patches that are now inside our `new-project`
+repository, remember that we have just created it and there were now patches in
+there to begin with.
+
+```
+$ cd ../new-project
+$ darcs log
+patch cfaa89a2b431c0642687d9bfa0bbb721015cc775
+Author: raichoo@example.com
+Date:   Fri Jun 29 13:02:03 CEST 2018
+  * added some file
+```
+
+Nice, as you can see our patch has been transfered from `new-project-work` to
+the `new-project` repository. If you take a look at the working tree you will
+also find that all the changes contained in our transfered patches have been
+applied. Piece of cake!
+
+Keep in mind that the destination does not need to be just another folder on our
+own computer, it can as well be a remote destination.
+
+Pulling
+-------
+
+But what if the patches we are interested in are on a remote machine to which we
+cannot simple log in and issue a `push`. Well, for that we have `pull`. Let's
+pretend that we didn't push the patch to `new-project` like we just did. This
+time we are going to `pull` it in from `new-project-work` to `new-project`
+rather then the other way around. So now we are in the working tree of
+`new-project`.
+
+```
+$ darcs pull ../new-project-work
+HINT: if you want to change the default remote repository to
+      /tmp/darcs/new-project-work,
+      quit now and issue the same command with the --set-default flag.
+patch cfaa89a2b431c0642687d9bfa0bbb721015cc775
+Author: raichoo@example.com
+Date:   Fri Jun 29 13:02:03 CEST 2018
+  * added some file
+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 log
+patch cfaa89a2b431c0642687d9bfa0bbb721015cc775
+Author: raichoo@example.com
+Date:   Fri Jun 29 13:02:03 CEST 2018
+  * added some file
+```
+
+So now rather than pushing to another location we can `pull` our patches in
+from, let's say a website like [darcshub](https://hub.darcs.net).
+
+Wait a minute though, there is something in the output that we didn't talk about
+yet. `darcs` emits a `HINT` message which tells us something about a **default
+remote repository**. What does that mean? A default remote repository allows is
+to omit the destination when pushing and pulling. To check if you have one set
+you can issue `darcs show repo`.
+
+```
+$ darcs show repo
+         Format: hashed, darcs-2
+           Root: /tmp/darcs/new-project
+   PristineType: HashedPristine
+          Cache: thisrepo:/tmp/darcs/new-project, cache:/home/raichoo/.cache/darcs
+     PatchIndex: enabled, but not yet created
+    Num Patches: 1
+      Weak Hash: cfaa89a2b431c0642687d9bfa0bbb721015cc775
+```
+
+This gives us some information about our repository, but I can't spot a default
+repository here. Let's use the `--set-default` flag just like `darcs` told us to
+in the hint.
+
+```
+$ darcs pull --set-default ../new-project-work
+No remote patches to pull in!
+darcs show repo
+         Format: hashed, darcs-2
+           Root: /tmp/darcs/new-project
+   PristineType: HashedPristine
+          Cache: thisrepo:/tmp/darcs/new-project, cache:/home/raichoo/.cache/darcs
+     PatchIndex: enabled, but not yet created
+ Default Remote: /tmp/darcs/new-project-work
+    Num Patches: 1
+      Weak Hash: cfaa89a2b431c0642687d9bfa0bbb721015cc775
+```
+
+Here we go! Now we do not have to explicitly state the remote repository we are
+working with when we just want to talk to the default remote repository.
+
+```
+$ darcs pull
+Pulling from "/tmp/darcs/new-project-work"...
+No remote patches to pull in!
+$ darcs push
+Pushing to "/tmp/darcs/new-project-work"...
+No recorded local patches to push!
+```
+
+Of course we can still explicitly specify other repositories if we want to
+communicate with a different repository, we can also always set a different
+default remote repository just by using the `--set-default` flag on a `push` or
+`pull`. This saves us from memorizing all the remote repositories we are working
+with and thus makes life a little easier for us.
+
+Annotate
+--------
+
+Once you start working with multiple people it becomes useful to know who had
+recorded what patches and how that affected a current file. Imagine you are
+working on an important and someone has written a patch you don't fully
+understand, maybe it's not a sufficiently documented change or you are just
+having a bad day and need the person who wrote that to help you understand
+what is going on.
+
+Here we have a simple file but it presents us with an issue, who wrote which
+line? Thankfully `annotate` can be of assistance here.
+
+```
+$ cat text.txt
+I wrote this!
+I wrote this!
+1: patch abcb03dd0b39a08c6424700eac117f72fb465ea5
+Author: raichoo@example.com
+Date:   Fri Jun 29 14:09:20 CEST 2018
+  * adding important information
+2: patch 3f8ee5063a2697aeec8856246f7069ae8c9aafa5
+Author: tauli@example.com
+Date:   Fri Jun 29 14:09:57 CEST 2018
+  * some more information
+
+1:  raichoo@example.com   #1 | I wrote this!
+2:    tauli@example.com   #2 | I wrote this!
+```
+
+The contents of the file does not help us a lot when we want to figure out who
+contributed which line to the file. But `annotate` presents us with a list of
+involved changes and who recorded them. This can be immensely useful when trying
+to find bugs or just figure out the right person to talk to about a particular
+piece of code. Quite a lot of power you got there, remember to use it
+responsibly. Fun fact: other version control systems tend to call this command
+`blame`, you can guess what some people are primarily using it for. Don't be
+that person.