Mercurial > evolve
comparison docs/obs-concept.rst @ 175:f86ed5a82723
docs: some fixes on the index and the first half of the obsolete concepts.
author | Arne Babenhauserheide <bab@draketo.de> |
---|---|
date | Tue, 27 Mar 2012 18:35:18 +0200 |
parents | 8f8a52cd0b9f |
children | 4da5ecfb5d41 |
comparison
equal
deleted
inserted
replaced
170:7151691b85ef | 175:f86ed5a82723 |
---|---|
1 ----------------------------------------------------------- | 1 ============================== |
2 Why Do We Need a New Concept | 2 Why Do We Need a New Concept |
3 ----------------------------------------------------------- | 3 ============================== |
4 | 4 |
5 Current DVCS are great tool to forge a series of flawless changeset on your own. | 5 Current DVCS are great tool to forge a series of flawless changeset on your own. |
6 But they perform poorly whe is comes to **share** work in progress and | 6 But they perform poorly when is comes to **share** work in progress and |
7 **collaborate** on such work in progress. | 7 **collaborate** on such work in progress. |
8 | 8 |
9 When people forge new version of a changeset they create a new changeset and get | 9 When people forge new version of a changeset they create a new changeset and get |
10 ride of the original changeset. Difficultis to collaborate mostly came from the | 10 ride of the original changeset. Difficulties to collaborate mostly came from the |
11 way old content are *removed* from repository. | 11 way old content are *removed* from repository. |
12 | 12 |
13 Mercurial Approach: Strip | 13 Mercurial Approach: Strip |
14 ----------------------------------------------------- | 14 ========================= |
15 | 15 |
16 With current version of mercurial, every changesets that exist in your | 16 With current version of mercurial, every changesets that exist in your |
17 repository are *visible* and *meaningful*. To get ride of old changeset you | 17 repository are *visible* and *meaningful*. To get ride of old changeset you |
18 rewrote mercurial remove them from the repository storage. with an operation | 18 rewrote mercurial remove them from the repository storage. with an operation |
19 called *strip*. After the *strip* the repository looks like if the changeset | 19 called *strip*. After the *strip* the repository looks like if the changeset |
20 never existed. | 20 never existed. |
21 | 21 |
22 This approach is simple and effective but have a very big drawnback: You can | 22 This approach is simple and effective but have a very big drawback: You can |
23 remove changesets from **your repository only**. If strip exists in other | 23 remove changesets from **your repository only**. If strip exists in other |
24 repositories it will show of again and again. This only cure for this is to | 24 repositories it will show of again and again. This only cure for this is to |
25 strip the offending changeset from all repository. And operation at best | 25 strip the offending changeset from all repository. And operation at best |
26 impractical and in most case impossible! | 26 impractical and in most case impossible! |
27 | 27 |
28 | 28 |
29 As consequence, **you can not rewrite something once you exchange it with | 29 As consequence, **you can not rewrite something once you exchange it with |
30 others**. The old version will still exists along side the new one [#]_. | 30 others**. The old version will still exists along side the new one [#]_. |
31 | 31 |
32 Moreover backup are create stripped changeset in most case. This allow | 32 Moreover stripping changesets creates backup bundles. This allows |
33 restoration of old changeset but the process is painful. | 33 restoration of the deleted changesets, but the process is painful. |
34 | 34 |
35 Finally, as the repository format is not optimized for deletion. stripping a | 35 Finally, as the repository format is not optimized for deletion. stripping a |
36 changeset may be slow in some situation. | 36 changeset may be slow in some situations. |
37 | |
38 | 37 |
39 To sum up, the strip approach is very simple but does not handle interaction | 38 To sum up, the strip approach is very simple but does not handle interaction |
40 with the outer world. Which is unfortunate for a *Distributed* VCS. | 39 with the outer world. Which is unfortunate for a *Distributed* VCS. |
41 | 40 |
42 .. [#] various work around exists but they are work around with their own flow. | 41 .. [#] various work around exists but they require their own workflows which are distinct from the very elegant basic workflow of Mercurial. |
43 | 42 |
44 Git Approach: Overwrite Reference | 43 Git Approach: Overwrite Reference |
45 ----------------------------------------------------- | 44 ================================= |
46 | 45 |
47 Git approach for repository is a bit more complex: They can be any amount of | 46 Git approach for repository is a bit more complex: Any number of |
48 changeset can exist in a repository. but **only changesets referenced by a git | 47 changesets can exist in a repository. but **only changesets referenced by a git |
49 branch** are *visible* and *meaningful*. | 48 branch** are *visible* and *meaningful*. |
50 | 49 |
51 | 50 |
52 .. warning:: add a schema:: | 51 .. warning:: add a schema:: |
53 | 52 |
57 | | 56 | |
58 A | 57 A |
59 | 58 |
60 Only B and A are visible. | 59 Only B and A are visible. |
61 | 60 |
62 This ease the process of getting ride of old changeset. You can just leave them | 61 This simplifies the process of getting rid of old changesets. You can |
63 in place and move the reference on the new one. You can then propagate those | 62 just leave them in place and move the reference on the new one. You |
64 change by moving the git-branch on remote host, newer version overwritting the | 63 can then propagate that change by moving the git-branch on remote host |
65 older one. | 64 with the newer version of the marker overwriting the older one. |
66 | 65 |
67 This approach goes a bit further but still have major drawback: | 66 This approach goes a bit further but still has a major drawback: |
68 | 67 |
69 | 68 |
70 Because you **overwrite** git-branch you have no conflit resolution. The last | 69 Because you **overwrite** the git-branch, you have no conflict resolution. The last |
71 to spoke win. This make collaboration on multiple changeset difficult because | 70 to act wins. This makes collaboration on multiple changesets difficult because |
72 you can't merge concurent update on changeset. | 71 you can't merge concurrent updates on a changeset. |
73 | 72 |
74 Every overwrite is forced operation where the operator say "Yes I want this to | 73 Every overwrite is a forced operation where the operator say "Yes I want this to |
75 replace that. On higly distributed environment user may end with conflicting | 74 replace that. In highly distributed environments, a user may end up with conflicting |
76 reference with and no proper way to choose. | 75 references and no proper way to choose. |
77 | 76 |
78 Because of this way to visualize a repository, git-branches are a very core | 77 Because of this way to visualize a repository, git-branches are a core |
79 part of git. This make user interface more complicated and move through history | 78 part of git, which makes the user interface more complicated and |
80 more constrainted. | 79 constrains the ways to move through history. |
81 | 80 |
82 Finally, even if all older changeset still exist in the repository acces to them | 81 Finally, even if all older changeset still exist in the repository, access to them |
83 is still painful. | 82 is still painful. |
84 | 83 |
85 | 84 |
86 ----------------------------------------------------- | 85 ============================= |
87 The Obsolete Marker Concept | 86 The Obsolete Marker Concept |
88 ----------------------------------------------------- | 87 ============================= |
89 | 88 |
90 | 89 |
91 | 90 |
92 | 91 |
93 | 92 |
94 As None of the concept was powerful enough to embrace the need to safely rewrite | 93 As None of the concepts was powerful enough to fulfill the need of safely rewriting |
95 history, easily share and collaborate on mutable history we needed another one. | 94 history, including easy sharing and collaborating on mutable history, we needed another one. |
96 | 95 |
97 | 96 |
98 | 97 |
99 Basic concept | 98 Basic concept |
100 ----------------------------------------------------- | 99 ============= |
101 | 100 |
102 | 101 |
103 Every history rewriting operation stores the information that old rewritten | 102 Every history rewriting operation stores the information that the old rewritten |
104 changesets has newer version available in a set of changeset. | 103 changeset is replaced by newer version in a given set of changeset. |
105 | 104 |
106 All basic history rewriting operation can create a appropriate obsolete marker. | 105 All basic history rewriting operation can create an appropriate obsolete marker. |
107 | 106 |
108 | 107 |
109 .. figure:: ./figures/example-1-update.* | 108 .. figure:: ./figures/example-1-update.* |
110 | 109 |
111 *Updating* a changeset | 110 *Updating* a changeset |
145 | 144 |
146 To conclude, a single obsolete marker express a relation from **0..n** new | 145 To conclude, a single obsolete marker express a relation from **0..n** new |
147 changesets to **1** old changeset. | 146 changesets to **1** old changeset. |
148 | 147 |
149 Basic Usage | 148 Basic Usage |
150 ----------------------------------------------------- | 149 =========== |
151 | 150 |
152 Obsolete markers create a perpendicular history: **a versionned version of the | 151 Obsolete markers create a perpendicular history: **a versioned changeset graph**. This means that offers the same features we have for |
153 changeset graph**. This means that we can have the same feature we have for | |
154 versioned files but applied to changeset: | 152 versioned files but applied to changeset: |
155 | 153 |
156 First: we can display a **coherent view** of the history graph with only a | 154 First: we can display a **coherent view** of the history graph in which only a |
157 single version of your changeset are displayed by the UI. | 155 single version of your changesets are displayed by the UI. |
158 | 156 |
159 Second, because obsolete changeset content are still **available**. You can | 157 Second, because obsolete changeset content is still **available**. You can |
160 | 158 |
161 * **browse** the content of your obsolete commit, | 159 * **browse** the content of your obsolete commit, |
162 | 160 |
163 * **compare** newer and older version of a changeset, | 161 * **compare** newer and older version of a changeset, |
164 | 162 |
171 Conflicting history rewriting operation can be detected and **resolved** as easily | 169 Conflicting history rewriting operation can be detected and **resolved** as easily |
172 as conflicting changes on file. | 170 as conflicting changes on file. |
173 | 171 |
174 | 172 |
175 Detecting and solving tricky situation | 173 Detecting and solving tricky situation |
176 ----------------------------------------------------- | 174 ====================================== |
177 | 175 |
178 History rewriting can lead to complex situation. Obsolete marker introduce a | 176 History rewriting can lead to complex situations. Obsolete marker introduce a |
179 simple representation this complex reality. But people using complex workflow | 177 simple representation of this complex reality. But people using complex workflows |
180 will one day or another you have to face the intrinsics complexity of some | 178 will one day or another have to face the intrinsic complexity of some |
181 situation. | 179 situations. |
182 | 180 |
183 This section describe possible situations, define precise set of changesets | 181 This section describes possible situations, defines precise sets of changesets |
184 involved in such situation and explains how error case can we automatically | 182 involved in such situations and explains how error cases can automatically be |
185 resolved using available information. | 183 resolved using available information. |
186 | 184 |
187 | 185 |
188 obsolete changesets | 186 obsolete changesets |
189 ```````````````````` | 187 ------------------- |
190 | 188 |
191 Old changesets left behind by obsolete operation are said **obsolete**. | 189 Old changesets left behind by obsolete operation are called **obsolete**. |
192 | 190 |
193 With current version of mercurial, this *obsolete* part is stripped from the | 191 With the current version of mercurial, this *obsolete* part is stripped from the |
194 repository before the end of every rewritting operation. | 192 repository before the end of every rewriting operation. |
195 | 193 |
196 .. figure:: ./figures/error-obsolete.* | 194 .. figure:: ./figures/error-obsolete.* |
197 | 195 |
198 Rebasing `B` and `C` on `A` (as `B'`, `C'`) | 196 Rebasing `B` and `C` on `A` (as `B'`, `C'`) |
199 | 197 |
200 This rebase operation added two obsolete markers from new changesets to old | 198 This rebase operation added two obsolete markers from new changesets to old |
201 changesets. These Two old changesets are now part of the *obsolete* part of the | 199 changesets. These two old changesets are now part of the *obsolete* part of the |
202 history. | 200 history. |
203 | 201 |
204 In most case the obsolete set will be fully hidden to both UI and discovery so | 202 In most cases, the obsolete set will be fully hidden to both UI and discovery so |
205 user do not have to care about them unless he wants to audit history rewriting | 203 the user does not have to care about them unless he wants to audit the history rewriting |
206 operation. | 204 operation. |
207 | 205 |
208 Unstable changesets | 206 Unstable changesets |
209 ``````````````````` | 207 ------------------- |
210 | 208 |
211 While exploring obsolete marker possibility a bit further you way end up with | 209 While exploring the possibilities of the obsolete a bit further, you may end up with |
212 *obsolete* changeset with *non-obsolete* children. There is two common ways to | 210 *obsolete* changeset which have *non-obsolete* children. There is two common ways to |
213 achieve this: | 211 achieve this: |
214 | 212 |
215 * Pull a changeset based of an old version of a changeset [#]_. | 213 * Pull a changeset based of an old version of a changeset [#]_. |
216 | 214 |
217 * Use a partial rewriting operation. For example amend on a changeset with | 215 * Use a partial rewriting operation. For example amend on a changeset with |
218 childrens. | 216 children. |
219 | 217 |
220 *Non-obsolete* changeset based on *obsolete* one are said **unstable** | 218 *Non-obsolete* changeset based on *obsolete* one are said **unstable** |
221 | 219 |
222 .. figure:: ./figures/error-unstable.* | 220 .. figure:: ./figures/error-unstable.* |
223 | 221 |
246 | 244 |
247 .. [#] For this to happen one needs to explicitly enable exchange of draft | 245 .. [#] For this to happen one needs to explicitly enable exchange of draft |
248 changeset. See phase help for details. | 246 changeset. See phase help for details. |
249 | 247 |
250 The two part of the obsolete set | 248 The two part of the obsolete set |
251 `````````````````````````````````````` | 249 -------------------------------- |
252 | 250 |
253 The previous section show that it could be two kinds of *obsolete* changeset: | 251 The previous section show that it could be two kinds of *obsolete* changeset: |
254 | 252 |
255 | 253 |
256 * *obsolete* changeset with no or *obsolete* only descendants, said **extinct**. | 254 * *obsolete* changeset with no or *obsolete* only descendants, said **extinct**. |
272 have to stay visible and available until they unstable descendant are rewritten | 270 have to stay visible and available until they unstable descendant are rewritten |
273 in stable version. | 271 in stable version. |
274 | 272 |
275 | 273 |
276 Conflicting rewriting | 274 Conflicting rewriting |
277 `````````````````````` | 275 --------------------- |
278 | 276 |
279 If people start to concurrently edit the same part of the history they will | 277 If people start to concurrently edit the same part of the history they will |
280 likely meet conflicting situation when a changeset have been rewritten in two | 278 likely meet conflicting situation when a changeset have been rewritten in two |
281 different versions. | 279 different versions. |
282 | 280 |
296 | 294 |
297 Allowing multiple new changesets to obsolete a single one allow to distinct a | 295 Allowing multiple new changesets to obsolete a single one allow to distinct a |
298 splitted changeset from history rewriting conflict. | 296 splitted changeset from history rewriting conflict. |
299 | 297 |
300 Reliable history | 298 Reliable history |
301 `````````````````````` | 299 ---------------- |
302 | 300 |
303 Obsolete marker really help to smooth rewriting operation process. However they | 301 Obsolete marker really help to smooth rewriting operation process. However they |
304 do not change the fact that **you should only rewrite the mutable part of the | 302 do not change the fact that **you should only rewrite the mutable part of the |
305 history**. The phase concept enforce this rules by explicitly defining a | 303 history**. The phase concept enforce this rules by explicitly defining a |
306 public immutable set of changeset. Rewriting operation refuse to work on | 304 public immutable set of changeset. Rewriting operation refuse to work on |
323 | 321 |
324 .. warning:: add a schema | 322 .. warning:: add a schema |
325 | 323 |
326 | 324 |
327 Conclusion | 325 Conclusion |
328 ---------------- | 326 ========== |
329 | 327 |
330 Obsolete marker is a powerful concept that allow mercurial to safely handle | 328 Obsolete marker is a powerful concept that allow mercurial to safely handle |
331 history rewriting operations. It is a new type of relation between Mercurial | 329 history rewriting operations. It is a new type of relation between Mercurial |
332 changesets that track the result of history rewriting operations. | 330 changesets that track the result of history rewriting operations. |
333 | 331 |
334 This concept is simple to define and provides a very solid base to: | 332 This concept is simple to define and provides a very solid base to: |
335 | 333 |
336 | 334 |
337 - Very fast history rewriting operations, | 335 - Very fast history rewriting operations, |
338 | 336 |
339 - auditable and reversible history rewritting process, | 337 - auditable and reversible history rewriting process, |
340 | 338 |
341 - clean final history, | 339 - clean final history, |
342 | 340 |
343 - share and collaborate on mutable part of the history, | 341 - share and collaborate on mutable part of the history, |
344 | 342 |