restore unstability content
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Wed, 09 May 2012 18:52:57 +0200
changeset 231 f589d054329a
parent 230 bcf095c8239c
child 232 adb7e29cb2bd
restore unstability content
docs/unstability.rst
--- a/docs/unstability.rst	Wed May 09 16:41:38 2012 +0200
+++ b/docs/unstability.rst	Wed May 09 18:52:57 2012 +0200
@@ -1,5 +1,6 @@
+
 -----------------------------------
-The Unstability Principle
+The instability Principle
 -----------------------------------
 
 
@@ -7,14 +8,15 @@
 An intrinsic contradiction
 -----------------------------------
 
+XXX starts by talking about getting ride of changeset.
 
 DVCS bring two new major concepts to the Version Control Scene:
 
-    * Organisation of the history with robust DAG,
-    * Mutation of history.
+    * History is organized as a robust DAG,
+    * History can be rewritten.
 
 
-However, the two concepts opposes them self:
+However, the two concepts are in contradiction:
 
 To achieve a robust history, three key elements are gathered in *changeset*:
 
@@ -22,33 +24,34 @@
     * Reference to the previous full snapshot used to build the new one,
     * A description of the change who lead from the old content to the new old.
 
-All three elements are used generate a *unique* hash that identify the changeset
+All three elements are to compute a *unique* hash that identify the changeset
 (with various other metadata). This identification is a key part of DVCS design.
 
+This is a very useful property because Changing B parent means changing B
+content too.  This require the creation of **another** changeset which is a good
+semantic.
+
 ::
 
   Schema base,  A, B and B'
 
-The old changeset is usually discarded
-t in DVCS history.
+To avoid duplication, the older changeset is usually discarded from accessible
+history. I'm calling them *obsolete* changesets.
+
 
+But rewriting a changeset with children does not changes children parent! And
+because children of the rewritten changeset still **depends** on the older
+"dead" version of the changeset with can not get ride of this dead version.
 
 ::
 
   Schema base,  A and A' and B.
 
-Rewriting a changeset with children does not changes children parent! And
-because children of the rewritten changeset still **depends** on the older
-"dead" version of the changeset with can not get ride of this dead version.
-
-This is a very useful property because Changing B parent means changing B
-content too.  This require the creation of **another** changeset.
-
-I'll qualify those children as **unstable** because they are based one a dead
+I'm calling those children **unstable** because they are based one a dead
 changeset and prevent people to get ride of it.
 
 This instability is an **unavoidable consequence** of the strict dependency of
-changese.  History Rewriting history alway  need to take it in account and
+changeset.  History Rewriting history alway  need to take it in account and
 provide a way to rewrite the descendant on the new changeset to avoid
 coexistence of the old and new version of a rewritten changeset..
 
@@ -56,73 +59,158 @@
 Everybody is working around the issue
 ------------------------------------------------
 
-I'm not claiming that rewriting history is impossible. People are 
-
+I'm not claiming that rewriting history is impossible. People are successfully
+doing for years. However they all need to work around *instability*. Several
+work around strategy exists.
 
 
 Rewriting all at once
 ``````````````````````````
 
+The simplest way to avoid instability is to ensure rewriting operation always
+ends in a stable situation. This is achieve by rewriting all impacted changeset
+at the same time.
+
+Rewriting all descendants at the same time than the rewritted of a changeset.
+
+::
+
+  Schema!
+
+Several Mercurial commands apply it: rebase, collapse, histedit.  Mercurial also
+refuse to amend changeset with descendant.  The git branch design enforce such
+approach in git too.
 
 
-stable situation to stable situation
+However, DVCS are **Distributed**. This means that you do not control what
+happen outside your repository. Once a changeset have been exchanged *outside*,
+there is no way to be sure it does not have descendants somewhere else.
+Therefore **if you rewrite changeset that exists elsewhere, you can't eradicate
+the risk of instability.**
 
-Distributed means that you do not control what happen outside your repository:
-
+Do not rewrite exchanged changeset
+```````````````````````````````````
 
-* phase.
-* overwrite.
+To work around the issue above, mercurial introduced phases that prevent you to
+rewrite shared changeset and ensure other can't pull certain changeset from you.
+But this is a very frustrating limitation that prevent you to efficiently share,
+review and collaborate on mutable changeset.
 
-
-Boiler Plate
+Git world use another approach to prevent instability.  By convention only a
+single developper works on a changeset contained in a named branch. But once
+again this is a huge blocker for collaborating. Moreover clueless people
+**will** mess up social convention soon or later.
 
 
 Loose the DAG robustness
 ````````````````````````````
 
-The other approach is
+The other approach use in Mercurial is to keep the mutable part of the history
+outside the DVCS constraint. This is the MQ approach of sticking a quilt queue
+over Mercurial.
 
-mq -- quilt
+This allow much more flexible workflow but two major feature are lost in the
+process:
 
-Conflict too much conflict
+:Graceful merge: MQ use plain-patch to store changeset content and patch have
+                 trouble to apply in changing context. Applying your queue
+                 becomes very painful when context changes.
 
-Linear
-
+:easy branching: A quilt queue is by definition a linear queue. Increasing risk
+                 of conflict
 
-Deny a lot of option
-````````````````````````````
-
-
+It is possible to collaborate over versioned mq! But you are going ahead a lot
+of troubles.
 
-[] rewrite
-
-[] exchange
-
-[] collaborate
-
+.. Ignore conflicts
+.. ```````````````````````````````````
+.. 
+.. Another ignored issue is conflicting rewritting of the same changeset. If a
+.. changeset is rewritten two times we have two newer version, duplicated history
+.. complicate to merge.
+.. 
+.. Mercurial work around by
+.. 
+.. The "One set of mutable changset == One developper" mantra is also a way to work
+.. around conflicting rewritting of changeset. If two different people are able to
+.. 
+.. The git branch model allow to overwrite changeset version by another one. But it
+.. does not care about divergent version. It is the equilent of "common ftp" source
+.. management for changeset.
 
 Facing The Danger Once And For All
 ------------------------------------------------
-The more effort you put to avoid instability, the more option you deny. And even
-most restrictive work flow can't garantee that instability will never show up!
+
+Above we saw that, the more effort you put to avoid instability, the more option
+you deny. And even most restrictive work flow can't guarantee that instability
+will never show up!
+
+Obsolete marker can handle the job
+```````````````````````````````````
 
 It is time to provide a full featured solution to deal with instability and to
 stop working around the issue! This is why I developing a new feature for
-mercurial called "Obsolete marker".
+mercurial called "Obsolete markers". Obsolete markers have two key properties:
 
 
-* Any changeset is we want to get ride of is **explicitly** marked as "obsolete"
-  by history rewritting operation..
+* Any "old" changeset we want to get ride of is **explicitly** marked as "obsolete"
+  by history rewriting operation.
 
-* Relations between old and new version of changesets are tracked by Obsolete
+  By explicitly marking the obsolete part of the history, we will be able to
+  easily detect instability situation.
+
+* Relations between old and new version of changesets are tracked by obsolete
   markers.
 
-By explicitly marking the obsolete part of the history, we will be able to
-easily detect appearance of unstability. By Storing a meta-history of changeset
-evolution we are able to easily resolve instability and edition conflict.
+  By Storing a meta-history of changeset evolution we are able to easily resolve
+  instability and edition conflict [#]_ .
+
+.. [#] edition conflict is another major obstable to collaboration. See the
+       section dedicated to obsolete marker for details.
+
+Improves robustness == improves simplicity
+````````````````````````````````````````````````
+
+This proposal should **first** be seen as a safety measure.
+
+It allow to detect instability as soon as possible
+
+::
+    $ hg pull
+    added 3 changeset
+    +2 unstable changeset
+    (do you want "hg stabilize" ?)
+    working directory parent is obsolete!
+    $ hg push
+    outgoing unstable changesets
+    (use "hg stabilize" or force the push)
+
+And should not not encourage people to create unstability
+
+::
+    $ hg up 42
+    $ hg commit --amend
+    changeset have descendant.
+    $ hg commit --amend -f
+    +5 unstable changeset
+
+    $ hg rebase -D --rev 40::44
+    rebasing already obsolete changeset 42:AAA will conflict with newer version 48:BBB
+
+While allowing powerful feature
+````````````````````````````````````````````````
 
 
+* Help to automatically solve instability.
+
+* "kill" changeset remotely.
+
+* track resulting changeset when submitting patch//pull request.
+
+* Focus on what you do:
+
+  I do not like the "all at once" model of history rewriting. I'm comfortable
+  with unstability and obsolete marker offer all the tool to safely create and
+  handle unstability locally.
 
 
-No instability is still a bad situation.
-No instability is still a bad situation that should be avoided.