Skip to content

Instantly share code, notes, and snippets.

@sebfisch
Last active December 14, 2015 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebfisch/5136973 to your computer and use it in GitHub Desktop.
Save sebfisch/5136973 to your computer and use it in GitHub Desktop.
A dialog on how to manage patches with Darcs.

A Dialog on How to Manage Patches with Darcs

Fred: So, you know Darcs?

Lisa: Sure.

Fred: I heard it is quite flexible in managing patches. Wanna show me?

Lisa: Ok, let's make a new repository for some imaginary project.

# mkdir project; cd project; darcs init

Fred: Ok, now add these files. A Main module using some helper function from a Utilities module.

# echo define helperFunction > Utilities
# echo import Utilities > Main
# echo use helperFunction >> Main

Lisa: Let's make a patch including all these changes.

# darcs -lam "added initial Main and Utilities"

Fred: I want to add database access. I make a new module and use it in Main.

# echo define access > Database
# echo use Database.access >> Main

Fred: I also add a helper to Utilities and use it in Database.

# echo define dbHelper >> Utilities
# echo use dbHelper >> Database

Lisa: Here is a patch for that.

# darcs record -lam "added database access with helper"

Lisa: I add a GUI and use your database helper for that.

# echo import Utilities > GUI
# echo use dbHelper >> GUI

Lisa: I also add another helper function and use it.

# echo define guiHelper >> Utilities
# echo use guiHelper >> GUI

Fred: By now, I know how to make a patch.

# darcs record -lam "added GUI with helper and using DB helper"

Lisa: Let's see what we have until now.

# yes | darcs changes --reverse

[added initial Main and Utilities]
addfile ./Main
hunk ./Main 1
+import Utilities
+use helperFuntion
addfile ./Utilities
hunk ./Utilities 1
+define helperFunction

[added database access with helper]
addfile ./Database
hunk ./Database 1
+define access
+use dbHelper
hunk ./Main 3
+use Database.access
hunk ./Utilities 2
+define dbHelper

[added GUI with helper and using DB helper]
addfile ./GUI
hunk ./GUI 1
+import Utilities
+use dbHelper
+use guiHelper
hunk ./Utilities 3
+define guiHelper

Fred: Ok, I see which files were added by which patch and hunks seem to be changes to the contents of files.

Lisa: Right. Now I want to remove database access but keep the GUI.

Fred: You can't remove the database patch because the GUI patch depends on it adding the dbHelper.

Lisa: It would be nice, if Darcs would let me split your patch, so I can remove your changes to Database and Main but keep your changes to Utilities. There is no split command but we can do it by hand.

# cd ..; mkdir clone; cd clone; darcs init
# echo yyny | darcs pull ../project

Fred: Now we have a clone containing only the first two patches and can remove the second because nothing depends on it?

Lisa: Right. We can use unrecord for that. Then we record two patches, splitting your changes.

# echo yny | darcs unrecord
# echo nnyy | darcs record -m "added database helper"
# yes | darcs record -m "added database access"

Lisa: Now we can pull the remaining changes. This will also include the original big patch adding database access and the helper function.

# yes | darcs pull project

Fred: So now we are back where we started?

Lisa: But we can now obliterate the big database patch as well as the small one that I don't need for the GUI.

# echo nyyy | darcs obliterate

Fred: Let's see what we have now.

# yes | darcs changes --reverse

[added initial Main and Utilities]
addfile ./Main
hunk ./Main 1
+import Utilities
+use helperFuntion
addfile ./Utilities
hunk ./Utilities 1
+define helperFunction

[added database helper]
hunk ./Utilities 2
+define dbHelper

[added GUI with helper and using DB helper]
addfile ./GUI
hunk ./GUI 1
+import Utilities
+use dbHelper
+use guiHelper
hunk ./Utilities 3
+define guiHelper

Fred: Ok, but that sure was complicated. There should be a split command that does what you just did by hand. Can we now pull back the changes from the clone into our project?

# cd ../project; darcs pull ../clone

darcs: bug at src/Darcs/Patch/Depends.hs:322
Failed to commute common patches:
  * added GUI with helper and using DB helper
  * added database access with helper

Lisa: Oops! Let's just work in the clone.

Fred: I know how to drastically simplify your GUI implementation. I don't need the guiHelper and just delete it from GUI and Utilities.

# sed -i "$ d" Utilities
# sed -i "$ d" GUI

Fred: Let's record that.

# darcs record -am "simplified GUI"

Lisa: There are now two patches for adding the GUI.

# yes | darcs changes --reverse --last=2

[added GUI with helper and using DB helper]
addfile ./GUI
hunk ./GUI 1
+import Utilities
+use dbHelper
+use guiHelper
hunk ./Utilities 3
+define guiHelper

[simplified GUI]
hunk ./GUI 3
-use guiHelper
hunk ./Utilities 3
-define guiHelper

Fred: Hmm, I wish I could merge them into a single patch that just adds the GUI file without using guiHelper.

Lisa: Then you should have used amend-record instead of recording a new patch. Now you can still unrecord and then amend the changes.

# echo yny | darcs unrecord
# yes | darcs amend-record

Fred: But unrecording would not work if there were already other patches depending on the simplified GUI.

Lisa: Right. That would complicate things again. Seems like there should be a merge command. Or can splitting and merging be implemented using rebase for Darcs?

Fred: Well, you said you know Darcs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment