There've been several questions recently about skipping changes when maintaining release branches in Mercurial. For example:
- Mercurial: Branch specific changes keep coming back after dummy merge
- Why are Mercurial backouts in one branch affecting other branches?
Since it was introduced in 2.0, I've wondered about using graft
to avoid this problem. Given a revision tree like this:
A---B---C---D---E---F---G---H---I---J
Suppose we need to create a release branch that skips the Evil change E
.
hg update -r D
hg graft "F::J"
giving us:
A---B---C---D---E---F---G---H---I---J
\
--F'--G'--H'--I'--J'
- Q1: What just happened here? I can understand that
transplant
would have generated patches out ofF::J
, and then applied them ontoD
, butgraft
is said to use the 3-way merge rather than patches. So....... how does that work? Why is it better?
Lets say I now fix E
, and merge that into my release branch.
--E2-----------------
/ \
A---B---C---D---E---F---G---H---I---J---M1
\ \
--F'--G'--H'--I'--J'---------M2--
M1 is a straight merge; nothing special there. M2 is merging branches which have "the same" (or at least equivalent) changes on.
- Q2: Is this merge just a normal 3-way merge using
D
,J'
andM1
? - Q3: Has mercurial stored/used extra information about the graft operation to help it with the merge?
And finally...
- Q4: What are the potential problems with a flow like this?