3. In it's purest non-VCS specific definition
a line of 1+ changes that diverges from another one
1 2 3 4 5 6
1 2 3 4 6 7
5 8 9
I'm a branch!
4. or why you don't want to be forced into a
linear history
Why branch?
5. Commit races
are a thing of every day with linear history
1 2 3 4
5
6
Hey!, my changes
had to go first!
Deal with it!
(and by "it" I mean merge conflicts)
7. Merging hell
Branching is good, until you forget to merge early. Branch way more and you
will be merging more frequently and with less bad consequences.
1 2 3 4 126
5 94 ?
Uh, oh!... long-lived branches
8. or why merging has to kick-ass by design
Why are branches
important to DVCSs?
9. Saved a new change?
congratulations... you also created a new branch (one per clone)
Blessed Repository
Clones
Clone A
Clone B
Clone C
1 2 3
3 4 5
3 4 5 6
3 4
T I M E
cloning happens three times at revision 3
10. Now how do I get my work back to the main repository?
well, you merge
1 2 3 A:4 A:5
B:4 B:5 B:6
TIME
B:7*
C:4 C:5*
New commit after merging
Blessed Repository
merge
merge
branch
branch
First one to push back will not create a branch
11. And if I don't want to merge?
...you don't, but you create heads
1 2 3 A:4 A:5
B:4 B:5 B:6
TIME
C:4
Heads
Blessed Repository
Everything being worked at the default branch
(can be considered as a "trunk")
12. If these are branches, how come
they have no name, huh?
● These are called "anonymous branches"
● They are created implicitly each time you clone
○ When repositories are formally disconnected
○ ...and as a consequence two new revisions can have the same parent
○ Normally one exists per developer (as they work)
● You don't have to care about them
○ They are frequently merged:
■ Each time you push, Mercurial notifies you should pull and merge
■ You can regularly pull and merge locally to keep your work in sync
○ Numbering is relative (sha1 hashes are tracked by Mercurial)
● They give you breathing room to work
○ Without having to worry about creating named branches
○ If you are already working in a named branch
15. Using clones
Not really recommended as real branching, but is easy to cleanup
Local Repository Clones for experimenting
Clone A
Clone B
Clone C
1 2 3
3 4 5
3 4 5 6
3 4
16. Cloning to branch
● Not remotely recommended as it can be just as
convenient as working with any other branching method
○ But folks still do it
○ No need to know about branching concepts
○ No need to clone from the remote repository, or even locally, just copy
& paste the repository folder
○ Integrating work back to your main clone involves the same
● Use cases (or why people do it)
○ Informal throw-away experimentation
○ Working with two branches at the same time (without wanting to wait
for the 2-3 second update)
● Understand it, but preferably don't do it
18. How do you create one?
name it, then commit it
1 2 4
5
DEFAULT
hg commit
hg update defaulthg branch my_branch
2
31
MY_BRANCH
hg update my_branch4
Executing hg branches should list "default" and "my_branch"
Executing hg branch should display the current branch as "my_branch" after 4
19. How do you merge them?
Easy as 1-2-3
1 2 4
5
DEFAULT
MY_BRANCH 6
Do an hg update <branch or revision> to move the branch you want to merge another to.
Do an hg merge <branch or revision> to merge another branch into the current one.
hg update my_branch1
hg merge default2
hg commit3
20. What do you do when you finish with it?
just add the --close-branch option when you commit
1 2 4
5
DEFAULT
hg commit --close-branch1
MY_BRANCH 6 7
my_branch will no longer be listed in hg branches, but you
can reopen it by creating a new normal commit
21. Named branches
● Standard way of branching
● Branches always get all pushed at the same time unless
specified
● Recommendable to have a branch policy and/or naming
convention, e.g.:
○ Types:
■ Bugfix branches should pull frequently from the baseline and be
short-lived
■ Feature branches can be long-lived
■ Hotfix branches should be merged before other branches
○ Naming
<type>-(<ticket system>_<ticket number>)?-<description>
● Named branches are the only ones that use the "branch" command
30. Anonymous branching
● The branches that just happen by
themselves.
● Can be made intentionally/forcefully by
changing to a past revision and committing
from it
● Anonymous branches can be counted by
counting named branches and subtracting
the number of heads
● Heads can be unmade easily (merge)
● Not very sane to do anonymous branching
locally
32. Making anonymous branching sane
and they can be private (i.e. not pushed by default)
1 3 4
5
DEFAULT
hg commit
hg update -r 3
hg commit
1
2
3
hg bookmark my_stuff4
my_stuff
33. And using them is as easy as with named branches
anonymous branches without having to track revision numbers
1 3 4
5
DEFAULT
hg update default5
hg update my_stuff6
my_stuff
5
hg commit7
the "my_stuff"
bookmark moves
automatically when
you commit
...updating to a branch
...updating to a bookmark
34. Bookmarks
● A good local replacement for git's "private local
branching"
○ Can be deleted
○ But keeping the history
○ Can be shared (pushed/pulled) or not
● Bookmarks are not branches
○ They just give a name to anonymous branches
36. No need to worry about them, 99% of the
time, but you should understand what they
mean
Heads
37. Don't lose your heads
...because there should be one head per branch (anonymous or named)
1 2 4
5
DEFAULT
MY_BRANCH
Executing hg heads should list 4 & 5 as heads
heads
38. Having 1+ heads in a named branch means there are pending merges
probably someone used hg push -f, and you should go hit them on the head
(the one above their shoulders)
1 2 4
5
DEFAULT
MY_BRANCH
Executing hg heads should list 4, 6 & 7 as heads,
6 & 7 belonging to my_branch
heads
6
7
39. Having a merged head in a given branch means the branch is inactive
...meaning it is abandoned, since it's changes are no longer unique to the
named branch (aka has no new code)
1 2 4
5
DEFAULT
MY_BRANCH
Executing hg branches should mark my_branch as "inactive"
Committing again on my_branch makes the branch active again
heads
6
inactive branch
41. Feature branching
● Make a branch for each feature, refactor,
experiment, bug, hotfix, etc.
● A fool-proof integration workflow
○ While at your feature branch, keep pulling and
merging the common baseline into it as often as
possible. Deal with merging often.
○ When finished with your feature branch:
■ Merge baseline int it one last time
■ Test/hack ad-nauseam
■ Close branch
■ Change to baseline and merge your branch into it
● How is this different in DVCS?:
○ It is a lot less scary because you can screw up
42. Feature branching
● Benefits:
○ Code-review is easy, even if you decided to do many
commits
○ All your changes are "pull-request" ready in such a
way that is easier to think about (and even
document)
○ You can multi-task and use branches to stashaway
your changes
○ Collaboration with peers is simplified
● You and branches are now BFFs ♥
You will wonder where branches were all this time and how could you live
without them (oh... yeah, copy/pasting your project directory)
43. ... I want private local branching like in Git
What about "private local
branching"?
44. Mercurial's bookmarks == Git's branches
Because both behave like pointers, they are private by
default and can be deleted without any trouble.
Mercurial repository cloned from source Git repository through hg-git
Git repository displaying all branches
45. Set phases to secret!
Mercurial phases help you to go into "private mode" since in Mercurial's
philosophy everything is public by default. In Git, things are private by default.
1 2 3
4
DEFAULT
MY_BRANCH 5
6
public
draft
7
secret
MY_SECRET_BRANCH
hg commit
hg phase --secret --force
1
2
Next commits are secret, so they
are not shared by default,
therefore you can safely run
destructive operations on such a
branch
hg commit3
46. Set phases to secret!
Secret changes are private, so nobody cares what you do to them. Make the
first commit in a branch secret and the branch will be secret from there on.
1 2 3
4
DEFAULT
MY_BRANCH 5
6
public
draft
7
secret
MY_SECRET_BRANCH
hg push1
Push won't share your
branch at this point!
47. Set phases to secret!
Finished with your branch and are confident about sharing it?, make the latest
commit in the branch (i.e. the head) public and the phase will back-propagate
1 2 3
4
DEFAULT
MY_BRANCH 5
6
public
draft
7
secret
MY_SECRET_BRANCH
hg push
hg phase --draft
1
3Liked your branch?, good! =D,
make it public, then push
hg update -r 72
Push won't share your
branch at this point!
hg push4
Push shares your
branch now!
48. Set phases to secret!
If your experiment didn't work or you just want to delete your branch, just do it.
If it is secret from the start you never pushed it, so don't worry about stripping
1 2 3
4
DEFAULT
MY_BRANCH 5
6
public
draft
7
secret
MY_SECRET_BRANCH
hg push1
Didn't like your branch?, just
leave it like that or delete it
hg strip -r 62
Push won't share your
branch at this point!
50. Conclusions
● Everybody branches and merges even without knowing
it
○ With anonymous branches
○ Merging is very frequent
○ ...and this information is taken into account for dealing with
conflicts
● Creating & merging branches does not affect others
○ This takes out the fear factor
○ Integration can happen away from the blessed repo, at several levels
● Branching becomes fun when experimenting locally
● Developers can do the integrator's work at a lower level