Consequences of using graft in Mercurial
When you update to D
and graft F::J
, Mercurial runs a number of merges. It will start with this merge:
M = three_way_merge(local=D, other=F, base=E)
If we write +d
for the delta between the states C
and D
, then we start with:
+d +e +f
---- C ---- D ---- E ---- F ----
Turn the graph 90 degrees clockwise and the above three-way merge looks like this:
-e
.---- D
/
E
\
'---- F
+f
That is, we pretend that we started with E
and applied the opposite of -e
to get to D
. I think of as the reverse patch of +e
. Starting in E
we also went to state F
with the normal delta +f
. There's nothing strange here — we have all the states (D
, E
, and F
) in the repository already. So seen like this, it's clear that we can merge D
and F
.
Merging is a matter of "completing the diamond". So we find a new state M
that is a mix of D
and F
and where the difference from D
to M
is similar to +f
and the difference from F
to M
is similar to -e
. It looks like this:
-e +f'
.---- D ----.
/ \
E M
\ /
'---- F ----'
+f -e'
The +f
delta became +f'
and the -e
delta became -e'
. This is just a normal three-way merge, but the effect is interesting: we've applied F
onto D
instead of E
!
After the merge, the second parent of M
to F
is dropped:
-e +f'
.---- D ----.
/ \
E M
\
'---- F
+f
To reiterate: We have copied the "effect" of F
onto D
, that is, we have found a delta (+f'
) that applied to D
give the same effect as when +f
was applied to E
. We can straighten the graph a bit to get:
+f'
--- D ---- M
\
'---- E ---- F
+e +f
The result is that F
is grafted onto D
using the full three-way machinery.
-
Q1: What just happened here? So....... how does that work? Why is it better?
A1: Using merges is better than patches since the merge machinery takes things like renames into account.
-
Q2: Is this merge just a normal 3-way merge using D, J' and M1?
A2: Yes, grafting does not alter the topology of the graph.
-
Q3: Has mercurial stored/used extra information about the graft operation to help it with the merge?
A3: No.
-
Q4: What are the potential problems with a flow like this?
A4: From a merge perspective it should work okay. It will duplicate some history which might be confusing for people.
Q1: It helps when there are conflicts. You can use your usual merge tool then (for me it's inline conflict markers, which I edit with Emacs' smerge-mode).
Q2: It's a normal merge.
Q3: No.
Q4: I think it's ugly to have two almost identical branches.