~jan0sch/darcs-book

Showing details for patch 602eb6cc14fd11ab0c10d1921860b648eaf2b974.
2018-06-27 (Wed), 1:45 PM - - 602eb6cc14fd11ab0c10d1921860b648eaf2b974

add chapter 3

Summary of changes
1 files added
  • en/03-working-locally.md
diff -rN -u old-darcs-book/en/03-working-locally.md new-darcs-book/en/03-working-locally.md
--- old-darcs-book/en/03-working-locally.md	1970-01-01 00:00:00.000000000 +0000
+++ new-darcs-book/en/03-working-locally.md	2024-11-24 08:12:37.949800880 +0000
@@ -0,0 +1,405 @@
+Working locally
+===============
+
+Time for some action! Until this point we didn't really use `darcs` for
+anything, but now we are familiar with its core concepts and we can have some
+fun. In this chapter we will explore how to work locally with `darcs`. We will
+create our own patches, review them and look at some workflows.
+
+Creating our first repository
+-----------------------------
+
+Every new project starts somewhere and if you are using version control it
+usually starts with initializing a repository for our patches to live in. So
+let's jump right into the terminal and get going!
+
+We want to create a new project and call it `my-awesome-project`, no need to be
+humble here, we are ambitious! A new repository is initialized using the `init`
+command.
+
+```
+$ darcs init my-awesome-project
+Repository initialized.
+```
+
+That's it! `darcs` tells us that the repository has been initialized. It
+automatically created a new folder `my-awesome-project` and inside of that
+folder we will find a folder called `_darcs`, this is where `darcs` keeps all
+its information regarding the repository. Whenever we are issuing a `darcs`
+command `darcs` will try to find this folder somewhere in our directory
+hierarchy. For the rest of this chapter I will assume that we are inside of the
+`my-awesome-project` folder.
+
+Ch-Ch-Ch Changes!
+-----------------
+
+Okay, we now have a repository. Let's find what patches it holds. We can do
+this by issuing `darcs log`.
+
+```
+$ darcs log
+```
+
+Huh, `darcs` returns without reporting any patches. That's not very surprising
+since we have not recorded any yet.
+
+To warm up let's just create a simple "Hello World" program written in
+Haskell and add that change to our repository inside our newly created project
+folder.
+
+```
+$ echo 'main = putStrLn "Hello World!"' > Main.hs
+```
+
+This creates a new file `Main.hs` with the content `main = putStrLn "Hello
+World"`, of course you can also use your favorite text editor to do this. By
+doing this we have changed our **working directory**.
+
+To find out what changes we have done to the working directory we can issue
+`darcs status`.
+
+```
+$ darcs status
+a ./Main.hs
+```
+
+What `darcs` does here is that it compares the state of your working directory
+against the state of the repository (recall that the state of the respository is
+a set of changes). In our current repository there are no recorded changes so
+adding something to our working directory surely should constitute a change
+shouldn't it?
+
+Let's take a closer look at the output of `darcs status`. What does the lower
+case `a` in front of `./Main.hs` mean? Well, it means that the file `Main.hs` is
+currently **unadded**. Let's try to `record` a patch and see what happens.
+
+When we want to `record` a new patch we can simply issue `darcs record` and
+`darcs` will compare our current working directory against the state of our
+repository and consider all changes for the patch we are about to `record`.
+
+```
+$ darcs record
+No changes!
+```
+
+What? But we just created a new file? How isn't that a change? Well, `darcs`
+only looks at changes to **added** files, remember that `darcs status` reported
+`Main.hs` as **unadded**, so we need to inform it that we are interested in
+`Main.hs`. We do this by issuing `darcs add Main.hs`.
+
+```
+$ darcs add Main.hs
+Adding 'Main.hs'
+$ darcs status
+A ./Main.hs
+```
+
+Look at that! The lower case `a` changed to an upper case `A`, `darcs` is
+keeping track of changes to our `Main.hs` and we can now record our first
+change.
+
+```
+$ darcs record -m 'add Main.hs'
+Each patch is attributed to its author, usually by email address (for
+example, `Fred Bloggs <fred@example.net>').  Darcs could not determine
+your email address, so you will be prompted for it.
+
+Your address will be stored in /home/raichoo/.darcs
+It will be used for all patches you record in ALL repositories.
+If you move that file to _darcs/prefs/author, it will
+be used for patches recorded in this repository only.
+What is your email address? raichoo@example.com
+addfile ./Main.hs
+Shall I record this change? (1/2)  [ynW...], or ? for more options: y
+hunk ./Main.hs 1
++main = putStrLn "Hello World!"
+Shall I record this change? (2/2)  [ynW...], or ? for more options: y
+Do you want to Record these changes? [Yglqk...], or ? for more options: y
+Finished recording patch 'add Main.hs'
+```
+
+A lot of things happened here, so let's break it down.
+
+So what's with the `-m 'add Main.hs'`? That's actually the name we are giving
+this patch. We can later use it to refer to it it's also a small summary of what
+this patch is supposed to do. If you don't specify a name `darcs` will open your
+editor (which is specified by the `$EDITOR` environment variable) and you can
+provide the name there. Apart from only giving the patch a name you can also
+give some more detail about your new patch.
+
+The first thing that `darcs` does is asking us for our email, this makes sense
+because every patch needs an author. Once we tell `darcs` who we are it stores
+our email address in `~/.darcs` and won't bother us again.
+
+Now `darcs` asks us about the actual changes that we want to `record` for this
+patch. The first one is that we simply want to add the `Main.hs` file the we
+created. The type of this change is `addfile`. The second change it asks us
+about adds the content to the file, this change type is what we call a `hunk`.
+This `hunk` just adds our single line program to the file.
+
+`darcs log` will now show us our first recorded patch!
+
+```
+$ darcs log
+patch 2e484ff04a52871b0f2ee643a31c155b24eb1898
+Author: raichoo@example.com
+Date:   Tue Jun 26 22:54:24 CEST 2018
+  * add Main.hs
+```
+
+Here you can see the name we have given to the patch namely 'add Main.hs' as
+well as a hash `2e484ff04a52871b0f2ee643a31c155b24eb1898`. Both can be used to
+identify the patch for later use.
+
+To get a more detailed output we can issue `darcs log -v` and we can see the
+changes recorded in this patch.
+
+```
+Author: raichoo@exmaple.com
+Date:   Tue Jun 26 22:54:24 CEST 2018
+  * add Main.hs
+    addfile ./Main.hs
+    hunk ./Main.hs 1
+    +main = putStrLn "Hello World!"
+```
+Removing a file
+---------------
+
+At some point we might want to get rid of a file in our repository. You can
+simply delete the file and record a new change. Don't worry, your file is still
+contained in the history if you recorded it earlier, so you can always get it
+back.
+
+```
+$ rm Main.hs
+$ darcs status
+R ./Main.hs
+$ darcs record -m 'remove Main.hs'
+```
+
+`darcs status` indicates that we have removed by displaying an upper case `R` in
+its output.
+
+I like to `move` it!
+--------------------
+
+For some reason we have decided that we do not like the name `Main.hs` for our
+file, `Hello.hs` is much more fitting. With `darcs move` we create a **move**
+change. Let's take a look.
+
+```
+$ darcs move Main.hs Hello.hs
+Moved: Main.hs to: Hello.hs
+$ darcs status
+./Main.hs -> ./Hello.hs
+$ darcs record -m 'rename Main.hs'
+move ./Main.hs ./Hello.hs
+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 'rename Main.hs'
+$ darcs log -v
+patch 785647f796cad98bcb63d2c30c8e88223600059b
+Author: raichoo@exmaple.com
+Date:   Tue Jun 26 23:23:00 CEST 2018
+  * rename Main.hs
+    move ./Main.hs ./Hello.hs
+
+patch 2e484ff04a52871b0f2ee643a31c155b24eb1898
+Author: raichoo@exmaple.com
+Date:   Tue Jun 26 22:54:24 CEST 2018
+  * add Main.hs
+    addfile ./Main.hs
+    hunk ./Main.hs 1
+    +main = putStrLn "Hello World!"
+```
+
+As you can see, we now have two patches in our repository.
+
+What's new pussy cat?
+---------------------
+
+Since we currently only added and moved files it's time for things to get a
+little more interesting. We are going to make some actual changes to our code.
+So let's break out our text editor and change our `"Hello World!"` into `"Hello
+Everyone!"`. I'll use `sed` to change the program, but you can use whatever you
+want.
+
+```
+$ sed -i '' 's/World/Everyone/' Hello.hs
+$ darcs status
+M ./Hello.hs -1 +1
+```
+
+As you can see, `darcs` has detected a change. In particular it has detected
+that the file `Hello.hs` has been modified which is indicated by the upper case
+`M`. Furthermore it reports some more information about the modification. The
+`-1` means that we have deleted a line while the `+1` means that we have edited
+a line. To look at the actual change we can use `darcs whatsnew`.
+
+```
+$ darcs whatsnew
+hunk ./Hello.hs 1
+-main = putStrLn "Hello World!"
++main = putStrLn "Hello Everyone!"
+```
+
+So `darcs` has swapped out the entire line just because we have changed a single
+word as indicated by the `hunk` change. If we wanted to we can record a new
+patch based on this patch but let's look at another way to do something like
+this.
+
+Seek and replace
+----------------
+
+Let's pretend that we didn't to the last change where we replaced "World" with
+"Everyone". `darcs replace` offers a different way to make this change without
+deleting the old line and inserting a new one.
+
+```
+$ darcs replace World Everyone Hello.hs
+M ./Hello.hs r1
+$ darcs whatsnew
+replace ./Hello.hs [A-Za-z_0-9] World Everyone
+```
+
+Changes like this allow you to be a little more specific about what your
+intentions are. `replace` is often used when renaming functions or variables.
+
+Booooooooooring!!!
+------------------
+
+Remember that **unadded** files are displayed with a lower case `a` in the `darcs
+status` output? This can be a bit annoying because there might be some files in
+our working directory that we would never consider for a patch. For files like
+this we have a list of files that we consider **boring**.
+
+Here's an example. We now have our `Hello.hs` file in our working directory and
+we want to compile that program. When we take a look at the our `status` we get
+a surprise.
+
+```
+$ darcs status
+a ./Hello
+```
+
+Hm, so now `Hello` is considered **unadded** but we never want to add it to the
+repository anyway. This situation might not be so bad but image you have a bunch
+of these files. Your `status` output will soon become cluttered with files you
+actually want to ignore. To help is with this `darcs` maintains a **boring**
+file under `_darcs/prefs/boring`. This file contains a list of regular
+expressions to filter out files we are not interested in for version control. We
+can simply add our `Hello` file to it and won't be bothered with it anymore.
+
+```
+$ darcs status
+a ./Hello
+$ echo Hello >> _darcs/prefs/boring
+$ darcs status
+No changes!
+```
+
+
+The boring file is a plain text file so you can simply edit it with your
+favorite text editor.
+
+Revisiting history
+------------------
+
+We briefly looked at `darcs log` to take a look at our recorded patches. One of
+the useful utilities of `log` is the `-v` flag that displays the changes that a
+certain patch represents. That might be a little to much sometimes, think about
+adding a large new text file to your repository. You almost certainly don't want
+to see that entire file in you `log` output. The `-s` flag allows you just to
+look at a summary of changes, similar to the `darcs status` output.
+
+```
+$ darcs log -s
+patch 0dd46bd7a710d66136d7293b667984bdaffb1509
+Author: raichoo@example.com
+Date:   Mon Jun 18 12:31:32 CEST 2018
+  * display move
+
+    M ./__fish_darcs_prompt.fish +6
+
+patch d3cc32993f6ff5e6b69fd6e1ac5e4e5d9b2f83ec
+Author: raichoo@example.com
+Date:   Mon Jun 11 19:16:21 CEST 2018
+  * initial record
+
+    A ./__fish_darcs_prompt.fish
+```
+
+Another quite useful flag is `--last` which takes a number `n` and displays the
+last `n` changes. This is useful if you just want to look at the most recent
+changes.
+
+```
+$ darcs log --last 3
+patch eec36aaa61a4fad924657cd86624ba162991860d
+Author: raichoo@example.com
+Date:   Mon Jun 18 12:32:34 CEST 2018
+  * fish: add move color to darcs prompt
+
+patch 745297151266fb6d76634d647084ad37a7b3bb1c
+Author: raichoo@example.com
+Date:   Thu Jun 14 20:43:08 CEST 2018
+  * fish: clean up fish config
+
+patch e791ff48013903112ea42071e27b4e9ab7b86327
+Author: raichoo@example.com
+Date:   Mon Jun 11 19:40:43 CEST 2018
+  * move darcs prompt into plugin
+
+```
+
+Sometimes you just want to look at certain patches here is where the name we
+provide whenever we are recording a new patch comes in handy. `log` takes a `-p`
+that allows us to specify a regular expression and `darcs log` will pick out
+only the patches where the regular expression matches the name.
+
+I'm managing my system configuration files with `darcs`. Let's say I want to
+have a summary of the patches that deal with the program `dunst` (`dunst` is the
+notification daemon I'm using to display messages on my desktop).
+
+This is how I would do it.
+
+```
+$ darcs log -p dunst -s
+patch 81fac56462c274f8a507f9e5497c22e8d418cae9
+Author: raichoo <raichoo@example.com>
+Date:   Tue Apr 17 17:48:15 CEST 2018
+  * key shortcut to close dunst notifications
+
+    M ./dunst/dunstrc -2 +2
+
+patch 0743c619f5cf0d67fc9d36de96f83752c3c56b12
+Author: raichoo <raichoo@example.com>
+Date:   Fri Mar 30 18:28:54 CEST 2018
+  * add dunst config
+
+    A ./dunst/
+    A ./dunst/dunstrc
+```
+
+The patch with the hash `81fac56462c274f8a507f9e5497c22e8d418cae9` looks
+interesting and I want to dril down further. I can use the `-h' flag to specify
+a patch hash. I don't need to specify the entire hash but only a unique prefix.
+`darcs log` will display the first patch where the hash matches the given
+prefix.
+
+```
+$ darcs log -v -h 81fac
+patch 81fac56462c274f8a507f9e5497c22e8d418cae9
+Author: raichoo <raichoo@example.com>
+Date:   Tue Apr 17 17:48:15 CEST 2018
+  * key shortcut to close dunst notifications
+    hunk ./dunst/dunstrc 231
+    -    close = ctrl+space
+    +    close = mod4+space
+    hunk ./dunst/dunstrc 234
+    -    close_all = ctrl+shift+space
+    +    close_all = mod4+shift+space
+```
+
+`darcs log` is very powerful and I encourage you to look at `darcs help log` and
+the `darcs` manpage.