10 An intrinsic contradiction |
10 An intrinsic contradiction |
11 ----------------------------------- |
11 ----------------------------------- |
12 |
12 |
13 XXX starts by talking about getting ride of changeset. |
13 XXX starts by talking about getting ride of changeset. |
14 |
14 |
15 DVCSes bring two new major concepts to the Version Control Scene: |
15 DVCSes bring two new major concepts to the version control scene: |
16 |
16 |
17 * History is organized as a robust DAG, |
17 * History is organized as a robust DAG, |
18 * History can be rewritten. |
18 * History can be rewritten. |
19 |
19 |
20 However, the two concepts are in contradiction: |
20 However, the two concepts are in contradiction: |
21 |
21 |
22 To achieve a robust history, three key elements are gathered in *changesets*: |
22 To achieve a robust history, three key elements are gathered in *changesets*: |
23 |
23 |
24 * Full snapshot of the versioned content, |
24 * Full snapshot of the versioned content, |
25 * Reference to the previous full snapshot used to build the new one, |
25 * Reference to the previous full snapshot used to build the new one, |
26 * A description of the change who lead from the old content to the new old. |
26 * A description of the change which leads from the old content to the new content. |
27 |
27 |
28 All three elements are to compute a *unique* hash that identify the changeset |
28 All three elements are used to compute a *unique* hash that identifies the changeset |
29 (with various other metadata). This identification is a key part of DVCS design. |
29 (with various other metadata). This identification is a key part of DVCS design. |
30 |
30 |
31 This is a very useful property because Changing B parent means |
31 This is a very useful property because changing B's parent means |
32 changing B content too. This requires the creation of **another** |
32 changing B's content too. This requires the creation of **another** |
33 changeset, which is semantically good. |
33 changeset, which is semantically good. |
34 |
34 |
35 .. figure:: ./figures/edit-is-rewrite-step2.svg |
35 .. figure:: ./figures/edit-is-rewrite-step2.svg |
36 |
36 |
37 |
37 |
38 To avoid duplication, the older changeset is usually discarded from accessible |
38 To avoid duplication, the older changeset is usually discarded from accessible |
39 history. I'm calling them *obsolete* changesets. |
39 history. I'm calling them *obsolete* changesets. |
40 |
40 |
41 |
41 |
42 But rewriting a changeset with children does not change these |
42 But rewriting a changeset with children does not change the |
43 children's parent! And because children of the rewritten changeset |
43 children's parents! And because children of the rewritten changeset |
44 still **depend** on the older "dead" version of the changeset with |
44 still **depend** on the older "dead" version of the changeset, we |
45 can not get rid of this dead version. |
45 cannot get rid of this dead version. |
46 |
46 |
47 :: |
47 :: |
48 |
48 |
49 Schema base, A and A' and B. |
49 Schema base, A and A' and B. |
50 |
50 |
51 I'm calling these children **unstable** because they are based on a |
51 I'm calling these children **unstable** because they are based on a |
52 dead changeset and prevent people to get rid of it. |
52 dead changeset and prevent people from getting rid of it. |
53 |
53 |
54 This instability is an **unavoidable consequence** of the strict dependency of |
54 This instability is an **unavoidable consequence** of the strict dependency of |
55 changeset. History Rewriting history alway need to take it in account and |
55 changesets. Rewriting history always needs to take it into account and |
56 provide a way to rewrite the descendant on the new changeset to avoid |
56 provide a way to rewrite the descendants of the new changeset to avoid |
57 coexistence of the old and new version of a rewritten changeset. |
57 coexistence of the old and new versions of a rewritten changeset. |
58 |
58 |
59 |
59 |
60 Everybody is working around the issue |
60 Everybody is working around the issue |
61 ------------------------------------------------ |
61 ------------------------------------------------ |
62 |
62 |
63 I'm not claiming that rewriting history is impossible. People are successfully |
63 I'm not claiming that rewriting history is impossible. People have been successfully |
64 doing for years. However they all need to work around *instability*. Several |
64 doing it for years. However they all need to work around *instability*. Several |
65 work around strategy exists. |
65 workaround strategies exist. |
66 |
66 |
67 |
67 |
68 Rewriting all at once |
68 Rewriting all at once |
69 `````````````````````````` |
69 `````````````````````````` |
70 |
70 |
77 :: |
77 :: |
78 |
78 |
79 Schema! |
79 Schema! |
80 |
80 |
81 Several Mercurial commands apply it: rebase, collapse, histedit. |
81 Several Mercurial commands apply it: rebase, collapse, histedit. |
82 Mercurial also refuses to amend changeset with descendant. The git |
82 Mercurial also refuses to amend changesets with descendants. The git |
83 branch design enforces such approach in git too. |
83 branch design enforces this approach in git too. |
84 |
84 |
85 |
85 |
86 However, DVCS are **Distributed**. This means that you do not control what |
86 However, DVCS are **distributed**. This means that you do not control what |
87 happen outside your repository. Once a changeset have been exchanged *outside*, |
87 happens outside your repository. Once a changeset has been exchanged *outside*, |
88 there is no way to be sure it does not have descendants somewhere else. |
88 there is no way to be sure it does not have descendants somewhere else. |
89 Therefore **if you rewrite changeset that exists elsewhere, you can't eradicate |
89 Therefore **if you rewrite changeset that exists elsewhere, you can't eradicate |
90 the risk of instability.** |
90 the risk of instability.** |
91 |
91 |
92 Do not rewrite exchanged changeset |
92 Do not rewrite exchanged changesets |
93 ``````````````````````````````````` |
93 ``````````````````````````````````` |
94 |
94 |
95 To work around the issue above, Mercurial introduced phases, which |
95 To work around the issue above, Mercurial introduced phases, which |
96 prevent you from rewriting shared changesets and ensure others can't |
96 prevent you from rewriting shared changesets and ensure others can't |
97 pull certain changesets from you. But this is a very frustrating |
97 pull certain changesets from you. But this is a very frustrating |
98 limitation that prevents you to efficiently sharing, reviewing and |
98 limitation that prevents you to efficiently sharing, reviewing and |
99 collaborating on mutable changesets. |
99 collaborating on mutable changesets. |
100 |
100 |
101 In the Git world, they use another approach to prevent instability. By |
101 In the Git world, they use another approach to prevent instability. By |
102 convention only a single developper works on a changeset contained in |
102 convention only a single developer works on a changeset contained in |
103 a named branch. But once again this is a huge blocker for |
103 a named branch. But once again this is a huge blocker for |
104 collaborating. Moreover clueless people **will** mess up social |
104 collaborating. Moreover clueless people **will** mess up social |
105 convention soon or later. |
105 convention soon or later. |
106 |
106 |
107 |
107 |
108 Loose the DAG robustness |
108 Lose the DAG robustness |
109 ```````````````````````````` |
109 ```````````````````````````` |
110 |
110 |
111 The other approach in Mercurial is to keep the mutable part of the |
111 The other approach in Mercurial is to keep the mutable part of the |
112 history outside the DVCS constraint. This is the MQ approach of |
112 history outside the DVCS constraint. This is the MQ approach of |
113 sticking a quilt queue over Mercurial. |
113 sticking a quilt queue over Mercurial. |
114 |
114 |
115 This allow much more flexible workflow but two major feature are lost in the |
115 This allow much more flexible workflow but two major feature are lost in the |
116 process: |
116 process: |
117 |
117 |
118 :graceful merge: MQ use plain-patch to store changeset content and patch have |
118 :graceful merge: MQ uses plain patch to store changeset contents, which has |
119 trouble to apply in changing context. Applying your queue |
119 problems in changing context. Applying your queue |
120 becomes very painful when context changes. |
120 becomes very painful when context changes. |
121 |
121 |
122 :easy branching: A quilt queue is by definition a linear queue. Increasing risk |
122 :easy branching: A quilt queue is by definition a linear queue, increasing risk |
123 of conflict |
123 of conflict. |
124 |
124 |
125 It is possible to collaborate over versioned mq! But you are going to |
125 It is possible to collaborate over versioned MQ! But you are going to |
126 have a lot of troubles. |
126 have a lot of trouble. |
127 |
127 |
128 Ignore conflicts |
128 Ignore conflicts |
129 ``````````````````````````````````` |
129 ``````````````````````````````````` |
130 |
130 |
131 Another ignored issue is a conflicting rewrite of the same changeset. |
131 Another ignored issue is a conflicting rewrite of the same changeset. |
135 Mercurial work around by |
135 Mercurial work around by |
136 |
136 |
137 The "One set of mutable changset == One developer" mantra is also a way to work |
137 The "One set of mutable changset == One developer" mantra is also a way to work |
138 around conflicting rewriting of changeset. If two different people are able to |
138 around conflicting rewriting of changeset. If two different people are able to |
139 |
139 |
140 The git branch model allow to overwrite changeset version by another |
140 The git branch model allows overwriting changeset version by another |
141 one, but it does not care about divergent version. It is the equivalent |
141 one, but it does not care about divergent version. It is the equivalent |
142 of "common ftp" source management for changesets. |
142 of "common ftp" source management for changesets. |
143 |
143 |
144 Facing The Danger Once And For All |
144 Facing The Danger Once And For All |
145 ------------------------------------------------ |
145 ------------------------------------------------ |
146 |
146 |
147 Above we saw that, the more effort you put to avoid instability, the more option |
147 Above we saw that the more effort you put to avoid instability, the more options |
148 you deny. And even most restrictive work flow can't guarantee that instability |
148 you deny. And even the most restrictive workflow can't guarantee that instability |
149 will never show up! |
149 will never show up! |
150 |
150 |
151 Obsolete marker can handle the job |
151 Obsolete marker can handle the job |
152 ``````````````````````````````````` |
152 ``````````````````````````````````` |
153 |
153 |
154 It is time to provide a full featured solution to deal with |
154 It is time to provide a full-featured solution to deal with |
155 instability and to stop working around the issue! This is why I |
155 instability and to stop working around the issue! This is why I |
156 developing a new feature for mercurial called "Obsolete markers". |
156 am developing a new feature for Mercurial called "Obsolete markers". |
157 Obsolete markers have two key properties: |
157 Obsolete markers have two key properties: |
158 |
158 |
159 |
159 |
160 * Any "old" changeset we want to get ride of is **explicitly** marked |
160 * Any "old" changeset we want to get rid of is **explicitly** marked |
161 as "obsolete" by history rewriting operation. |
161 as "obsolete" by history rewriting operations. |
162 |
162 |
163 By explicitly marking the obsolete part of the history, we will be able to |
163 By explicitly marking the obsolete part of the history, we will be able to |
164 easily detect instability situation. |
164 easily detect instability situation. |
165 |
165 |
166 * Relations between old and new version of changesets are tracked by obsolete |
166 * Relations between old and new version of changesets are tracked by obsolete |
167 markers. |
167 markers. |
168 |
168 |
169 By Storing a meta-history of changeset evolution we are able to easily resolve |
169 By storing a meta-history of changeset evolution we are able to easily resolve |
170 instability and edition conflict [#]_ . |
170 instability and edit conflicts [#]_ . |
171 |
171 |
172 .. [#] edition conflict is another major obstable to collaboration. See the |
172 .. [#] Edit conflicts is another major obstable to collaboration. See the |
173 section dedicated to obsolete marker for details. |
173 section dedicated to obsolete marker for details. |
174 |
174 |
175 Improves robustness == improves simplicity |
175 Improved robustness == improved simplicity |
176 ```````````````````````````````````````````````` |
176 ```````````````````````````````````````````````` |
177 |
177 |
178 This proposal should **first** be seen as a safety measure. |
178 This proposal should **first** be seen as a safety measure. |
179 |
179 |
180 It allow to detect instability as soon as possible |
180 It allows detecting instability as soon as possible. |
181 |
181 |
182 :: |
182 :: |
183 |
183 |
184 $ hg pull |
184 $ hg pull |
185 added 3 changeset |
185 added 3 changeset |