~jan0sch/darcs-book
Showing details for patch 46a3917ad44cfc783ebdf701b5aab70e42764209.
diff -rN -u old-darcs-book/en/07-rewriting-history.md new-darcs-book/en/07-rewriting-history.md --- old-darcs-book/en/07-rewriting-history.md 2024-11-23 21:06:57.301599299 +0000 +++ new-darcs-book/en/07-rewriting-history.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,549 +0,0 @@ -Rewriting History -================= - -Before we start talking about rewriting our repository history, we should take a -step back and take a look at how `darcs` looks at our patches again. Whenever we -take a look at our changes with `darcs log` everything is presented to us in a -linear fashion, but that's not the only way we can think of organizing our -patches. We now have heard numerous times that a "repository's state is defined -by a set a changes". We have also heard what it means when to patches `A` and -`B` commute, namely that it does not matter in which order we apply them. Until -now we didn't really exploit these properties of `darcs` that much. So let's -talk a little bit about dependencies so we can get the most out of recording and -crafting our patches. - -Dependencies in `darcs` ------------------------ - -To illustrate how patches can depend on each other in `darcs` let's create a -very simple repository with two files called `A` and `B`. First we are going to -`add` these two files and then we are going to change their contents. - -``` -$ touch A B -$ darcs add A -Adding 'A' -$ darcs record -m 'add A' -a -Finished recording patch 'add A' -$ darcs add B -Adding 'B' -$ darcs record -m 'add B' -a -Finished recording patch 'add B' -$ echo A >> A -$ darcs record -m 'change A' -a A -Recording changes in: "A" -Finished recording patch 'change A' -$ echo B >> B -$ darcs record -m 'change B' -a B -Recording changes in: "B" -Finished recording patch 'change B' -patch 376b1bc0febb10802797a5afe7d55e35e42ac89f -Author: raichoo@example.com -Date: Mon Jul 9 19:04:01 CEST 2018 - * change B - -patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b -Author: raichoo@example.com -Date: Mon Jul 9 19:02:49 CEST 2018 - * change A - -patch 0d87b94c8d03fea3a2b613c43032df8da8cbff93 -Author: raichoo@example.com -Date: Mon Jul 9 19:02:02 CEST 2018 - * add B - -patch 0b2f173ea79d311c34d8e321b6a8d86582d18ff4 -Author: raichoo@example.com -Date: Mon Jul 9 19:01:03 CEST 2018 - * add A -``` - -Nothing too surprising has happened here. We have added some files and then we -have changed them. Everything looks nice and linear. But let's take a look at -how these patches depend on each other. - -`darcs show dependencies` will give us some `graphviz` output that we can pipe -into the `dot` command to generate a visual representation of all the patch -dependencies in our repository. The command to do this looks like this. - -``` -darcs show dependencies | dot -Tpng -o dependencies-1.png -``` - -For our little example repository `darcs` and `dot` will generate a `png` file -that looks like this. - -![](../img/dependencies-1.png) - -Huh, now that looks radically different. Let's talk about what this output -actually means. We see that `change B` depends on `add B` and `change A` depends -on `add A`. That's not really surprising. You can only really change a file -after you have added it. Makes sense doesn't it. But how does `darcs` figure out -what patches depend on each other? It's quite simple. Remember when we talked -about **commuting patches**. To patches `A` and `B` commute if we can apply them -to our repository in any order and end up with the same result. Now that's -clearly not the case for our patches above. I can't change a file that isn't -there, therefore I have to `add` it before changing it. These to patches do not -commute, and this is what we call a **dependency**. You need to satisfy all the -dependencies of a patch before you can apply it. - -In our dependency graph you can also see that all our changes concerning the -files `A` and `B` are totally independent from each other. So I could pull only -the changes concerning `B` from the repository while ignoring the changes -regarding `A` altogether. This is an incredibly powerful mechanism that -**snapshot based** version control systems do not have. Now you can pull in a -set of patches and ignore all those that don't depend on the change you are -currently interested in. Other version control systems like `git` for example -call this **cherry picking**, but compared to `darcs` they are suffering from -some short comings. In those version control system you re-record the patch when -you **cherry pick** it. That means that its whole identity changes, one way in -which this manifests is that it will get a different hash. So even though it's -the exact same change the patches are now different. This can become quite -annoying when working in a distributed setting, with `darcs` this is a complete -non-issue. - -Let's play some more with this. We now want to change file `A` but let's pretend -that we are referencing something that is in file `B` (maybe a function, or a -paragraph). - -``` -$ echo use B >> A -$ darcs record -m 'use B' -a A -``` - -![](../img/dependencies-2.png) - -Darn, that's not really what we wanted. Now we have a change in file `A` that -depends on file `B` being present, but `darcs` has no understanding of the -semantics of a file's content. This is problematic because if someone decided to -pull in the `use B` patch without pulling in all our `B` patches the state of -our repository would not make sense. You can't use anything in `B` if it isn't -there, makes sense doesn't it? But fear not, we can instruct `record` to prompt -us for dependencies, so we can inform `darcs` about semantic relationships -between patches. So let's try again! - -``` -$ darcs record --ask-deps -m 'use B' -a A -Recording changes in: "A" -hunk ./A 2 -+use B -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 -patch 376b1bc0febb10802797a5afe7d55e35e42ac89f -Author: raichoo@example.com -Date: Mon Jul 9 19:04:01 CEST 2018 - * change B -Shall I depend on this patch? (1/2) [ynW...], or ? for more options: y -Will not ask whether to depend on 1 already decided patch. -Do you want to Depend on these patches? [Yglqk...], or ? for more options: y -Finished recording patch 'use B' -``` - -The `--ask-deps` flag instructs `darcs` to prompt us for dependencies and we -tell it that we want our new patch to depend on the patch `change B`. Now the -dependency graph looks like this. - -![](../img/dependencies-3.png) - -This gives us unprecedented control over our patches. We now can enrich them -with semantic information and our collaborators can leverage that information to -mix and match patches to their liking. Want to `pull` in one feature but not the -other one because it's still too experimental for you, or maybe clashes with -some feature you are working on? You can do that now, and all of that while -maintaining the identity of patches. This is one of the true powers of `darcs`. - -Amending patches ----------------- - -When you start using version control you will quickly encounter situations where -you have recorded a patch and realize that you have made a mistake. For example -you have recorded a patch with a typo or you have forgotten to state a -dependency in a patch. That's really super annoying. What you could do now is -`record` a new patch correcting that error but that would make our history more -and more confusing as time progresses and this kind patches start to accumulate. -This is where `darcs amend` comes in handy, it let's you change a patch the you -have already recorded without creating a new one. - -As an example we are going to pretend that we accidentally didn't state the -dependency of our `use B` patch in the above section correctly, so our -repository once again looks like this. - -![](../img/dependencies-2.png) - -So let's use `amend` to right that wrong. - -``` -$ darcs amend --ask-deps -p 'use B' -patch 610c31ea41237cd407464ff41720d04bce214ef2 -Author: raichoo@example.com -Date: Mon Jul 9 20:05:30 CEST 2018 - * use B -Shall I amend this patch? [yNjk...], or ? for more options: y -patch 376b1bc0febb10802797a5afe7d55e35e42ac89f -Author: raichoo@example.com -Date: Mon Jul 9 19:04:01 CEST 2018 - * change B -Shall I depend on this patch? (1/2) [ynW...], or ? for more options: y -Will not ask whether to depend on 1 already decided patch. -Do you want to Depend on these patches? [Yglqk...], or ? for more options: y -Finished amending patch: -patch 9890bbfa50839674d45c416395bdb7e3bcd0ac00 -Author: raichoo@example.com -Date: Mon Jul 9 20:07:22 CEST 2018 - * use B -``` - -We have used the `-p` flag to state a pattern for the patch we want to `amend` -and instructed `darcs` to prompt us for dependencies. We don't need to specify a -pattern but sometimes if we know exactly what patch we want to `amend` it can -certainly speed up the process. After selecting the patch we want to take care -of, `darcs` will prompt us for changes just like it would to when recording a -change. Our repository now looks like we want it to. - -![](../img/dependencies-3.png) - -`amend` works very much like `record` but rather than recording a new patch it -prompts you for an existing patch that you intend to improve first and then -proceeds just like we are used to when recording patches. We can add more -changes to our patch, change hunks, messages, author etcetera. Keep in mind that -you should not rewrite patches that have already been pushed to a public -repository since this action is **local only**, pushed patches will remain in -your remote repository even if you amend them locally. If you want to change the -state of a remote repository your best option is to `record` a new patch and -`push` it there. - -You also cannot `amend` patches that are a dependency of another patch. That -would be like pulling a rug away from under their feet. There are more powerful -tools that let you do even that, but that's something for a later chapter. - -Another example that is a bit more common deals with typos. Typos are probably -the most annoying thing when you deal with recording patches. They show up in -parts of your projects as well as patch names. Heck, they are pretty much -everywhere, just look at this patch gone horribly wrong. - -``` -$ darcs log -v -patch a7f5a2efe162787b3e7f6ceb215f53fa300f6590 -Author: raichoo@example.com -Date: Tue Jul 10 19:41:56 CEST 2018 - * initial rceord - addfile ./Main.hs - hunk ./Main.hs 1 - +main = "Hello Wrold!" -``` - -Oh boy, looks like we weren't quite awake yet when we recorded that patch. We -misspelled "World" as well as "record". That's quite embarrassing, surely we -don't want to `push` that! Thankfully we can still `amend` that patch before its -publication. - -``` -$ sed -i '' 's/Wrold/World/' Main.hs -$ darcs amend -m 'initial record' -patch a7f5a2efe162787b3e7f6ceb215f53fa300f6590 -Author: raichoo@example.com -Date: Tue Jul 10 19:41:56 CEST 2018 - * initial rceord -Shall I amend this patch? [yNjk...], or ? for more options: y -hunk ./Main.hs 1 --main = "Hello Wrold!" -+main = "Hello World!" -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 amending patch: -patch 1e00a2684025c2ee9e1cbbb809d71d8167482458 -Author: raichoo@example.com -Date: Tue Jul 10 19:45:57 CEST 2018 - * initial record -``` - -Patch quality is certainly an important thing to take care of, so be sure to -double check before you publish something important. - -Unrecording patches -------------------- - -Sometimes we want to get rid of patches without getting rid of the work we have -done. Maybe we want to fold a bunch of patches into one, or maybe we want to -organize our patches a little differently. Whatever the case, sometimes some -patches need to be removed from our local repository and `unrecord` is how we -can do that. - -Let's say we are currently working on a new feature in our project and our -history currently looks something like this. - -We started out with a Haskell program just printing out "Hello!" and then we got -the feature request asking us to add two more messages to the output. First we -added some code that additionally prints out "World!". At that point wanted to -capture our progress, so we decided to `record` a patch and call it `WIP`. Then -we proceeded to add the other message requested in the feature and record that -as well. - -``` -$ cat Main.hs -main = do - putStrLn "Hello!" - putStrLn "World!" - putStrLn "Everyone!" -$ darcs log -v -patch 4f43a522ae0162dcef8dab6aab0d354ede209767 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:56 CEST 2018 - * WIP - hunk ./Main.hs 4 - + putStrLn "Everyone!" - -patch b7cf79bc1e3454f7dfdee86a480e72f312b43a14 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:42 CEST 2018 - * WIP - hunk ./Main.hs 3 - + putStrLn "World!" - -patch faf56a95edb01004d10f3bd4b72ad8d2b5ad2044 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:10 CEST 2018 - * initial record - addfile ./Main.hs - hunk ./Main.hs 1 - +main = do - + putStrLn "Hello!" -``` - -That's not a very useful history and really not fit for publishing since it's -showing our work in progress rather than a finished patch. It certainly served -its purpose, but it really needs to be cleaned up before we show it to the rest -of the world. We have recorded the state of our working tree whenever we felt -confident and then moved onward to the next step. We want to squash the two -`WIP` patches into a single patch. The first thing we do is that we `unrecord` -them. Since we have named all our "work in progress" patches `WIP` we can -specify a pattern for `unrecord` using the `-p` flag so `darcs` will only ask us -if it should `unrecord` patches that have a name matching this pattern. - -``` -$ darcs unrecord -p WIP -patch 4f43a522ae0162dcef8dab6aab0d354ede209767 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:56 CEST 2018 - * WIP -Shall I unrecord this patch? (1/2) [ynW...], or ? for more options: y -patch b7cf79bc1e3454f7dfdee86a480e72f312b43a14 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:42 CEST 2018 - * WIP -Shall I unrecord this patch? (2/2) [ynW...], or ? for more options: y -Do you want to Unrecord these patches? [Yglqk...], or ? for more options: y -Finished unrecording. -$ darcs log -patch faf56a95edb01004d10f3bd4b72ad8d2b5ad2044 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:10 CEST 2018 - * initial record -``` - -Okay, good. We are now back with only one patch in our repository. We have -decided that this is the only thing that we want to keep and re-record our work -on top of that. Since `unrecord` does not change our working tree still contains -our work. - -``` -$ cat Main.hs -main = do - putStrLn "Hello!" - putStrLn "World!" - putStrLn "Everyone!" -``` - -Now all the modifications that we have done to our project since the `initial -record` are now unrecorded again and `darcs whatsnew` will report them as such. - -``` -$ darcs whatsnew -hunk ./Main.hs 3 -+ putStrLn "World!" -+ putStrLn "Everyone!" -``` - -So let's create a new patch single patch out of these changes and call it `add -cool new feature`. - -``` -$ darcs record -a -m 'add cool new feature' -Finished recording patch 'add cool new feature' -$ darcs log -v -patch 07729b85848c949e03ae856005a8c90bf42c785a -Author: raichoo@example.com -Date: Sun Jul 8 15:11:42 CEST 2018 - * add cool new feature - hunk ./Main.hs 3 - + putStrLn "World!" - + putStrLn "Everyone!" - -patch faf56a95edb01004d10f3bd4b72ad8d2b5ad2044 -Author: raichoo@example.com -Date: Sun Jul 8 14:51:10 CEST 2018 - * initial record - addfile ./Main.hs - hunk ./Main.hs 1 - +main = do - + putStrLn "Hello!" -``` - -That's better. We are now happy with our new patch. Again, keep in mind that you -should not do this with patches you have already published. Just like `amend` -this operation is **local only**. - -Unrecording individual changes ------------------------------- - -In the previous sections we have met `amend` and `unrecord` and sometimes it -would be great if we could bring those two functionalities together. Image you -have recorded a patch but instead of adding something to it by using `amend` you -would like to get rid of a change in that patch. Right now we only know how to -add things to a patch by using `amend` or `unrecord` to get right of the whole -thing. So here's a situation where things went a bit wrong. We have recorded a -patch and added a change that we didn't really want. - -``` -patch 319dfd6efb2f69bcb5205263aa716cfe6e5d54ea -Author: raichoo@example.com -Date: Mon Jul 16 20:20:28 CEST 2018 - * adding some stuff - hunk ./file.txt 1 - +I want to add this - hunk ./file.txt 3 - +but not this… -``` - -So one possibility would be to `unrecord` the whole patch and `record` it again, -this time without the change that we didn't want to have in there. In this -situation that might not be that big of an issue, but if we had a larger patch -and only wanted to get rid of a single line this approach is unacceptable. -However, `amend` has a very handy `--unrecord` flag that allows us to `unrecord` -individual changes from a patch. Super useful! - -``` -$ darcs amend --unrecord -patch 319dfd6efb2f69bcb5205263aa716cfe6e5d54ea -Author: raichoo@example.com -Date: Mon Jul 16 20:20:28 CEST 2018 - * adding some stuff -Shall I amend this patch? [yNjk...], or ? for more options: y -hunk ./file.txt 1 -+I want to add this -Shall I unrecord this change? (1/2) [ynW...], or ? for more options: n -hunk ./file.txt 3 -+but not this… -Shall I unrecord this change? (2/2) [ynW...], or ? for more options: y -Do you want to Unrecord these changes? [Yglqk...], or ? for more options: y -Finished amending patch: -patch 796db1adfd5a11c00feec4ee50fff63e4fd4ddd1 -Author: raichoo@example.com -Date: Mon Jul 16 20:25:22 CEST 2018 - * adding some stuff -$ darcs log -v --last 1 -patch 796db1adfd5a11c00feec4ee50fff63e4fd4ddd1 -Author: raichoo@example.com -Date: Mon Jul 16 20:25:22 CEST 2018 - * adding some stuff - hunk ./file.txt 1 - +I want to add this -$ darcs whatsnew -hunk ./file.txt 3 -+but not this… -``` - -That's a lot more convenient and this way we can make a lot less mistakes than -if we were to re-record our patch. - -OB-LIT-E-RATE! --------------- - -Sometime we want to go even further than `unrecord`. For example when a feature -we are working on turns out to be completely broken and we think that we are -better off to start from scratch. Of course we could just do an `unrecord` -followed by a `revert` to make the patches disappear from our repository and -then make the changes disappear from our working tree. If that is what you want -you can use `obliterate`. That command sounds scary for a reason. It basically -throws away work permanently. - -So here's our repository from the first section again. - -``` -$ ls -A B _darcs -$ darcs log -patch 9890bbfa50839674d45c416395bdb7e3bcd0ac00 -Author: raichoo@example.com -Date: Mon Jul 9 20:07:22 CEST 2018 - * use B - -patch 376b1bc0febb10802797a5afe7d55e35e42ac89f -Author: raichoo@example.com -Date: Mon Jul 9 19:04:01 CEST 2018 - * change B - -patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b -Author: raichoo@example.com -Date: Mon Jul 9 19:02:49 CEST 2018 - * change A - -patch 0d87b94c8d03fea3a2b613c43032df8da8cbff93 -Author: raichoo@example.com -Date: Mon Jul 9 19:02:02 CEST 2018 - * add B - -patch 0b2f173ea79d311c34d8e321b6a8d86582d18ff4 -Author: raichoo@example.com -Date: Mon Jul 9 19:01:03 CEST 2018 - * add A -``` - -We now want to get rid of all of the changes involving the file `B` and we want -to get rid of them for good. - -``` -$ darcs obliterate -patch 9890bbfa50839674d45c416395bdb7e3bcd0ac00 -Author: raichoo@example.com -Date: Mon Jul 9 20:07:22 CEST 2018 - * use B -Shall I obliterate this patch? (1/5) [ynW...], or ? for more options: y -patch 376b1bc0febb10802797a5afe7d55e35e42ac89f -Author: raichoo@example.com -Date: Mon Jul 9 19:04:01 CEST 2018 - * change B -Shall I obliterate this patch? (2/5) [ynW...], or ? for more options: y -patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b -Author: raichoo@example.com -Date: Mon Jul 9 19:02:49 CEST 2018 - * change A -Shall I obliterate this patch? (3/5) [ynW...], or ? for more options: n -patch 0d87b94c8d03fea3a2b613c43032df8da8cbff93 -Author: raichoo@example.com -Date: Mon Jul 9 19:02:02 CEST 2018 - * add B -Shall I obliterate this patch? (4/5) [ynW...], or ? for more options: y -Will not ask whether to obliterate 1 already decided patch. -Do you want to Obliterate these patches? [Yglqk...], or ? for more options: y -Finished obliterating. -$ darcs log -patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b -Author: raichoo@example.com -Date: Mon Jul 9 19:02:49 CEST 2018 - * change A - -patch 0b2f173ea79d311c34d8e321b6a8d86582d18ff4 -Author: raichoo@example.com -Date: Mon Jul 9 19:01:03 CEST 2018 - * add A -$ ls -A _darcs -``` - -`obliterate` has done its name justice. All the patches involving `B` are gone -as well as the related files in our working tree. Notice how `darcs` has kept -all our changes regarding file `A` even though the changes to `A` and `B` where -interleaved in our first `darcs log` output. But there is no relationship -between those changes so `darcs` could get separate those two cleanly from one -another. diff -rN -u old-darcs-book/en/08-rewriting-history.md new-darcs-book/en/08-rewriting-history.md --- old-darcs-book/en/08-rewriting-history.md 1970-01-01 00:00:00.000000000 +0000 +++ new-darcs-book/en/08-rewriting-history.md 2024-11-23 21:06:57.301599299 +0000 @@ -0,0 +1,398 @@ +Rewriting History +================= + +Amending patches +---------------- + +When you start using version control you will quickly encounter situations where +you have recorded a patch and realize that you have made a mistake. For example +you have recorded a patch with a typo or you have forgotten to state a +dependency in a patch. That's really super annoying. What you could do now is +`record` a new patch correcting that error but that would make our history more +and more confusing as time progresses and this kind patches start to accumulate. +This is where `darcs amend` comes in handy, it let's you change a patch the you +have already recorded without creating a new one. + +As an example we are going to pretend that we accidentally didn't state the +dependency of our `use B` patch in the above section correctly, so our +repository once again looks like this. + +![](../img/dependencies-2.png) + +So let's use `amend` to right that wrong. + +``` +$ darcs amend --ask-deps -p 'use B' +patch 610c31ea41237cd407464ff41720d04bce214ef2 +Author: raichoo@example.com +Date: Mon Jul 9 20:05:30 CEST 2018 + * use B +Shall I amend this patch? [yNjk...], or ? for more options: y +patch 376b1bc0febb10802797a5afe7d55e35e42ac89f +Author: raichoo@example.com +Date: Mon Jul 9 19:04:01 CEST 2018 + * change B +Shall I depend on this patch? (1/2) [ynW...], or ? for more options: y +Will not ask whether to depend on 1 already decided patch. +Do you want to Depend on these patches? [Yglqk...], or ? for more options: y +Finished amending patch: +patch 9890bbfa50839674d45c416395bdb7e3bcd0ac00 +Author: raichoo@example.com +Date: Mon Jul 9 20:07:22 CEST 2018 + * use B +``` + +We have used the `-p` flag to state a pattern for the patch we want to `amend` +and instructed `darcs` to prompt us for dependencies. We don't need to specify a +pattern but sometimes if we know exactly what patch we want to `amend` it can +certainly speed up the process. After selecting the patch we want to take care +of, `darcs` will prompt us for changes just like it would to when recording a +change. Our repository now looks like we want it to. + +![](../img/dependencies-3.png) + +`amend` works very much like `record` but rather than recording a new patch it +prompts you for an existing patch that you intend to improve first and then +proceeds just like we are used to when recording patches. We can add more +changes to our patch, change hunks, messages, author etcetera. Keep in mind that +you should not rewrite patches that have already been pushed to a public +repository since this action is **local only**, pushed patches will remain in +your remote repository even if you amend them locally. If you want to change the +state of a remote repository your best option is to `record` a new patch and +`push` it there. + +You also cannot `amend` patches that are a dependency of another patch. That +would be like pulling a rug away from under their feet. There are more powerful +tools that let you do even that, but that's something for a later chapter. + +Another example that is a bit more common deals with typos. Typos are probably +the most annoying thing when you deal with recording patches. They show up in +parts of your projects as well as patch names. Heck, they are pretty much +everywhere, just look at this patch gone horribly wrong. + +``` +$ darcs log -v +patch a7f5a2efe162787b3e7f6ceb215f53fa300f6590 +Author: raichoo@example.com +Date: Tue Jul 10 19:41:56 CEST 2018 + * initial rceord + addfile ./Main.hs + hunk ./Main.hs 1 + +main = "Hello Wrold!" +``` + +Oh boy, looks like we weren't quite awake yet when we recorded that patch. We +misspelled "World" as well as "record". That's quite embarrassing, surely we +don't want to `push` that! Thankfully we can still `amend` that patch before its +publication. + +``` +$ sed -i '' 's/Wrold/World/' Main.hs +$ darcs amend -m 'initial record' +patch a7f5a2efe162787b3e7f6ceb215f53fa300f6590 +Author: raichoo@example.com +Date: Tue Jul 10 19:41:56 CEST 2018 + * initial rceord +Shall I amend this patch? [yNjk...], or ? for more options: y +hunk ./Main.hs 1 +-main = "Hello Wrold!" ++main = "Hello World!" +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 amending patch: +patch 1e00a2684025c2ee9e1cbbb809d71d8167482458 +Author: raichoo@example.com +Date: Tue Jul 10 19:45:57 CEST 2018 + * initial record +``` + +Patch quality is certainly an important thing to take care of, so be sure to +double check before you publish something important. + +Unrecording patches +------------------- + +Sometimes we want to get rid of patches without getting rid of the work we have +done. Maybe we want to fold a bunch of patches into one, or maybe we want to +organize our patches a little differently. Whatever the case, sometimes some +patches need to be removed from our local repository and `unrecord` is how we +can do that. + +Let's say we are currently working on a new feature in our project and our +history currently looks something like this. + +We started out with a Haskell program just printing out "Hello!" and then we got +the feature request asking us to add two more messages to the output. First we +added some code that additionally prints out "World!". At that point wanted to +capture our progress, so we decided to `record` a patch and call it `WIP`. Then +we proceeded to add the other message requested in the feature and record that +as well. + +``` +$ cat Main.hs +main = do + putStrLn "Hello!" + putStrLn "World!" + putStrLn "Everyone!" +$ darcs log -v +patch 4f43a522ae0162dcef8dab6aab0d354ede209767 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:56 CEST 2018 + * WIP + hunk ./Main.hs 4 + + putStrLn "Everyone!" + +patch b7cf79bc1e3454f7dfdee86a480e72f312b43a14 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:42 CEST 2018 + * WIP + hunk ./Main.hs 3 + + putStrLn "World!" + +patch faf56a95edb01004d10f3bd4b72ad8d2b5ad2044 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:10 CEST 2018 + * initial record + addfile ./Main.hs + hunk ./Main.hs 1 + +main = do + + putStrLn "Hello!" +``` + +That's not a very useful history and really not fit for publishing since it's +showing our work in progress rather than a finished patch. It certainly served +its purpose, but it really needs to be cleaned up before we show it to the rest +of the world. We have recorded the state of our working tree whenever we felt +confident and then moved onward to the next step. We want to squash the two +`WIP` patches into a single patch. The first thing we do is that we `unrecord` +them. Since we have named all our "work in progress" patches `WIP` we can +specify a pattern for `unrecord` using the `-p` flag so `darcs` will only ask us +if it should `unrecord` patches that have a name matching this pattern. + +``` +$ darcs unrecord -p WIP +patch 4f43a522ae0162dcef8dab6aab0d354ede209767 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:56 CEST 2018 + * WIP +Shall I unrecord this patch? (1/2) [ynW...], or ? for more options: y +patch b7cf79bc1e3454f7dfdee86a480e72f312b43a14 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:42 CEST 2018 + * WIP +Shall I unrecord this patch? (2/2) [ynW...], or ? for more options: y +Do you want to Unrecord these patches? [Yglqk...], or ? for more options: y +Finished unrecording. +$ darcs log +patch faf56a95edb01004d10f3bd4b72ad8d2b5ad2044 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:10 CEST 2018 + * initial record +``` + +Okay, good. We are now back with only one patch in our repository. We have +decided that this is the only thing that we want to keep and re-record our work +on top of that. Since `unrecord` does not change our working tree still contains +our work. + +``` +$ cat Main.hs +main = do + putStrLn "Hello!" + putStrLn "World!" + putStrLn "Everyone!" +``` + +Now all the modifications that we have done to our project since the `initial +record` are now unrecorded again and `darcs whatsnew` will report them as such. + +``` +$ darcs whatsnew +hunk ./Main.hs 3 ++ putStrLn "World!" ++ putStrLn "Everyone!" +``` + +So let's create a new patch single patch out of these changes and call it `add +cool new feature`. + +``` +$ darcs record -a -m 'add cool new feature' +Finished recording patch 'add cool new feature' +$ darcs log -v +patch 07729b85848c949e03ae856005a8c90bf42c785a +Author: raichoo@example.com +Date: Sun Jul 8 15:11:42 CEST 2018 + * add cool new feature + hunk ./Main.hs 3 + + putStrLn "World!" + + putStrLn "Everyone!" + +patch faf56a95edb01004d10f3bd4b72ad8d2b5ad2044 +Author: raichoo@example.com +Date: Sun Jul 8 14:51:10 CEST 2018 + * initial record + addfile ./Main.hs + hunk ./Main.hs 1 + +main = do + + putStrLn "Hello!" +``` + +That's better. We are now happy with our new patch. Again, keep in mind that you +should not do this with patches you have already published. Just like `amend` +this operation is **local only**. + +Unrecording individual changes +------------------------------ + +In the previous sections we have met `amend` and `unrecord` and sometimes it +would be great if we could bring those two functionalities together. Image you +have recorded a patch but instead of adding something to it by using `amend` you +would like to get rid of a change in that patch. Right now we only know how to +add things to a patch by using `amend` or `unrecord` to get right of the whole +thing. So here's a situation where things went a bit wrong. We have recorded a +patch and added a change that we didn't really want. + +``` +patch 319dfd6efb2f69bcb5205263aa716cfe6e5d54ea +Author: raichoo@example.com +Date: Mon Jul 16 20:20:28 CEST 2018 + * adding some stuff + hunk ./file.txt 1 + +I want to add this + hunk ./file.txt 3 + +but not this… +``` + +So one possibility would be to `unrecord` the whole patch and `record` it again, +this time without the change that we didn't want to have in there. In this +situation that might not be that big of an issue, but if we had a larger patch +and only wanted to get rid of a single line this approach is unacceptable. +However, `amend` has a very handy `--unrecord` flag that allows us to `unrecord` +individual changes from a patch. Super useful! + +``` +$ darcs amend --unrecord +patch 319dfd6efb2f69bcb5205263aa716cfe6e5d54ea +Author: raichoo@example.com +Date: Mon Jul 16 20:20:28 CEST 2018 + * adding some stuff +Shall I amend this patch? [yNjk...], or ? for more options: y +hunk ./file.txt 1 ++I want to add this +Shall I unrecord this change? (1/2) [ynW...], or ? for more options: n +hunk ./file.txt 3 ++but not this… +Shall I unrecord this change? (2/2) [ynW...], or ? for more options: y +Do you want to Unrecord these changes? [Yglqk...], or ? for more options: y +Finished amending patch: +patch 796db1adfd5a11c00feec4ee50fff63e4fd4ddd1 +Author: raichoo@example.com +Date: Mon Jul 16 20:25:22 CEST 2018 + * adding some stuff +$ darcs log -v --last 1 +patch 796db1adfd5a11c00feec4ee50fff63e4fd4ddd1 +Author: raichoo@example.com +Date: Mon Jul 16 20:25:22 CEST 2018 + * adding some stuff + hunk ./file.txt 1 + +I want to add this +$ darcs whatsnew +hunk ./file.txt 3 ++but not this… +``` + +That's a lot more convenient and this way we can make a lot less mistakes than +if we were to re-record our patch. + +OB-LIT-E-RATE! +-------------- + +Sometime we want to go even further than `unrecord`. For example when a feature +we are working on turns out to be completely broken and we think that we are +better off to start from scratch. Of course we could just do an `unrecord` +followed by a `revert` to make the patches disappear from our repository and +then make the changes disappear from our working tree. If that is what you want +you can use `obliterate`. That command sounds scary for a reason. It basically +throws away work permanently. + +So here's our repository from the first section again. + +``` +$ ls +A B _darcs +$ darcs log +patch 9890bbfa50839674d45c416395bdb7e3bcd0ac00 +Author: raichoo@example.com +Date: Mon Jul 9 20:07:22 CEST 2018 + * use B + +patch 376b1bc0febb10802797a5afe7d55e35e42ac89f +Author: raichoo@example.com +Date: Mon Jul 9 19:04:01 CEST 2018 + * change B + +patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b +Author: raichoo@example.com +Date: Mon Jul 9 19:02:49 CEST 2018 + * change A + +patch 0d87b94c8d03fea3a2b613c43032df8da8cbff93 +Author: raichoo@example.com +Date: Mon Jul 9 19:02:02 CEST 2018 + * add B + +patch 0b2f173ea79d311c34d8e321b6a8d86582d18ff4 +Author: raichoo@example.com +Date: Mon Jul 9 19:01:03 CEST 2018 + * add A +``` + +We now want to get rid of all of the changes involving the file `B` and we want +to get rid of them for good. + +``` +$ darcs obliterate +patch 9890bbfa50839674d45c416395bdb7e3bcd0ac00 +Author: raichoo@example.com +Date: Mon Jul 9 20:07:22 CEST 2018 + * use B +Shall I obliterate this patch? (1/5) [ynW...], or ? for more options: y +patch 376b1bc0febb10802797a5afe7d55e35e42ac89f +Author: raichoo@example.com +Date: Mon Jul 9 19:04:01 CEST 2018 + * change B +Shall I obliterate this patch? (2/5) [ynW...], or ? for more options: y +patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b +Author: raichoo@example.com +Date: Mon Jul 9 19:02:49 CEST 2018 + * change A +Shall I obliterate this patch? (3/5) [ynW...], or ? for more options: n +patch 0d87b94c8d03fea3a2b613c43032df8da8cbff93 +Author: raichoo@example.com +Date: Mon Jul 9 19:02:02 CEST 2018 + * add B +Shall I obliterate this patch? (4/5) [ynW...], or ? for more options: y +Will not ask whether to obliterate 1 already decided patch. +Do you want to Obliterate these patches? [Yglqk...], or ? for more options: y +Finished obliterating. +$ darcs log +patch 1f9b4b1566ce3410c70ad5231ff21abb0dfed04b +Author: raichoo@example.com +Date: Mon Jul 9 19:02:49 CEST 2018 + * change A + +patch 0b2f173ea79d311c34d8e321b6a8d86582d18ff4 +Author: raichoo@example.com +Date: Mon Jul 9 19:01:03 CEST 2018 + * add A +$ ls +A _darcs +``` + +`obliterate` has done its name justice. All the patches involving `B` are gone +as well as the related files in our working tree. Notice how `darcs` has kept +all our changes regarding file `A` even though the changes to `A` and `B` where +interleaved in our first `darcs log` output. But there is no relationship +between those changes so `darcs` could get separate those two cleanly from one +another.