~jan0sch/darcs-book
Showing details for patch 602eb6cc14fd11ab0c10d1921860b648eaf2b974.
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.