9. .hgrc: Extensions
● Mercurial without extensions is barely
useable
● Small core, but easy to extend
● Extensions add some sugar
● Python scripts
○ Write your own!
10. .hgrc: Extensions
[extensions]
pager = # pipe through less automatically
color = # Color output
graphlog = # ASCII art graphical logs
fetch = # Pull-and-merge, use with care
mq = # Strip, flexible commit queues
highlight = # syntax highlighting in hgweb
11. .hgrc: aliases
[alias]
blame = annotate -u
out-diff = out -pvM
in-diff = in -pvM
# Show the diff of a given changeset ID
show = log -p -v -r
12. How to think about Mercurial
It's a stack of patches
with downward links between them
13. A Stack of Patches
Working directory
commit
@ 4:ch4ch4: Change number 3
Parent: ch3ch3
tag: tip
Top of the
stack
Patch Save Time
3:ch3ch3: Merge in Alice's work
Stack index Parent: ch2ch2
Clone- Parent: al1al1
dependent!
Node ID 2:ch2ch2: Change number 2
Unique! Parent: ch1ch1
1:al1al1: Alice's changes
parent: ch1ch1 is-child-of
0:ch1ch1: Change number 1
Root commit Parent: ch0ch0
Identifies a repository
14. What is a commit?
● Diff
● Metadata
○ timestamp
○ user SHA1 Unique Commit
○ branch? ID
○ parent(s): 1 or 2
○ ...
● If you change any of these fields:
○ commit ID will change
○ you create a different commit!
15. Cause of all those merges
Local repository status:
1:ch2ch2: Change number 2
Parent: ch1ch1
0:ch1ch1: Change number 1
16. Cause of all those merges
Pull from Alice's repository:
2:al1al1: Alice's changes
parent: ch1ch1
No re-ordering can 1:ch2ch2: Change number 2
Parent: ch1ch1
happen without altering
the tags and therefore the
unique hashes of the
commits!
0:ch1ch1: Change number 1
17. Cause of all those merges
2 'heads'!
2:al1al1: Alice's changes
parent: ch1ch1
1:ch2ch2: Change number 2
Parent: ch1ch1
0:ch1ch1: Change number 1
We want one 'head'!
18. Cause of all those merges
3:ch3ch3: Merge in Alice's work
Parent: ch2ch2
Parent: al1al1
2:al1al1: Alice's changes
parent: ch1ch1
1:ch2ch2: Change number 2
Parent: ch1ch1
0:ch1ch1: Change number 1
-> We need to merge. :-(
20. Quiz 1
● What is .hgrc good for?
○ Username
○ Extensions
○ Aliases
○ Much, much more
21. Quiz 1
● What is .hgrc good for?
○ Username
○ Extensions
○ Aliases
○ Much, much more
● How should you imagine a Mercurial
repository?
22. Quiz 1
● What is .hgrc good for?
○ Username
○ Extensions
○ Aliases
○ Much, much more
● How should you imagine a Mercurial
repository?
○ As a stack of patches.
23. Basic Commands
● help
● clone
● init
● add/remove/addremove
● cp/rename/mv
● status
● diff
● commit
24. Help!
● hg help: General help
○ List of commands
○ List of extensions
○ Additional help topics (advanced stuff)
● hg help <command>
○ hg <command> --help
25. Cloning a repository
● hg clone <remote> <foldername>
● Creates a .hg folder in <foldername>
● Downloads all the patches/commits from
<remote>
● Checks out the files of the last commit on the
default branch on your disk, in <foldername>
26. Init: Creating a new repository
● hg init <foldername>
● Creates a .hg folder in <foldername>
○ No commits yet
○ No changes yet
27. Add/Remove/Addremove
● hg add <path>
○ 'enables' <path> for committing
● hg rm <path>
○ 'disables' <path> for committing
● hg addremove <path>
○ "Add all new files and remove all missing files from
the repository."
○ Use with care (.hgignore!)
● Paths either absolute or relative to $PWD!
○ <> 'hg status' output
32. locate: test a pattern
● "locate files matching specific patterns"
● hg locate "glob:**.py"
○ The quotes are needed to avoid your shell
expanding the '*'
● Only prints files under Mercurial control
○ Like find, but limited to 'tracked' files.
33. Diff: what did I change?
● hg diff
● Changed files:
○ Show diff with previously committed version
● Added files:
○ Show content
● Removed files:
○ Show content
● Specify <path>
○ Diff only that file/those files
○ Can use re: and glob:
● USE COLOR !!!
34. Color extension
● .hgrc
● [extensions]
color =
● Colors can be customized
● Adds color to almost all commands that have output
○ status
○ diff
○ log
○ ...
35. Commit: Create a new commit
● hg commit
○ Username
■ from .hgrc (preferably!)
■ -u "Joske Vermeulen <joske@incubaid.com>"
○ Commit message
■ in editor (default)
■ -m "My commit"
○ Files
■ Default: everything shown as A/R/M in status
■ Use -I and -X for more control (re, glob)
● Creates a new commit
● Use nice commit messages
36. Log: check the history
● hg log
● Order: stack of patches!
● Spammy? There's an extension for that!
[extensions]
pager =
[pager]
pager = less -R
attend = annotate, cat, df, diff,
>>glog, help, in-diff, incoming,
>>log, out-diff, outgoing, qdiff,
>>show, tip, grep
37. Graph log
● Useful when branching, merging, ...
● ASCII art graphs!
● Need to enable the extension
○ [extensions]
graphlog =
● hg glog
● @ marks the working directory commit
41. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
42. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
43. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
● Commit only one file when multiple are
changed?
44. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
● Commit only one file when multiple are
changed?
○ hg commit -I <path>
45. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
● Commit only one file when multiple are
changed?
○ hg commit -I <path>
● Command to show an ASCII art log graph?
46. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
● Commit only one file when multiple are
changed?
○ hg commit -I <path>
● Command to show an ASCII art log graph?
○ hg glog
47. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
● Commit only one file when multiple are
changed?
○ hg commit -I <path>
● Command to show an ASCII art log graph?
○ hg glog
● Mark for the working directory commit?
48. Quiz 2: basic hg commands
● Start tracking an untracked file?
○ hg add <path>
● Print the root of the repository you're in?
○ hg root
● Commit only one file when multiple are
changed?
○ hg commit -I <path>
● Command to show an ASCII art log graph?
○ hg glog
● Mark for the working directory commit?
○ @
50. Branching...
● Not very flexible in Mercurial
○ Unique branch names
○ No branch renames
○ Branch name must be chosen before first commit on
that branch
○ ...
● Just adds a "branch=name" to the metadata
of a commit.
● Default branch has no "branch=default"
● Interesting comparison: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
51. Back to the stack of patches...
8:cb2cb2: Also on the branch
Parent: cb1cb1
branch: mybranch
tag: tip
hg update mybranch
Patch Save Time
7:ch5ch5: Change number 5
Parent: ch4ch4
hg update default
6:cb1cb1: Branching!
Parent: ch3ch3
branch: mybranch
hg update 4 && hg branch mybranch
5:ch4ch4: Change number 4
Parent: ch3ch3
4:ch3ch3: Change number 3
Parent: ch2ch2
52. Branch-related commands
● hg branch
○ What branch am I on?
● hg branches
○ What branches are there?
● hg branch <name>
○ Create a branch with <name>
53. Update
● Changes the working directory commit (@)
○ hg update <branchname>
■ Go to the last commit on branch <branchname>
○ hg update <rev>
■ Go to revision <rev>
● Discard local changes (danger, no backup!)
○ hg update --clean ...
○ Forces the update
57. hg paths
● Prints the named paths for the repository:
○ $ hg paths
default = ssh://hg@bitbucket.org/incubaid/pylabs-core-5.1
private = ssh://hg@bitbucket.org/geiregaj/pylabs-core-5.1-jens
58. Push -b
● hg push -b default ssh://...
● Push one branch
○ Keeps the <remote> clean
○ Push your branch to a private repository, after merge
push to the common repository
59. hg duw
● [alias]
duw = push -r .
● Pushes your working directory commit (@)
60. Pull
● hg pull
● hg pull default
● hg pull ssh://hg@bitbucket.org/incubaid/pylabs-core-5.1
● Downloads the changesets that are on
<remote> but not on <local>
● Shortcut: hg pull -u
○ == hg pull && hg update
● Tip will be the newest of the pulled commits
61. Incoming, outgoing
● Show commits that would be pulled or
pushed
● Useful as a quick check without the danger
of pulling things you don't want yet.
62. Quiz 3
● Why do you need to commit to create a
branch?
63. Quiz 3
● Why do you need to commit to create a
branch?
○ Because branches only really exist in the commits,
as a tag. No commit means no tag. No tag means no
branch.
64. Quiz 3
● Why do you need to commit to create a
branch?
○ Because branches only really exist in the commits,
as metadata. No commit means no metadata. No
metadata means no branch.
● How to print all branch names?
65. Quiz 3
● Why do you need to commit to create a
branch?
○ Because branches only really exist in the commits,
as metadata. No commit means no metadata. No
metadata means no branch.
● How to print all branch names?
○ hg branches
66. Quiz 3
● Why do you need to commit to create a
branch?
○ Because branches only really exist in the commits,
as metadata. No commit means no metadata. No
metadata means no branch.
● How to print all branch names?
○ hg branches
● How to find out what your working directory
commit is?
67. Quiz 3
● Why do you need to commit to create a
branch?
○ Because branches only really exist in the commits,
as metadata. No commit means no metadata. No
metadata means no branch.
● How to print all branch names?
○ hg branches
● How to find out what your working directory
commit is?
○ hg identify
○ hg glog and search for the '@'
69. How to Merge
● This is where things typically go wrong.
○ Merge direction...
○ > 2 heads
○ Conflicts (oh noes!)
70. Merge Direction: Goal
● A small diff!
○ Keeps your tools from choking on HUGE diffs
● From hg merge --help
○ The current working directory is updated with all
changes made in the requested revision since the
last common predecessor revision.
71. Merge Direction
1. Create your local commit
2. Pull in the latest changes from <remote>
3. Check the situation with
a. hg glog
b. hg heads
4. Decide on the merge direction
5. hg update <base> (if needed)
6. hg merge
7. Check the merge (tests?)
8. Commit
72. Merge Direction
9:ch7ch7: Change number 7
Parent: ch6ch6
8:ch6ch6: Change number 6
Parent: ch5ch5
Pulled
7:ch5ch5: Change number 5
Parent: ch4ch4
@ 6:abcabc: My change
Parent: ch2ch2
5:ch4ch4: Change number 4
Parent: ch3ch3
4:ch3ch3: Change number 3
Parent: ch2ch2
73. Merge Direction
hg update ch7ch7
@ 9:ch7ch7: Change number 7
Parent: ch6ch6
8:ch6ch6: Change number 6
Parent: ch5ch5
Pulled 10 changes
7:ch5ch5: Change number 5
Parent: ch4ch4
@ 6:abcabc: My change
Parent: ch2ch2
5:ch4ch4: Change number 4
Parent: ch3ch3
1000 changes 4:ch3ch3: Change number 3
Parent: ch2ch2
74. @ 9:ch8ch8c: Merge
Parent: ch7ch7
Merge Direction Parent: abcabc
9:ch7ch7: Change number 7
Parent: ch6ch6 hg merge
hg commit
8:ch6ch6: Change number 6
Parent: ch5ch5
-m "Merge"
Pulled
7:ch5ch5: Change number 5
Parent: ch4ch4
6:abcabc: My change
Parent: ch2ch2
5:ch4ch4: Change number 4
Parent: ch3ch3
4:ch3ch3: Change number 3
Parent: ch2ch2
75. Merge: > 2 heads
● Mercurial can only merge 2 heads / commit
● To merge > 2 heads, merge multiple times
○ Choose head with most changes (biggest diff)
○ hg update <bighead>
○ hg merge <smallerhead>
○ hg commit
○ -> repeat
76. Merge: conflicts
● kdiff3
○ 3-way merge tool
○ Powerful
○ Simple to use
○ Install it and configure it in your .hgrc
■ or use my example config...
77. Merge: conflicts Next unmerged conflict
Choose
● Kdiff3! line
Common ancestor Local
Remote
Result: Edit by clicking A/B/C or by manually editing the text
78. Merge: conflicts
● Kdiff3 workflow:
○ Fix all unmerged conflicts
■ use triple arrows to find them
■ A/B/C or manual edit
○ When all unmerged conflicts are resolved
■ Click 'save'
■ Exit kdiff3
79. Howto: discard changes
● You changed or removed a file
● But want to restore it to how it looked in the
last commit
○ hg revert <path>
● Shortcut: revert everything:
○ hg revert --all
● The content before the revert is saved with
suffix .orig
● Revert to a specific revision
○ hg revert -r abcabc <path>
80. Howto: Collaborate
● Avoid working on the same files at the same
time
○ Same for moving files that other people are working
on
● Push your code often
○ What if you lose your laptop?
○ If you don't want to push to the main repository,
create a private clone on Bitbucket
● Merge with care
● But...
○ what if Bitbucket goes down?!
82. Howto: Collaborate
● hg serve to the rescue!
● Runs an HTTP server
○ Browse your repository
■ Useful for quick reviews!
○ Pull code from it
■ hg pull http://my.ip.com:8000/
● hg serve is built-in
83. Howto: Collaborate
● Default push/pull 'protocol': SSH
● Allows pushing (hg serve does not, by
default)
● hg push ssh://user@host/home/user/repo/path/
○ Use SSH keys
84. Howto: Feature Branches
● Upside:
○ Develop your feature without messing up the
'default' branch of the repository
● Downside
○ amount of branches might become very large...
■ Close your feature branches
■ Use clones, bookmarks, ...
85. Howto: Feature Branches
Feature merged into
default D6
No choice about merge direction
here. D5 B5 Use --close-branch
D4 B4 Merge latest
default
D3 B3 hg merge default
B2
D2 B1 Feature branch
D1
Default D0
87. Howto: (Bitbucket) SSH keys
● Easier pushing and pulling from Bitbucket
● Easy to set up
○ http://bit.ly/S4l1ly
● Invest 2 minutes, gain years of easier
Bitbucket interaction.
● Also useful for non-Bitbucket servers
○ Use ssh-copy-id to publish your public key to a
remote machine
88. Howto: Remove a commit
● Removes a commit and every commit
depending on it
○ DANGER!
○ Creates a backup in .hg/strip-backup as a bundle
○ Can only be used when the strip happens on ALL
clones that contain the stripped commit(s).
● Part of the mq extension:
○ [extensions]
mq =
● Bitbucket can strip too
○ Part of the admin interface
89. Howto: undo a commit
● Commit the inverted patch of a previous
commit
● hg backout <rev>
91. Quiz 4
● What is the command to discard changes?
○ hg revert
92. Quiz 4
● What is the command to discard changes?
○ hg revert
● What 'protocols' can be used for push/pull?
93. Quiz 4
● What is the command to discard changes?
○ hg revert
● What 'protocols' can be used for push/pull?
○ SSH and HTTP
94. Quiz 4
● What is the command to discard changes?
○ hg revert
● What 'protocols' can be used for push/pull?
○ SSH and HTTP
● Which head should you merge to?
95. Quiz 4
● What is the command to discard changes?
○ hg revert
● What 'protocols' can be used for push/pull?
○ SSH and HTTP
● Which head should you merge to?
○ The one with the most changes
96. End of the basics.
● But there's much, much more.
○ 'Advanced' commands (cat, archive, locate, grep)
○ revsets
○ mq
○ (let me know what you would like to know)
○ Anyone interested?
● Links:
○ http://confluence.incubaid.
com/display/ENG/Incubaid+Starter+Kit
○ http://confluence.incubaid.
com/display/ENG/Mercurial+Cheat+Sheet+-
+Hg+Cheat+Sheet
○ http://hginit.com/
○ http://hgbook.red-bean.com/