docs/obs-concept.rst
changeset 192 706a3a57b567
parent 191 0f1b8119a281
parent 186 0698376bb13c
child 193 adf92ff8d4f6
equal deleted inserted replaced
191:0f1b8119a281 192:706a3a57b567
     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 tools to forge a series of flawless changeset on your own.
     6 But they perform poorly when is comes to **share** work in progress and
     6 But they perform poorly when it comes to **sharing** some work in progress and
     7 **collaborate** on such work in progress.
     7 **collaborating** 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 a new version of a changeset they actually create a
    10 ride of the original changeset. Difficulties to collaborate mostly came from the
    10 new changeset and get rid of the original changeset. Difficulties to
    11 way old content are *removed* from repository.
    11 collaborate mostly came from the way old content is *removed* from
       
    12 a repository.
    12 
    13 
    13 Mercurial Approach: Strip
    14 Mercurial Approach: Strip
    14 =========================
    15 -----------------------------------------------------
    15 
    16 
    16 With current version of mercurial, every changesets that exist in your
    17 With the current version of mercurial, every changeset that exists in
    17 repository are *visible* and *meaningful*. To get ride of old changeset you
    18 your repository is *visible* and *meaningful*. To delete old
    18 rewrote mercurial remove them from the repository storage. with an operation
    19 (rewritten) changesets, mercurial removes them from the repository
    19 called *strip*. After the *strip* the repository looks like if the changeset
    20 storage with an operation called *strip*. After the *stripping*, the
    20 never existed.
    21 repository looks like if the changeset never existed.
    21 
    22 
    22 This approach is simple and effective but have a very big drawback: You can
    23 This approach is simple and effective except for one big
    23 remove changesets from **your repository only**. If strip exists in other
    24 drawback: you can remove changesets from **your repository only**. If
    24 repositories it will show of again and again. This only cure for this is to
    25 a stripped changeset exists in another repository it touches, it will
    25 strip the offending changeset from all repository. And operation at best
    26 show up again. This is because a shared changeset becomes
    26 impractical and in most case impossible!
    27 part of a shared global history. Stripping a changeset from all
    27 
    28 repositories is at best impractical and in most case impossible!
    28 
    29 
    29 As consequence, **you can not rewrite something once you exchange it with
    30 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 [#]_.
    31 others**. The old version will still exist along side the new one [#]_.
    31 
    32 
    32 Moreover stripping changesets creates backup bundles. This allows
    33 Moreover stripping changesets creates backup bundles. This allows
    33 restoration of the deleted changesets, but the process is painful.
    34 restoration of the deleted changesets, but the process is painful.
    34 
    35 
    35 Finally, as the repository format is not optimized for deletion. stripping a
    36 Finally, as the repository format is not optimized for deletion. stripping a
    36 changeset may be slow in some situations.
    37 changeset may be slow in some situations.
    37 
    38 
    38 To sum up, the strip approach is very simple but does not handle interaction
    39 To sum up, the strip approach is very simple but does not handle
    39 with the outer world. Which is unfortunate for a *Distributed* VCS.
    40 interaction with the outer world, which is very unfortunate for a
       
    41 *Distributed* VCS.
    40 
    42 
    41 .. [#] various work around exists but they require their own workflows which are distinct from the very elegant basic workflow of Mercurial.
    43 .. [#] various work around exists but they require their own workflows which are distinct from the very elegant basic workflow of Mercurial.
    42 
    44 
    43 Git Approach: Overwrite Reference
    45 Git Approach: Overwrite Reference
    44 =================================
    46 -----------------------------------------------------
    45 
    47 
    46 Git approach for repository is a bit more complex: Any number of
    48 The Git approach to repository structure is a bit more complex: there
    47 changesets can exist in a repository. but **only changesets referenced by a git
    49 can be any amount of unrelated changesets in a repository, and **only
    48 branch** are *visible* and *meaningful*.
    50 changesets referenced by a git branch** are *visible* and
       
    51 *meaningful*.
    49 
    52 
    50 
    53 
    51 .. warning:: add a schema::
    54 .. warning:: add a schema::
    52 
    55 
    53         C
    56         C
    58 
    61 
    59     Only B and A are visible.
    62     Only B and A are visible.
    60 
    63 
    61 This simplifies the process of getting rid of old changesets. You can
    64 This simplifies the process of getting rid of old changesets. You can
    62 just leave them in place and move the reference on the new one. You
    65 just leave them in place and move the reference on the new one. You
    63 can then propagate that change by moving the git-branch on remote host
    66 can then propagate this change by moving the git-branch on remote host
    64 with the newer version of the marker overwriting the older one.
    67 with the newer version of the marker overwriting the older one.
    65 
    68 
    66 This approach goes a bit further but still has a major drawback:
    69 This approach goes a bit further but still has a major drawback:
    67 
       
    68 
    70 
    69 Because you **overwrite** the git-branch, you have no conflict resolution. The last
    71 Because you **overwrite** the git-branch, you have no conflict resolution. The last
    70 to act wins. This makes collaboration on multiple changesets difficult because
    72 to act wins. This makes collaboration on multiple changesets difficult because
    71 you can't merge concurrent updates on a changeset.
    73 you can't merge concurrent updates on a changeset.
    72 
    74 
    73 Every overwrite is a forced operation where the operator say "Yes I want this to
    75 Every overwrite is a forced operation where the operator says "Yes I want this to
    74 replace that. In highly distributed environments, a user may end up with conflicting
    76 replace that. In highly distributed environments, a user may end up with conflicting
    75 references and no proper way to choose.
    77 references and no proper way to choose.
    76 
    78 
    77 Because of this way to visualize a repository, git-branches are a core
    79 Because of this way to visualize a repository, git-branches are a core
    78 part of git, which makes the user interface more complicated and
    80 part of git, which makes the user interface more complicated and
    79 constrains the ways to move through history.
    81 constrains moving through history.
    80 
    82 
    81 Finally, even if all older changeset still exist in the repository, access to them
    83 Finally, even if all older changesets still exist in the repository, accesing them
    82 is still painful.
    84 is still painful.
    83 
    85 
    84 
    86 
    85 =============================
    87 -----------------------------------------------------
    86  The Obsolete Marker Concept
    88 The Obsolete Marker Concept
    87 =============================
    89 -----------------------------------------------------
    88 
    90 
    89 
    91 
    90 
    92 As None of the concepts was powerful enough to fulfill the need of safely rewriting                              
    91 
    93 history, including easy sharing and collaborating on mutable history, we needed another one. 
    92 
       
    93 As None of the concepts was powerful enough to fulfill the need of safely rewriting
       
    94 history, including easy sharing and collaborating on mutable history, we needed another one.
       
    95 
       
    96 
       
    97 
    94 
    98 Basic concept
    95 Basic concept
    99 =============
    96 -----------------------------------------------------
   100 
    97 
   101 
    98 
   102 Every history rewriting operation stores the information that the old rewritten
    99 Every history rewriting operation stores the information that old rewritten
   103 changeset is replaced by newer version in a given set of changeset.
   100 changeset is replaced by newer version in a given set of changesets.
   104 
   101 
   105 All basic history rewriting operation can create an appropriate obsolete marker.
   102 All basic history rewriting operation can create an appropriate obsolete marker.
   106 
   103 
   107 
   104 
   108 .. figure:: ./figures/example-1-update.*
   105 .. figure:: ./figures/example-1-update.*
   144 
   141 
   145 To conclude, a single obsolete marker express a relation from **0..n** new
   142 To conclude, a single obsolete marker express a relation from **0..n** new
   146 changesets to **1** old changeset.
   143 changesets to **1** old changeset.
   147 
   144 
   148 Basic Usage
   145 Basic Usage
   149 ===========
   146 -----------------------------------------------------
   150 
   147 
   151 Obsolete markers create a perpendicular history: **a versioned changeset graph**. This means that offers the same features we have for
   148 Obsolete markers create a perpendicular history: **a versioned changeset graph**. This means that offers the same features we have for
   152 versioned files but applied to changeset:
   149 versioned files but applied to changeset:
   153 
   150 
   154 First: we can display a **coherent view** of the history graph in which only a
   151 First: we can display a **coherent view** of the history graph in which only a
   155 single version of your changesets are displayed by the UI.
   152 single version of your changesets is displayed by the UI.
   156 
   153 
   157 Second, because obsolete changeset content is still **available**. You can 
   154 Second, because obsolete changeset content is still **available**. You can 
   158 
   155 you can
   159     * **browse** the content of your obsolete commit,
   156 
   160 
   157     * **browse** the content of your obsolete commits,
   161     * **compare** newer and older version of a changeset,
   158 
   162 
   159     * **compare** newer and older versions of a changeset,
   163     * **restore** content of previously obsolete changeset.
   160 
   164 
   161     * **restore** content of previously obsolete changesets.
   165 Finally, obsolete marker can be **exchanged between repositories**. You are able to
   162 
   166 share the result on your history rewriting operation with other and **collaborate
   163 Finally, the obsolete marker can be **exchanged between
   167 on mutable part of the history**.
   164 repositories**. You are able to share the result on your history
   168 
   165 rewriting operations with other prople and **collaborate on the
   169 Conflicting history rewriting operation can be detected and **resolved** as easily
   166 mutable part of the history**.
   170 as conflicting changes on file.
   167 
       
   168 Conflicting history rewriting operation can be detected and
       
   169 **resolved** as easily as conflicting changes on a file.
   171 
   170 
   172 
   171 
   173 Detecting and solving tricky situations
   172 Detecting and solving tricky situations
   174 ======================================
   173 -----------------------------------------------------
   175 
   174 
   176 History rewriting can lead to complex situations. Obsolete marker introduce a
   175 History rewriting can lead to complex situations. The obsolete marker
   177 simple representation of this complex reality. But people using complex workflows
   176 introduces a simple representation for this complex reality. But
   178 will one day or another have to face the intrinsic complexity of some
   177 people using complex workflows will one day or another have to face
   179 situations.
   178 the intrinsic complexity of some real-world situation.
   180 
   179 
   181 This section describes possible situations, defines precise sets of changesets
   180 This section describes possible situations, defines precise sets of
   182 involved in such situations and explains how error cases can automatically be
   181 changesets involved in such situations and explains how the error
   183 resolved using available information.
   182 cases can be resolved automatically using the available information.
   184 
   183 
   185 
   184 
   186 obsolete changesets
   185 Obsolete changesets
   187 -------------------
   186 ````````````````````
   188 
   187 
   189 Old changesets left behind by obsolete operation are called **obsolete**.
   188 Old changesets left behind by obsolete operation are called **obsolete**.
   190 
   189 
   191 With the current version of mercurial, this *obsolete* part is stripped from the
   190 With the current version of mercurial, this *obsolete* part is stripped from the
   192 repository before the end of every rewriting operation.
   191 repository before the end of every rewriting operation.
   197 
   196 
   198     This rebase operation added two obsolete markers from new changesets to old
   197     This rebase operation added two obsolete markers from new changesets to old
   199     changesets. These two old changesets are now part of the *obsolete* part of the
   198     changesets. These two old changesets are now part of the *obsolete* part of the
   200     history.
   199     history.
   201 
   200 
   202 In most cases, the obsolete set will be fully hidden to both UI and discovery so
   201 In most cases, the obsolete set will be fully hidden to both the UI and
   203 the user does not have to care about them unless he wants to audit the history rewriting
   202 discovery, hence users do not have to care about them unless they want to
   204 operation.
   203 audit history rewriting operations.
   205 
   204 
   206 Unstable changesets
   205 Unstable changesets
   207 -------------------
   206 ```````````````````
   208 
   207 
   209 While exploring the possibilities of the obsolete a bit further, you may end up with
   208 While exploring the possibilities of the obsolete marker a bit further, you may end up with
   210 *obsolete* changeset which have *non-obsolete* children. There is two common ways to
   209 *obsolete* changesets which have *non-obsolete* children. There is two common ways to
   211 achieve this:
   210 achieve this:
   212 
   211 
   213 * Pull a changeset based of an old version of a changeset [#]_.
   212 * Pull a changeset based of an old version of a changeset [#]_.
   214 
   213 
   215 * Use a partial rewriting operation. For example amend on a changeset with
   214 * Use a partial rewriting operation. For example amend on a changeset with
   216   children .
   215   children.
   217 
   216 
   218 *Non-obsolete* changeset based on *obsolete* one are called **unstable**
   217 *Non-obsolete* changeset based on *obsolete* one are called **unstable**
   219 
   218 
   220 .. figure:: ./figures/error-unstable.*
   219 .. figure:: ./figures/error-unstable.*
   221 
   220 
   226     its parent `A` is *obsolete*. In addition, we have enough data to
   225     its parent `A` is *obsolete*. In addition, we have enough data to
   227     automatically resolve this instability: we know that the new version of `B`
   226     automatically resolve this instability: we know that the new version of `B`
   228     parent (`A`) is `A'`, We can deduce that we should rebase `B` on `A'` to get
   227     parent (`A`) is `A'`, We can deduce that we should rebase `B` on `A'` to get
   229     a stable history again.
   228     a stable history again.
   230 
   229 
   231 Proper warning should be issued when part of the history become unstable. UI
   230 Proper warnings should be issued when part of the history becomes
   232 will be able to use the obsolete marker to automatically suggest resolution to
   231 unstable. The UI will be able to use the obsolete marker to
   233 the user of even carry them out for him.
   232 automatically suggest a resolution to the user of even carry them out
       
   233 for him.
   234 
   234 
   235 
   235 
   236 XXX details on automatic resolution for
   236 XXX details on automatic resolution for
   237 
   237 
   238 * movement
   238 * movement
   243 
   243 
   244 
   244 
   245 .. [#] 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
   246        changesets. See phase help for details.
   246        changesets. See phase help for details.
   247 
   247 
   248 The two part of the obsolete set
   248 The two parts of the obsolete set
   249 --------------------------------
   249 ``````````````````````````````````````
   250 
   250 
   251 The previous section show that there can be two kinds of an *obsolete* changeset:
   251 The previous section shows that there could be two kinds of *obsolete*
   252 
   252 changesets:
   253 
   253 
   254 * an *obsolete* changeset with no or *obsolete* only descendants is called **extinct**.
   254 * an *obsolete* changeset with no or *obsolete* only descendants is called **extinct**.
   255 
   255 
   256 * an *obsolete* changeset with *unstable* descendants is called **suspended**.
   256 * an *obsolete* changeset with *unstable* descendants is called **suspended**.
   257 
   257 
   270 have to stay visible and available until their unstable descendant are rewritten
   270 have to stay visible and available until their unstable descendant are rewritten
   271 into stable version.
   271 into stable version.
   272 
   272 
   273 
   273 
   274 Conflicting rewrites
   274 Conflicting rewrites
   275 ---------------------
   275 ````````````````````
   276 
   276 
   277 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
   278 likely meet conflicting situations when a changeset has been rewritten in two
   278 likely meet conflicting situations when a changeset has been rewritten in two
   279 different ways.
   279 different ways.
   280 
   280 
   281 
   281 
   282 .. figure:: ./figures/error-conflicting.*
   282 .. figure:: ./figures/error-conflicting.*
   283 
   283 
   284     Conflicting rewrite of `A` into `A'` and `A''`
   284     Conflicting rewrite of `A` into `A'` and `A''`
   285 
   285 
   286 This kind of conflict is easy to detect with obsolete markers, because an obsolete
   286 This kind of conflict is easy to detect with an obsolete marker
   287 changeset can have more than one new version. It may be seen as the multiple heads
   287 because an obsolete changeset can have more than one new version. It
   288 case which Mercurial warns you about on pull. It is resolved the same way by a merge of
   288 may be seen as the multiple heads case. Mercurial warns you about this
   289 A' and A'' that will keep the same parent than `A'` and `A''` with two obsolete
   289 on pull. It is resolved the same way by a merge of A' and A'' that
       
   290 will keep the same parent than `A'` and `A''` with two obsolete
   290 markers pointing to both `A` and `A'`
   291 markers pointing to both `A` and `A'`
   291 
   292 
   292 .. warning::  TODO: Add a schema of the resolution. (merge A' and A'' with A as
   293 .. warning::  TODO: Add a schema of the resolution. (merge A' and A'' with A as
   293               ancestor and graft the result of A^)
   294               ancestor and graft the result of A^)
   294 
   295 
   295 Allowing multiple new changesets to obsolete a single one allows to differenciate
   296 Allowing multiple new changesets to obsolete a single one allows to
   296 split changesets from history rewriting conflicts.
   297 distinguish a split changeset from a history rewriting conflict.
   297 
   298 
   298 Reliable history
   299 Reliable history
   299 ----------------
   300 ``````````````````````
   300 
   301 
   301 Obsolete marker help to smooth rewriting operation process. However they
   302 Obsolete marker help to smooth rewriting operation process. However they
   302 do not change the fact that **you should only rewrite the mutable part of the
   303 do not change the fact that **you should only rewrite the mutable part of the
   303 history**. The phase concept enforces this rule by explicitly defining a
   304 history**. The phase concept enforces this rule by explicitly defining a
   304 public immutable set of changesets. Rewriting operations refuse to work on
   305 public immutable set of changesets. Rewriting operations refuse to work on
   305 public changesets, but there are still some corner cases where previously rewritten changesets
   306 public changesets, but there are still some corner cases where previously rewritten changesets
   306 are made public.
   307 are made public.
   307 
   308 
   308 Special rules apply for obsolete markers pointing to public changesets
   309 Special rules apply for obsolete markers pointing to public changesets:
   309 
   310 
   310 * Public changesets are excluded from the obsolete set (public changeset are
   311 * Public changesets are excluded from the obsolete set (public
   311   never hidden or candidate to garbage collection)
   312   changesets are never hidden or candidate to garbage collection)
   312 
   313 
   313 * *newer* version of public changeset are said **latecomer** and highlighted as
   314 * *newer* version of a public changeset are called **latecomer** and highlighted as
   314   error case.
   315   an error case.
   315 
   316 
   316 
   317 Solving such an error is easy. Because we know what changeset a
   317 Solving such error is easy. Because we know what changeset a *latecomer* try to
   318 *latecomer* tries to rewrite, we can easily compute a smaller
   318 rewrite, we can easily compute a smaller changeset containing only the change
   319 changeset containing only the change from the old *public* to the new
   319 from the old *public* to the new *latecomer*.
   320 *latecomer*.
   320 
       
   321 
   321 
   322 .. warning:: add a schema
   322 .. warning:: add a schema
   323 
   323 
   324 
   324 
   325 Conclusion
   325 Conclusion
   326 ==========
   326 ----------------
   327 
   327 
   328 The obsolete marker is a powerful concept that allows mercurial to safely handle
   328 The obsolete marker is a powerful concept that allows mercurial to safely handle
   329 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
   330 changesets which tracks the result of history rewriting operations.
   330 changesets which tracks the result of history rewriting operations.
   331 
   331