Merging hellBranching is good, until you forget to merge early. Branch way more and youwill be merging more frequently and with less bad consequences.1 2 3 4 1265 94 ?Uh, oh!... long-lived branches
or why merging has to kick-ass by designWhy are branchesimportant to DVCSs?
Saved a new change?congratulations... you also created a new branch (one per clone)Blessed RepositoryClonesClone AClone BClone C1 2 33 4 53 4 5 63 4T I M Ecloning happens three times at revision 3
Now how do I get my work back to the main repository?well, you merge1 2 3 A:4 A:5B:4 B:5 B:6TIMEB:7*C:4 C:5*New commit after mergingBlessed RepositorymergemergebranchbranchFirst one to push back will not create a branch
And if I dont want to merge?...you dont, but you create heads1 2 3 A:4 A:5B:4 B:5 B:6TIMEC:4HeadsBlessed RepositoryEverything being worked at the default branch(can be considered as a "trunk")
If these are branches, how comethey 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 dont 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
cloning, named, anonymous, bookmarksTypes of branching
(aka the lazy/incorrect way to branch)Clone to branch
Using clonesNot really recommended as real branching, but is easy to cleanupLocal Repository Clones for experimentingClone AClone BClone C1 2 33 4 53 4 5 63 4
Cloning to branch● Not remotely recommended as it can be just asconvenient 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 waitfor the 2-3 second update)● Understand it, but preferably dont do it
How do you create one?name it, then commit it1 2 45DEFAULThg commithg update defaulthg branch my_branch231MY_BRANCHhg update my_branch4Executing hg branches should list "default" and "my_branch"Executing hg branch should display the current branch as "my_branch" after 4
How do you merge them?Easy as 1-2-31 2 45DEFAULTMY_BRANCH 6Do 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_branch1hg merge default2hg commit3
What do you do when you finish with it?just add the --close-branch option when you commit1 2 45DEFAULThg commit --close-branch1MY_BRANCH 6 7my_branch will no longer be listed in hg branches, but youcan reopen it by creating a new normal commit
Named branches● Standard way of branching● Branches always get all pushed at the same time unlessspecified● Recommendable to have a branch policy and/or namingconvention, e.g.:○ Types:■ Bugfix branches should pull frequently from the baseline and beshort-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
Anonymous branching● The branches that just happen bythemselves.● Can be made intentionally/forcefully bychanging to a past revision and committingfrom it● Anonymous branches can be counted bycounting named branches and subtractingthe number of heads● Heads can be unmade easily (merge)● Not very sane to do anonymous branchinglocally
Making anonymous branching saneand they can be private (i.e. not pushed by default)1 3 45DEFAULThg commithg update -r 3hg commit123hg bookmark my_stuff4my_stuff
And using them is as easy as with named branchesanonymous branches without having to track revision numbers1 3 45DEFAULThg update default5hg update my_stuff6my_stuff5hg commit7the "my_stuff"bookmark movesautomatically whenyou commit...updating to a branch...updating to a bookmark
Bookmarks● A good local replacement for gits "private localbranching"○ 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
No need to worry about them, 99% of thetime, but you should understand what theymeanHeads
Dont lose your heads...because there should be one head per branch (anonymous or named)1 2 45DEFAULTMY_BRANCHExecuting hg heads should list 4 & 5 as headsheads
Having 1+ heads in a named branch means there are pending mergesprobably someone used hg push -f, and you should go hit them on the head(the one above their shoulders)1 2 45DEFAULTMY_BRANCHExecuting hg heads should list 4, 6 & 7 as heads,6 & 7 belonging to my_branchheads67
Having a merged head in a given branch means the branch is inactive...meaning it is abandoned, since its changes are no longer unique to thenamed branch (aka has no new code)1 2 45DEFAULTMY_BRANCHExecuting hg branches should mark my_branch as "inactive"Committing again on my_branch makes the branch active againheads6inactive branch
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 andmerging the common baseline into it as often aspossible. 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
Feature branching● Benefits:○ Code-review is easy, even if you decided to do manycommits○ All your changes are "pull-request" ready in such away that is easier to think about (and evendocument)○ You can multi-task and use branches to stashawayyour 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 livewithout them (oh... yeah, copy/pasting your project directory)
... I want private local branching like in GitWhat about "private localbranching"?
Mercurials bookmarks == Gits branchesBecause both behave like pointers, they are private bydefault and can be deleted without any trouble.Mercurial repository cloned from source Git repository through hg-gitGit repository displaying all branches
Set phases to secret!Mercurial phases help you to go into "private mode" since in Mercurialsphilosophy everything is public by default. In Git, things are private by default.1 2 34DEFAULTMY_BRANCH 56publicdraft7secretMY_SECRET_BRANCHhg commithg phase --secret --force12Next commits are secret, so theyare not shared by default,therefore you can safely rundestructive operations on such abranchhg commit3
Set phases to secret!Secret changes are private, so nobody cares what you do to them. Make thefirst commit in a branch secret and the branch will be secret from there on.1 2 34DEFAULTMY_BRANCH 56publicdraft7secretMY_SECRET_BRANCHhg push1Push wont share yourbranch at this point!
Set phases to secret!Finished with your branch and are confident about sharing it?, make the latestcommit in the branch (i.e. the head) public and the phase will back-propagate1 2 34DEFAULTMY_BRANCH 56publicdraft7secretMY_SECRET_BRANCHhg pushhg phase --draft13Liked your branch?, good! =D,make it public, then pushhg update -r 72Push wont share yourbranch at this point!hg push4Push shares yourbranch now!
Set phases to secret!If your experiment didnt work or you just want to delete your branch, just do it.If it is secret from the start you never pushed it, so dont worry about stripping1 2 34DEFAULTMY_BRANCH 56publicdraft7secretMY_SECRET_BRANCHhg push1Didnt like your branch?, justleave it like that or delete ithg strip -r 62Push wont share yourbranch at this point!
Conclusions● Everybody branches and merges even without knowingit○ With anonymous branches○ Merging is very frequent○ ...and this information is taken into account for dealing withconflicts● 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 integrators work at a lower level