docs/obs-concept.rst
branchstable
changeset 357 b398e9c2dbd1
parent 234 d32c07269dcd
child 519 9825c7da5b54
equal deleted inserted replaced
345:62de989b2a02 357:b398e9c2dbd1
     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 tools to forge a series of flawless changeset on your own.
     5 Current DVCSes are great tools for forging a series of flawless
     6 But they perform poorly when it comes to **sharing** some work in progress and
     6 changesets on your own. But they perform poorly when it comes to
     7 **collaborating** on such work in progress.
     7 **sharing** some work in progress and **collaborating** on such work
       
     8 in progress.
     8 
     9 
     9 When people forge a new version of a changeset they actually create a
    10 When people forge a new version of a changeset they actually create a
    10 new changeset and get rid of the original changeset. Difficulties to
    11 new changeset and get rid of the original changeset. Difficulties to
    11 collaborate mostly came from the way old content is *removed* from
    12 collaborate mostly came from the way old content is *removed* from
    12 a repository.
    13 a repository.
    16 
    17 
    17 With the current version of mercurial, every changeset that exists in
    18 With the current version of mercurial, every changeset that exists in
    18 your repository is *visible* and *meaningful*. To delete old
    19 your repository is *visible* and *meaningful*. To delete old
    19 (rewritten) changesets, mercurial removes them from the repository
    20 (rewritten) changesets, mercurial removes them from the repository
    20 storage with an operation called *strip*. After the *stripping*, the
    21 storage with an operation called *strip*. After the *stripping*, the
    21 repository looks like if the changeset never existed.
    22 repository looks as if the changeset never existed.
    22 
    23 
    23 This approach is simple and effective except for one big
    24 This approach is simple and effective except for one big
    24 drawback: you can remove changesets from **your repository only**. If
    25 drawback: you can remove changesets from **your repository only**. If
    25 a stripped changeset exists in another repository it touches, it will
    26 a stripped changeset exists in another repository it touches, it will
    26 show up again. This is because a shared changeset becomes
    27 show up again. This is because a shared changeset becomes
    27 part of a shared global history. Stripping a changeset from all
    28 part of a shared global history. Stripping a changeset from all
    28 repositories is at best impractical and in most case impossible!
    29 repositories is at best impractical and in most case impossible.
    29 
    30 
    30 As consequence, **you can not rewrite something once you exchange it with
    31 As consequence, **you can not rewrite something once you exchange it with
    31 others**. The old version will still exist along side the new one [#]_.
    32 others**. The old version will still exist along side the new one [#]_.
    32 
    33 
    33 Moreover stripping changesets creates backup bundles. This allows
    34 Moreover stripping changesets creates backup bundles. This allows
    38 
    39 
    39 To sum up, the strip approach is very simple but does not handle
    40 To sum up, the strip approach is very simple but does not handle
    40 interaction with the outer world, which is very unfortunate for a
    41 interaction with the outer world, which is very unfortunate for a
    41 *Distributed* VCS.
    42 *Distributed* VCS.
    42 
    43 
    43 .. [#] various work around exists but they require their own workflows which are distinct from the very elegant basic workflow of Mercurial.
    44 .. [#] various work around exists but they require their own workflows
       
    45    which are distinct from the very elegant basic workflow of
       
    46    Mercurial.
    44 
    47 
    45 Git Approach: Overwrite Reference
    48 Git Approach: Overwrite Reference
    46 -----------------------------------------------------
    49 -----------------------------------------------------
    47 
    50 
    48 The Git approach to repository structure is a bit more complex: there
    51 The Git approach to repository structure is a bit more complex: there
    66 can then propagate this change by moving the git-branch on remote host
    69 can then propagate this change by moving the git-branch on remote host
    67 with the newer version of the marker overwriting the older one.
    70 with the newer version of the marker overwriting the older one.
    68 
    71 
    69 This approach goes a bit further but still has a major drawback:
    72 This approach goes a bit further but still has a major drawback:
    70 
    73 
    71 Because you **overwrite** the git-branch, you have no conflict resolution. The last
    74 Because you **overwrite** the git-branch, you have no conflict
    72 to act wins. This makes collaboration on multiple changesets difficult because
    75 resolution. The last to act wins. This makes collaboration on multiple
    73 you can't merge concurrent updates on a changeset.
    76 changesets difficult because you can't merge concurrent updates on a
    74 
    77 changeset.
    75 Every overwrite is a forced operation where the operator says "Yes I want this to
    78 
    76 replace that. In highly distributed environments, a user may end up with conflicting
    79 Every overwrite is a forced operation where the operator says, "yes I
    77 references and no proper way to choose.
    80 want this to replace that". In highly distributed environments, a user
       
    81 may end up with conflicting references and no proper way to choose.
    78 
    82 
    79 Because of this way to visualize a repository, git-branches are a core
    83 Because of this way to visualize a repository, git-branches are a core
    80 part of git, which makes the user interface more complicated and
    84 part of git, which makes the user interface more complicated and
    81 constrains moving through history.
    85 constrains moving through history.
    82 
    86 
    83 Finally, even if all older changesets still exist in the repository, accesing them
    87 Finally, even if all older changesets still exist in the repository,
    84 is still painful.
    88 accesing them is still painful.
    85 
    89 
    86 
    90 
    87 -----------------------------------------------------
    91 -----------------------------------------------------
    88 The Obsolete Marker Concept
    92 The Obsolete Marker Concept
    89 -----------------------------------------------------
    93 -----------------------------------------------------
    90 
    94 
    91 
    95 
    92 As None of the concepts was powerful enough to fulfill the need of safely
    96 As none of the concepts was powerful enough to fulfill the need of
    93 rewriting history, including easy sharing and collaborating on mutable history,
    97 safely rewriting history, including easy sharing and collaboration on
    94 we needed another one. 
    98 mutable history, we needed another one.
    95 
    99 
    96 Basic concept
   100 Basic concept
    97 -----------------------------------------------------
   101 -----------------------------------------------------
    98 
   102 
    99 
   103 
   144 changesets to **1** old changeset.
   148 changesets to **1** old changeset.
   145 
   149 
   146 Basic Usage
   150 Basic Usage
   147 -----------------------------------------------------
   151 -----------------------------------------------------
   148 
   152 
   149 Obsolete markers create a perpendicular history: **a versioned changeset graph**. This means that offers the same features we have for
   153 Obsolete markers create a perpendicular history: **a versioned
   150 versioned files but applied to changeset:
   154 changeset graph**. This means that offers the same features we have
       
   155 for versioned files but applied to changeset:
   151 
   156 
   152 First: we can display a **coherent view** of the history graph in which only a
   157 First: we can display a **coherent view** of the history graph in which only a
   153 single version of your changesets is displayed by the UI.
   158 single version of your changesets is displayed by the UI.
   154 
   159 
   155 Second, because obsolete changeset content is still **available**. You can 
   160 Second, because obsolete changeset content is still **available**. You can 
   193 
   198 
   194 .. figure:: ./figures/error-obsolete.*
   199 .. figure:: ./figures/error-obsolete.*
   195 
   200 
   196     Rebasing `B` and `C` on `A` (as `B'`, `C'`)
   201     Rebasing `B` and `C` on `A` (as `B'`, `C'`)
   197 
   202 
   198     This rebase operation added two obsolete markers from new changesets to old
   203     This rebase operation added two obsolete markers from new
   199     changesets. These two old changesets are now part of the *obsolete* part of the
   204     changesets to old changesets. These two old changesets are now
   200     history.
   205     part of the *obsolete* part of the history.
   201 
   206 
   202 In most cases, the obsolete set will be fully hidden to both the UI and
   207 In most cases, the obsolete set will be fully hidden to both the UI and
   203 discovery, hence users do not have to care about them unless they want to
   208 discovery, hence users do not have to care about them unless they want to
   204 audit history rewriting operations.
   209 audit history rewriting operations.
   205 
   210 
   206 Unstable changesets
   211 Unstable changesets
   207 ```````````````````
   212 ```````````````````
   208 
   213 
   209 While exploring the possibilities of the obsolete marker a bit further, you may end up with
   214 While exploring the possibilities of the obsolete marker a bit
   210 *obsolete* changesets which have *non-obsolete* children. There is two common ways to
   215 further, you may end up with *obsolete* changesets which have
   211 achieve this:
   216 *non-obsolete* children. There is two common ways to achieve this:
   212 
   217 
   213 * Pull a changeset based of an old version of a changeset [#]_.
   218 * Pull a changeset based of an old version of a changeset [#]_.
   214 
   219 
   215 * Use a partial rewriting operation. For example amend on a changeset with
   220 * Use a partial rewriting operation. For example amend on a changeset with
   216   children.
   221   children.
   219 
   224 
   220 .. figure:: ./figures/error-unstable.*
   225 .. figure:: ./figures/error-unstable.*
   221 
   226 
   222     Amend `A` into `A'` leaving `B` behind.
   227     Amend `A` into `A'` leaving `B` behind.
   223 
   228 
   224     In this situation we can not consider `B` as *obsolete*.  But we have all
   229     In this situation we cannot consider `B` as *obsolete*. But we
   225     necessary data to detect `B` as an *unstable* branch of the history because
   230     have all the necessary data to detect `B` as an *unstable* branch
   226     its parent `A` is *obsolete*. In addition, we have enough data to
   231     of the history because its parent `A` is *obsolete*. In addition,
   227     automatically resolve this instability: we know that the new version of `B`
   232     we have enough data to automatically resolve this instability: we
   228     parent (`A`) is `A'`, We can deduce that we should rebase `B` on `A'` to get
   233     know that the new version of `B` parent (`A`) is `A'`. We can
   229     a stable history again.
   234     deduce that we should rebase `B` on `A'` to get a stable history
       
   235     again.
   230 
   236 
   231 Proper warnings should be issued when part of the history becomes
   237 Proper warnings should be issued when part of the history becomes
   232 unstable. The UI will be able to use the obsolete marker to
   238 unstable. The UI will be able to use the obsolete marker to
   233 automatically suggest a resolution to the user of even carry them out
   239 automatically suggest a resolution to the user of even carry them out
   234 for him.
   240 for them.
   235 
   241 
   236 
   242 
   237 XXX details on automatic resolution for
   243 XXX details on automatic resolution for
   238 
   244 
   239 * movement
   245 * movement
   264     In this example we have two *obsolete* changesets: `C` with no *unstable*
   270     In this example we have two *obsolete* changesets: `C` with no *unstable*
   265     children is *extinct*. `A` with *unstable* descendant (`B`) is *suspended*.
   271     children is *extinct*. `A` with *unstable* descendant (`B`) is *suspended*.
   266     `B` is *unstable* as before.
   272     `B` is *unstable* as before.
   267 
   273 
   268 
   274 
   269 Because nothing outside the obsolete set default on *extinct* changesets, they
   275 Because nothing outside the obsolete set default on *extinct*
   270 can be safely hidden in the UI and even garbage collected. *Suspended* changesets
   276 changesets, they can be safely hidden in the UI and even garbage
   271 have to stay visible and available until their unstable descendant are rewritten
   277 collected. *Suspended* changesets have to stay visible and available
   272 into stable version.
   278 until their unstable descendant are rewritten into stable version.
   273 
   279 
   274 
   280 
   275 Conflicting rewrites
   281 Conflicting rewrites
   276 ````````````````````
   282 ````````````````````
   277 
   283 
   298 distinguish a split changeset from a history rewriting conflict.
   304 distinguish a split changeset from a history rewriting conflict.
   299 
   305 
   300 Reliable history
   306 Reliable history
   301 ``````````````````````
   307 ``````````````````````
   302 
   308 
   303 Obsolete marker help to smooth rewriting operation process. However they
   309 Obsolete markers help to smooth rewriting operation process. However
   304 do not change the fact that **you should only rewrite the mutable part of the
   310 they do not change the fact that **you should only rewrite the mutable
   305 history**. The phase concept enforces this rule by explicitly defining a
   311 part of the history**. The phase concept enforces this rule by
   306 public immutable set of changesets. Rewriting operations refuse to work on
   312 explicitly defining a public immutable set of changesets. Rewriting
   307 public changesets, but there are still some corner cases where previously rewritten changesets
   313 operations refuse to work on public changesets, but there are still
   308 are made public.
   314 some corner cases where previously rewritten changesets are made
       
   315 public.
   309 
   316 
   310 Special rules apply for obsolete markers pointing to public changesets:
   317 Special rules apply for obsolete markers pointing to public changesets:
   311 
   318 
   312 * Public changesets are excluded from the obsolete set (public
   319 * Public changesets are excluded from the obsolete set (public
   313   changesets are never hidden or candidate to garbage collection)
   320   changesets are never hidden or candidate to garbage collection)
   314 
   321 
   315 * *newer* version of a public changeset are called **latecomer** and highlighted as
   322 * *newer* version of a public changeset are called **latecomer** and
   316   an error case.
   323   highlighted as an error case.
   317 
   324 
   318 Solving such an error is easy. Because we know what changeset a
   325 Solving such an error is easy. Because we know what changeset a
   319 *latecomer* tries to rewrite, we can easily compute a smaller
   326 *latecomer* tries to rewrite, we can easily compute a smaller
   320 changeset containing only the change from the old *public* to the new
   327 changeset containing only the change from the old *public* to the new
   321 *latecomer*.
   328 *latecomer*.
   341 
   348 
   342 - sharing and collaborating on the mutable part of the history,
   349 - sharing and collaborating on the mutable part of the history,
   343 
   350 
   344 - gracefully handling history rewriting conflicts,
   351 - gracefully handling history rewriting conflicts,
   345 
   352 
   346 - various history rewriting UI’s collaborating with an underlying common API.
   353 - various history rewriting UI's collaborating with an underlying common API.
   347 
   354 
   348 .. list-table:: Comparison on solution [#]_
   355 .. list-table:: Comparison on solution [#]_
   349    :header-rows: 1
   356    :header-rows: 1
   350 
   357 
   351    * - Solution
   358    * - Solution