Professional Documents
Culture Documents
Sergey Kishchenko
Quickoce
What every programmer should know about merging branches in Mercurial October 11, 2012
1 / 22
Branches
Two dierent branches Two dierent defaults
NOTE: Dierent repos cloned from one source are not actually dierent, they are essentially same repo. You can transfer changesets between them with push and pull IMPORTANT: Named branches in Mercurial are permanent!
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 2 / 22
Pull
First step in merge process: pulling remote changes > hg pull -b REMOTE_BRANCH REMOTE_REPO
Pulling change pulls also all its ancestors unneeded changes Pulling changes may result in creating new heads merge is needed Pulling branch pulls also all branches its based on merge is needed
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 3 / 22
Bad idea
Good idea
Having a specic x branch allows pulling this branch without pulling other changes (Feature A) You should think about it in advance and youre not a psychic
What every programmer should know about merging branches in Mercurial October 11, 2012
4 / 22
Fix A can be based on Feature A so patch will not apply smoothly SCM cant guess that Fix A and Fix B are actually the same and should be used as base when merging Fix C
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 5 / 22
graft uses 3-way merge and deals ne with Fix A being based on Feature A SCM still cant guess that Fix A and Fix A are actually the same and should be used as base when merging Fix C
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 6 / 22
graft doesnt deal with changesets from the remote repo at the moment because it needs all of the changes to do 3-way merge. But its possible to strip changes when they are not needed anymore grafting from remote repository > hg incoming --template="{node} " REMOTE_REPO -q \ -r GRAFT_REVISION > TEMP_FILE > hg pull -r GRAFT_REVISION REMOTE_REPO > hg graft --log GRAFT_REVISION > hg strip cat TEMP_FILE
What every programmer should know about merging branches in Mercurial October 11, 2012
7 / 22
What every programmer should know about merging branches in Mercurial October 11, 2012
8 / 22
What every programmer should know about merging branches in Mercurial October 11, 2012
9 / 22
Merge
Merging dierent branches > hg co local_branch > hg merge remote_branch > hg ci -m merge Merging heads in default branch > hg merge (while in default branch) > hg ci -m merge
Looks easy, huh? But it is not easy at all because of possible conicts
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 11 / 22
How to prevent?
Synchronize often Simplify connections between components Design clear and minimalistic API Notify other developers of the component when doing changes Dont exceed the reasonable amount of developers for one component Do not store autogenerated code in the tree
3-way merge
Base (B) line1 Local (L) line1 line2 Merged (M) line1 modified line2 Remote (R) line1 modified
Without base its hard to merge Local and Remote les: its hard to understand was it a removal of line2 and addition of modied or removal of modied and addition of line2 use a 3-way graphical merge tool Subjective choice: http://mercurial.selenic.com/wiki/KDiff3
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 13 / 22
resolve command
Imagine you need to merge a lot of changes Bad idea > hg merge # non-stop merging, here I come! Good idea
> > > > hg hg hg hg merge -t "internal:merge" # does the best it can automatically resolve -l # shows merge state resolve FILE # runs conflict resolving for specific file resolve -a # runs conflict resolving for all unresolved files
IMPORTANT: Unfortunately, resolve command doesnt save progress when interrupted. There is an issue for that: http://bz.selenic.com/show_bug.cgi?id=3638. Possible workaround: iterate through conicts and call resolve for each le
Sergey Kishchenko (Quickoce) What every programmer should know about merging branches in Mercurial October 11, 2012 14 / 22
How to prevent?
Synchronize often Spread the components knowledge among developers code cross-review
What every programmer should know about merging branches in Mercurial October 11, 2012
15 / 22
How to prevent?
Spread the ongoing refactoring knowledge among developers code cross-review Use early-x branch for refactoring and merge it immediately or notify everyone about it
Use 3-way merge graphical tool to see base(B), local(L) and remote(R) version of a le Lets assume refactoring was done only in remote. It means that base-local dierence is not large, its all about modifying names, adding params, issues x, etc. Base and remote dier a lot, often the remote version is completely missing, i.e., was moved to dierent le. Use log to identify what was refactoring about. E.g., you can nd the le that is a new home for the code that is missing from the R
Iterate through base-local dierences change by change and apply them to the code in a correct place In any case consider contacting those who did the refactoring for help and/or code review
What every programmer should know about merging branches in Mercurial October 11, 2012 17 / 22
How to prevent?
Avoid pointless modication of non-source les Consider using an early-x branch for non-source le modication and merge it into all branches immediately Do not store user settings in the tree Consider storing mergeable sources instead of the non-source products
Manual merges Applying patches manually Being a coward and selecting either local or remote version without checking it Trusting automatic merge tools completely Using bad names for branches Using --force ag Copying and moving les without using hg cp/hg mv
What every programmer should know about merging branches in Mercurial October 11, 2012
20 / 22
Doing a refactoring that cant be merged into all branches immediately Modifying non-source le without merging it into all branches immediately Modifying a component that somebody is working on without notifying this person Storing autogenerated code and user settings in the code tree Using branches without bookmarking or naming them Committing all of the changes in one changeset
What every programmer should know about merging branches in Mercurial October 11, 2012
21 / 22
What every programmer should know about merging branches in Mercurial October 11, 2012
22 / 22