1185.1.29
by Robert Collins
merge merge tweaks from aaron, which includes latest .dev |
1 |
**************** |
2 |
Joining branches |
|
3 |
**************** |
|
4 |
||
5 |
(I think this is pretty brilliant. :-) |
|
6 |
||
7 |
Branches diverge when people create more than one changeset following |
|
8 |
on from a common ancestor:: |
|
9 |
||
10 |
A: 0 ------- 1 |
|
11 |
B: \------- 2 |
|
12 |
||
13 |
We also allow branches to reunite. This means that all the decisions |
|
14 |
taken on multiple branches have been reconciled and unified into a |
|
15 |
single successor:: |
|
16 |
||
17 |
A: 0 ------- 1 ----- 3 |
|
18 |
\ / |
|
19 |
B: \------ 2 ----/ |
|
20 |
||
21 |
The predecessor of 3 is 1, in the sense that it was created on that |
|
22 |
branch. We could have created the exact same state as a successor to |
|
23 |
2, and we can move that state onto branch 2 without any loss of |
|
24 |
information. |
|
25 |
||
26 |
(One thing we can do here is just delete B. Because all of the work |
|
27 |
there has been merged onto A, this will not lose anything. We might |
|
28 |
do this if the purpose of B has been achieved, such as completing a |
|
29 |
feature or bug. But if the work is still in progress, we might keep |
|
30 |
it around. It makes little difference whether we decide to do new |
|
31 |
work in a branch called B or make a new one called C.) |
|
32 |
||
33 |
That is to say that 3 can be perfectly (trivially) merged onto B, |
|
34 |
with, say ``bzr push``, ``bzr pull`` or ``bzr update`` (whatever name |
|
35 |
works best). Perfectly merged means that we know there will be no |
|
36 |
conflicts or need for manual intervention, and that we can just |
|
37 |
directly store it without forming a roll-up changeset. |
|
38 |
||
39 |
I think we might also like the choice of merging A onto B, rather than |
|
40 |
pulling the changeset. That causes a new changeset to be created on |
|
41 |
B, noted as a successor of 2 and 3:: |
|
42 |
||
43 |
A: 0 ------- 1 ----- 3 ------+ |
|
44 |
\ / \ |
|
45 |
B: \------ 2 ----+---------- 4 |
|
46 |
||
47 |
One complication is that 3 is probably stored in A's history as a |
|
48 |
patch relative to 1; we can't just move this representation across. |
|
49 |
Instead, we need to recalculate the delta from 2 to 3 and store that. |
|
50 |
||
51 |
Despite that the delta is stored differently, the original signature |
|
52 |
on 3 should still be valid. So it must be a signature of the tree |
|
53 |
state, not the diff. |
|
54 |
||
55 |
Note from `Kernel Traffic discussion`__: |
|
56 |
||
57 |
__ http://www.kerneltraffic.org/kernel-traffic/kt20030323_210.txt |
|
58 |
||
59 |
But anyway, what made Bitkeeper suck less is the real DAG |
|
60 |
structure. Neither arch (http://arch.fifthvision.net/bin/view) |
|
61 |
nor subversion seem to have understood that and, as a result, |
|
62 |
don't and won't provide the same level of semantics. Zero hope for |
|
63 |
Linus to use them, ever. They're needed for any decently |
|
64 |
distributed development process. |
|
65 |
||
66 |
This in turn suggests that possibly deltas should be stored separately |
|
67 |
from the commits that create them. Commits name points of |
|
68 |
development; deltas describe how to get from one to the other. |
|
69 |
||
70 |
The separation is nice in allowing us to send just a delta when |
|
71 |
diffing trees or recording for undo. We might want to compute many |
|
72 |
deltas between different trees. |
|
73 |
||
74 |
Is this a problem? Does this ignore Tom's advice about the primacy of |
|
75 |
storing changesets? |
|
76 |
||
77 |
Splitting them is probably good, but then what manifest is stored in |
|
78 |
changesets? We don't want to store the manifest of the whole tree if |
|
79 |
we can avoid it. So I suppose the changeset just gives the hash of |
|
80 |
the manifest, and the manifest then can be stored separately, possibly |
|
81 |
delta-encoded. |