Benoît Allard avatar Benoît Allard committed 6d39516 Merge

merged

Comments (0)

Files changed (10)

File contents unchanged.

File contents unchanged.

 Here are various Materials on planned improvement to mercurial regarding
 rewriting history.
 
-The effort  splits in two parts:
+First read about what challenge arise while rewriting history and how we plan to
+solve them once and for all.
+
+.. toctree::
+   :maxdepth: 2
+
+   unstability
+
+The effort is splits in two parts:
 
  * The **obsolete marker** concept aims to provide and alternative to ``strip``
-   to get ride of changesets.
+   to get rid of changesets.
 
  * The **evolve** mercurial extension to rewrite history using *obsolete marker*
    under the hood.
 
-
 The first and most important step is by far the **obsolete marker**. However
-most user will never be directly exposed to the concept. For this reason
-document about changeset evolution are put first.
-
+most users will never be directly exposed to the concept. For this reason
+this manual starts with changeset evolution.
 
 Evolve: A robust alternative to MQ
 ====================================
 
-Evolve is an experimental history rewriting extensions that use obsolete
-markers. It is inspired from MQ and pbranch but have multiple advantage over
+Evolve is an experimental history rewriting extension that uses obsolete
+markers. It is inspired from MQ and pbranch but have multiple advantages over
 them:
 
-* sticks to "Work where you are" philosophy (I'll need better wording
-  for that)
+* Focus on your current work.
+
+    You can focus your work on a single changeset and take care of adapting
+    descendent changeset later.
 
 * Handle **non-linear history with branches and merges**
 
-* Use **robust merge** mechanism of mercurial.
+* Rely internally on **robust merge** mechanism of mercurial.
 
-  simple conflict are handled by real merge tools using appropriate ancestor.
+  Simple conflict are handled by real merge tools using appropriate ancestor.
   Conflict are much rarer and much more user friendly.
 
 *  Mutable history **fully available all the time**.
 
-  You are do not need to unapply and apply patche to access various part of you
-  history.
+  always use 'hg update' and forget about (un)applying patches to access the
+  mutable part of your history.
 
-* Use **plain changeset** only. Evole create and exchange real changeset only. 
-  Mutable history can be used in all usual operation 'pull, push, log, diff …)
 
-* Allow **sharing and collaboration** mutable history without fear of duplicate.
+* Use only **plain changeset** and forget about patches. Evole will create and
+  exchange real changesets. Mutable history can be used in all usual operations:
+  pull, push, log, diff, etc.
+
+* Allow **sharing and collaboration** mutable history without fear of duplicate
   (thanks to obsolete marker).
 
 * Cover all mq usage but guard.
 
 .. warning:: The evolve extention and the obsolete marker are at an experimental
-            stage. While using obsolet you'll likely be exposed to complexe
+            stage. While using obsolete you'll likely be exposed to complex
             implication of the **obsolete marker** concept. I do not recommend
-            non power user to test this at this stage.
+            non-power user to test this at this stage.
+
+            XXX make sure to read the XXX section before using it.
 
             Production ready version should hide such details to normal user.
 
     $ hg clone http://hg-dev.octopoid.net/hgwebdir.cgi/mutable-history/
     $ mutable-history/enable.sh >> ~/.hgrc
 
-You will probably want to use the associated version of hgview (QT viewer
-only). ::
+You will probably want to use the associated version of hgview (qt viewer
+recommended). ::
 
     $ hg clone http://hg-dev.octopoid.net/hgwebdir.cgi/hgview/
     $ cd hgview
     $ python setup.py install --user
 
+works with mercurial 2.1 and 2.2 (recommended)
 
  ---
 
-For more information see documents below
+For more information see documents below:
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 1
 
-   tutorial
+   tutorials/tutorial
    evolve-faq
    from-mq
    evolve-collaboration
 
 - Very fast history rewriting operations,
 
-- auditable and reversible history rewritting process,
+- auditable and reversible history rewriting process,
 
 - clean final history,
 
-- share and collaborate on mutable part of the history,
+- share and collaborate on mutable parts of the history,
 
-- gracefully handle history rewriting conflict,
+- gracefully handle history rewriting conflicts,
 
-- allows various history rewriting UI to collaborate with a underlying common API.
+- allow various history rewriting UI to collaborate with a underlying common API.
 
  ---
 
 For more information see documents below
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 1
 
    obs-concept
    obs-implementation
 
 
+Known caveats
+=============
 
+Here is a list of known issues that will be fixed later:
 
+* Unstable changeset turn secret.
 
+* ``hg stabilize`` does not handle conflicts.
 
-Know canveas
+Known limitation and bug
 =================================
 
 Here is a list of know issue that will be fixed later:
 
-* Unstable changeset turns secret.
 
-* ``hg stabilize`` does not handle conflict.
 
-* Mercurial think you are pushing additional heads even when the new head
-  obsolete another one. You have to use hg push -f more than necessary.
+* ``hg stabilize`` does not handle merge conflict.
+
+    You must fallback to graft or rebase when that happen.
+
+* rewriting conflict are not detected yet``hg stabilize`` does not handle them.
 
 * ``hg update`` can move an obsolete parent
 
-* you need to provideto graft --continue -O if you started you graft using -O.
+* you need to provide to `graft --continue -O` if you started you graft using `-O`.
+
+* ``hg merge`` considers an extinct head to be a valid target, hence requiring
+  you to manually specify target all the time.
+
+* trying to exchange obsolete relations with a static http repo will crash.
+
+* Extinct changeset are turned secret by various commands.
+
+* Extinct changesets are hidden using the *hidden* feature of mercurial only
+  supported by a few commands.
+
+  Only ``hg log``, ``hgview`` and `hg glog` (2.2 only) support it. ``hg head`` or other visual viewer don't.
+
+* hg heads show extinct changeset
+
+Fixed in 2.2
+---------------------------------
 
 * hg graphlog show extinct changeset
 
-* hg heads show extinct changeset
+* Mercurial 2.1 think you are pushing additional heads even when the new head
+  obsolete another one. You have to use hg push -f more often than necessary.
 
-* hg merge considered extinct head as valid target. requiring you to manually
-  specify target all the time.
 
-* obsolete relation exchange crash (as in traceback) on static http repo.
+* ``hg heads`` shows extinct changeset
 
+* ``hg merge`` considers an extinct head to be a valid target, hence requiring
+  you to manually specify target all the time.
 
-
-
+* trying to exchange obsolete relations with a static http repo will crash.
 
 Annexe
-=================================
+======
 
 .. toctree::
    :maxdepth: 1

File contents unchanged.

Add a comment to this file

docs/obs-implementation.rst

File contents unchanged.

docs/tutorials/tutorial.t

-Mutable History and collaboration
-=====================================================================
 
-
-.. warning:: need heavy update
-
-
-Single Developer Usage
-======================
-
-This tutorial shows how to use evolution to replace the basics of *mq*.
-
-
-Amending a changeset
+Initial setup
 ---------------------
-
-
-First there is some setup phase you will understand later.
-
-there is a local repository and a remote one.
-
+.. Various setup
 
   $ cat >> $HGRCPATH << EOF
   > [ui]
   > amend = amend -d '0 0'
   > [extensions]
   > hgext.graphlog=
-  > hgext.rebase=
   > EOF
-  $ $(dirname $TESTDIR)/enable.sh >> $HGRCPATH 2> /dev/null
 
   $ hg init local
   $ cat >> local/.hg/hgrc << EOF
   > [paths]
   > remote = ../remote
+  > other = ../other
   > [ui]
   > user = Babar the King
   > EOF
   > user = Celestine the Queen
   > EOF
 
+  $ hg init other
+  $ cat >> other/.hg/hgrc << EOF
+  > [ui]
+  > user = Princess Flore
+  > EOF
+
+
+This tutorial use the following configuration for Mercurial:
+
+A compact log template with phase data:
+
+  $ hg showconfig ui
+  ui.slash=True
+  ui.logtemplate="{node|short} ({phase}): {desc}\n"
+
+Improved git format diff:
+
+  $ hg showconfig diff
+  diff.git=1
+
+And the graphlog extension
+  $ hg showconfig extensions
+  extensions.hgext.graphlog=
+
+And of course, we anabled the experimental extensions for mutable history:
+
+  $ $(dirname $TESTDIR)/enable.sh >> $HGRCPATH 2> /dev/null
+
+
+-----------------------
+Single Developer Usage
+-----------------------
+
+This tutorial shows how to use evolution to rewrite history locally.
+
+
+Fixing mistake with `hg amend`
+--------------------------------
+
+We are versionning a shopping list
+
   $ cd local
-
-You can reopen you eyes.
-
-Now we make a first version of our shopping list.
-
   $ cat  >> shopping << EOF
   > Spam
   > Whizzo butter
   $ hg commit -A -m "Monthy Python Shopping list"
   adding shopping
 
-We share this first version with the outside.
+Its first version is shared with the outside.
 
   $ hg push remote
   pushing to $TESTTMP/remote
   > EOF
   $ hg commit -m "adding fruit"
 
-I now have the following history:
+This history is very linear
 
-  $ hg log
-  d85de4546133 (draft): adding fruit
-  4d5dc8187023 (draft): adding condiment
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg glog
+  @  d85de4546133 (draft): adding fruit
+  |
+  o  4d5dc8187023 (draft): adding condiment
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
-But, I just notice, I made a typo in Banana.
+But a typo was made in Babanas!
 
   $ hg export tip
   # HG changeset patch
   +Pear
   +Apple
 
-The faulty changeset is in the "draft" phase because he was not exchanged with the outside. The first one have been exchanged and is an immutable public changeset
+The faulty changeset is in the "draft" phase because he was not exchanged with
+the outside. The first one have been exchanged and is an immutable public
+changeset.
 
-  $ hg log
-  d85de4546133 (draft): adding fruit
-  4d5dc8187023 (draft): adding condiment
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg glog
+  @  d85de4546133 (draft): adding fruit
+  |
+  o  4d5dc8187023 (draft): adding condiment
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 hopefully. I can use hg amend to rewrite my faulty changeset!
 
 
 A new changeset with the right diff replace the wrong one.
 
-  $ hg log
-  0cacb48f4482 (draft): adding fruit
-  4d5dc8187023 (draft): adding condiment
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg glog
+  @  0cacb48f4482 (draft): adding fruit
+  |
+  o  4d5dc8187023 (draft): adding condiment
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
   $ hg export tip
   # HG changeset patch
   # User test
 
 While I was working on my list. someone help made a change remotly.
 
-close your eyes
-
   $ cd ../remote
   $ hg up -q
   $ sed -i'' -e 's/Spam/Spam Spam Spam/' shopping
   $ hg ci -m 'SPAM'
   $ cd ../local
 
-open your eyes
+I'll get this remote changeset when pulling
 
   $ hg pull remote
   pulling from $TESTTMP/remote
   added 1 changesets with 1 changes to 1 files (+1 heads)
   (run 'hg heads .' to see heads, 'hg merge' to merge)
 
-I now have a new heads. Note that the remote head is immutable
+I now have a new heads. Note that this remote head is immutable
 
-  $ hg log
-  9ca060c80d74 (public): SPAM
-  0cacb48f4482 (draft): adding fruit
-  4d5dc8187023 (draft): adding condiment
-  7e82d3f3c2cb (public): Monthy Python Shopping list
   $ hg log -G
   o  9ca060c80d74 (public): SPAM
   |
 
 My local work is now rebased on the remote one.
 
-  $ hg log
-  387187ad9bd9 (draft): adding fruit
-  dfd3a2d7691e (draft): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
   $ hg log -G
   @  387187ad9bd9 (draft): adding fruit
   |
   > boat
   > EOF
   $ hg ci -m 'transport'
-  $ hg log
-  d58c77aa15d7 (draft): transport
-  387187ad9bd9 (draft): adding fruit
-  dfd3a2d7691e (draft): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  @  d58c77aa15d7 (draft): transport
+  |
+  o  387187ad9bd9 (draft): adding fruit
+  |
+  o  dfd3a2d7691e (draft): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 I have a new commit but I realize that don't want it. (transport shop list does
 not fit well in my standard shopping list)
 
-  $ hg kill . # . is for working directory parent.
+  $ hg kill . # . is for working directory parent
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   working directory now at 387187ad9bd9
 
 The silly changeset is gone.
 
-  $ hg log
-  387187ad9bd9 (draft): adding fruit
-  dfd3a2d7691e (draft): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  @  387187ad9bd9 (draft): adding fruit
+  |
+  o  dfd3a2d7691e (draft): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 Reordering changeset
 ------------------------
 
 
-We create two changeset.
+We create two changesets.
 
 
   $ cat >> shopping << EOF
 
   $ sed -i'' -e 's/Spam/Spam Spam Spam/g' shopping
   $ hg ci -m 'SPAM SPAM'
-  $ hg log
-  c48f32fb1787 (draft): SPAM SPAM
-  8d39a843582d (draft): bathroom stuff
-  387187ad9bd9 (draft): adding fruit
-  dfd3a2d7691e (draft): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  @  c48f32fb1787 (draft): SPAM SPAM
+  |
+  o  8d39a843582d (draft): bathroom stuff
+  |
+  o  387187ad9bd9 (draft): adding fruit
+  |
+  o  dfd3a2d7691e (draft): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 .. note: don't amend changeset 7e82d3f3c2cb or 9ca060c80d74 as they are
 immutable.
 
-I now want to push to remote all my change but the bathroom one that i'm not totally happy with yet.
-
-To be able to push "SPAM SPAM" I need a version of "SPAM SPAM" not children of "bathroom stuff"
+I now want to push to remote all my change but the bathroom one that i'm not
+totally happy with yet. To be able to push "SPAM SPAM" I need a version of "SPAM SPAM" not children of
+"bathroom stuff"
 
 You can use 'rebase -r' or 'graft -O' for that:
 
 
 We have a new SPAM SPAM version without the bathroom stuff
 
-  $ grep Spam shopping  # enouth spamm
+  $ grep Spam shopping  # enouth spam
   Spam Spam Spam Spam Spam Spam Spam Spam Spam
   $ grep Toothbrush shopping # no Toothbrush
   [1]
   $ hg rebase -Dr 8d39a843582d -d a2fccc2e7b08
   merging shopping
   $ hg phase --draft .
+  $ hg log -G
+  @  8a79ae8b029e (draft): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
 
 
 Splitting change
 
 To be done (currently achieve with "revert + debugobsolete" or "rebase --collapse")
 
-collaboration
-====================
+
+
+
+
+
+-----------------------
+Collaboration
+-----------------------
 
 
 sharing mutable changeset
   $ cd ../remote
   $ hg -R ../local/ showconfig phases
 
-the localrepo does not have any specific configuration for `phases.publish`. It is ``true`` by default.
+the localrepo does not have any specific configuration for `phases.publish`. It
+is ``true`` by default.
 
   $ hg pull local
   pulling from $TESTTMP/local
   adding file changes
   added 1 changesets with 1 changes to 1 files
   (run 'hg update' to get a working copy)
-  $ hg log
-  8a79ae8b029e (public): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  o  8a79ae8b029e (public): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  @  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 
 
 
   $ hg rollback
   repository tip rolled back to revision 4 (undo pull)
-  $ hg log
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  @  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
-Let's make thz local repo "non publishing"
+Let's make the local repo "non publishing"
 
   $ echo "[phases]\npublish=false" >> ../local/.hg/hgrc
   $ echo "[phases]\npublish=false" >> .hg/hgrc
   adding file changes
   added 1 changesets with 1 changes to 1 files
   (run 'hg update' to get a working copy)
-  $ hg log
-  8a79ae8b029e (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  o  8a79ae8b029e (draft): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  @  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 Rebasing unstable change after pull
 ----------------------------------------------
 
-Remotely someone add a new changeset on top of our mutable "bathroom" on.
+Remotely someone add a new changeset on top of the mutable "bathroom" on.
 
   $ hg up 8a79ae8b029e -q
   $ cat >> shopping << EOF
   > Lion
   > Bear
   > EOF
-  $ hg ci -m 'animals' -q # XXX remove the -q
+  $ hg ci -m 'animals'
 
-While this time locally, we updated "bathroom changeset"
+But at the same time, locally, this same "bathroom changeset" was updated.
 
   $ cd ../local
   $ hg up 8a79ae8b029e -q
   $ sed -i'' -e 's/... More bathroom stuff to come/Bath Robe/' shopping
   $ hg amend
-  $ hg log
-  ffa278c50818 (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  @  ffa278c50818 (draft): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 
 When we pull from remote again we get an unstable state!
   added 1 changesets with 1 changes to 1 files (+1 heads)
   (run 'hg heads .' to see heads, 'hg merge' to merge)
   1 new unstables changesets
-  $ hg log -r 'extinct()'
-  $ hg log
-  9ac5d0e790a2 (draft): animals
-  ffa278c50818 (draft): bathroom stuff
-  8a79ae8b029e (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
 
 
 The new changeset "animal" is based one an old changeset of "bathroom". You can
-see both version showing up the log.
+see both version showing up in the log.
 
-  $ hg glog
+  $ hg log -G
   o  9ac5d0e790a2 (draft): animals
   |
   | @  ffa278c50818 (draft): bathroom stuff
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
 
-In hgview there is a nice doted relation highlighting ffa278c50818  is a new
-version of 8a79ae8b029e. this is not yet ported to graphlog.
+The older version 8a79ae8b029e never ceased to exist in the local repo. It was
+jsut hidden and excluded from pull and push.
+
+.. note:: In hgview there is a nice doted relation highlighting ffa278c50818  as a new version of 8a79ae8b029e. this is not yet ported to graphlog.
+
+Their is **unstable** changeset in this history now. Mercurial will refuse to
+share it with the outside:
+
+  $ hg push other
+  pushing to $TESTTMP/other
+  searching for changes
+  abort: Trying to push unstable changeset: 9ac5d0e790a2!
+  (use 'hg stabilize' to get a stable history (or --force to proceed))
+  [255]
+ 
+
+
 
 To resolve this unstable state, you need to rebase 9ac5d0e790a2 onto
-ffa278c50818 the "hg stabilize" command will make this for you. It has a
---dry-run option to only suggest the next move
+ffa278c50818 the "hg stabilize" command will make this for you.
+
+It has a --dry-run option to only suggest the next move.
 
   $ hg stabilize --dry-run
   move:[15] animals
   atop:[14] bathroom stuff
   hg rebase -Dr 9ac5d0e790a2 -d ffa278c50818
 
-
 Let's do it
 
   $ hg rebase -Dr 9ac5d0e790a2 -d ffa278c50818
   merging shopping
 
-The old version of bathroom is hidden again now.
+The old version of bathroom is hidden again.
 
-  $ hg log
-  437efbcaf700 (draft): animals
-  ffa278c50818 (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  @  437efbcaf700 (draft): animals
+  |
+  o  ffa278c50818 (draft): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 
 We can push this evolution to remote
 
-  $ hg push -f remote # XXX should not require -f
+  $ hg push remote
   pushing to $TESTTMP/remote
   searching for changes
   adding changesets
 remote get a warning that current working directory is based on an obsolete changeset
 
   $ cd ../remote
-  $ hg up . # XXX "loulz"
-  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg pull local # we up again to trigger the warning. it was displayed during the push
+  pulling from $TESTTMP/local
+  searching for changes
+  no changes found
   Working directory parent is obsolete
 
   $ hg up 437efbcaf700
   $ sed -i'' -e 's/Spam/Spam Spam Spam Spam/g' shopping
   $ hg commit -m "SPAM SPAM SPAM"
 
-Work I can keep getting localy
+I'm pulling its work locally.
 
   $ cd ../local
   $ hg pull remote
   adding file changes
   added 1 changesets with 1 changes to 1 files
   (run 'hg update' to get a working copy)
-  $ hg log
-  ae45c0c3092a (draft): SPAM SPAM SPAM
-  437efbcaf700 (draft): animals
-  ffa278c50818 (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  o  ae45c0c3092a (draft): SPAM SPAM SPAM
+  |
+  @  437efbcaf700 (draft): animals
+  |
+  o  ffa278c50818 (draft): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 In the mean time I noticed you can't buy animals in a super market and I kill the animal changeset:
 
 The animals changeset is still displayed because the "SPAM SPAM SPAM" changeset
 is neither dead or obsolete.  My repository is in an unstable state again.
 
-  $ hg log
-  ae45c0c3092a (draft): SPAM SPAM SPAM
-  437efbcaf700 (draft): animals
-  ffa278c50818 (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
-
-  $ hg log -r 'unstable()'
-  ae45c0c3092a (draft): SPAM SPAM SPAM
-
   $ hg log -G
   o  ae45c0c3092a (draft): SPAM SPAM SPAM
   |
   |
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
-# XXX make this work
+
+  $ hg log -r 'unstable()'
+  ae45c0c3092a (draft): SPAM SPAM SPAM
+
+# XXX make kill stabilization works
 #  $ hg stabilize --any
 #  merging shopping
 
   grafting revision 17
   merging shopping
 
-  $ hg log
-  20de1fb1cec5 (draft): SPAM SPAM SPAM
-  ffa278c50818 (draft): bathroom stuff
-  a2fccc2e7b08 (public): SPAM SPAM
-  387187ad9bd9 (public): adding fruit
-  dfd3a2d7691e (public): adding condiment
-  9ca060c80d74 (public): SPAM
-  7e82d3f3c2cb (public): Monthy Python Shopping list
+  $ hg log -G
+  @  20de1fb1cec5 (draft): SPAM SPAM SPAM
+  |
+  o  ffa278c50818 (draft): bathroom stuff
+  |
+  o  a2fccc2e7b08 (public): SPAM SPAM
+  |
+  o  387187ad9bd9 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
 
 
 Handling Conflicting amend
 
 We can detect that multiple diverging//conflicting amend have been made. There
 will be a "evol-merge" command to merge conflicting amend
+
+This command is not ready yet.

docs/unstability.rst

+
 -----------------------------------
-The Unstability Principle
+The instability Principle
 -----------------------------------
 
 
 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*:
 
     * 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..
 
 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.
 
-stable situation to stable situation
+::
 
-Distributed means that you do not control what happen outside your repository:
+  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.
 
-* phase.
-* overwrite.
 
+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.**
 
-Boiler Plate
+Do not rewrite exchanged changeset
+```````````````````````````````````
+
+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.
+
+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
 
+It is possible to collaborate over versioned mq! But you are going ahead a lot
+of troubles.
 
-Deny a lot of option
-````````````````````````````
-
-
-
-[] 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.
 
-No instability is still a bad situation.
-No instability is still a bad situation that should be avoided.
+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.
+
+
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-'''A set of command to make changeset evolve.'''
+'''a set of commands to handle changeset mutation'''
 
 from mercurial import cmdutil
 from mercurial import scmutil
     ],
     '')
 def stabilize(ui, repo, **opts):
-    """move changeset out of they unstable state
+    """move changeset out of the unstable state
 
     By default only works on changeset that will be rebase on ancestors of the
     current working directory parent (included)"""
 
 @command('^gdown',
     [],
-    'update to working directory parent and display summary lines')
+    '')
 def cmdgdown(ui, repo):
+    """update to working directory parent and display summary lines"""
     wkctx = repo[None]
     wparents = wkctx.parents()
     if len(wparents) != 1:
 
 @command('^gup',
     [],
-    'update to working directory children and display summary lines')
+    '')
 def cmdup(ui, repo):
+    """update to working directory children and display summary lines"""
     wkctx = repo[None]
     wparents = wkctx.parents()
     if len(wparents) != 1:

hgext/obsolete.py

 changeset history. Standard changeset history versions files. The *obsolete*
 relation versions changesets.
 
-:obsolete:     a changeset that have been replace by another one.
-:unstable:     a non-obsolet changeset based on another one.
+:obsolete:     a changeset that has been replaced by another one.
+:unstable:     a changeset that is not obsolete but has an obsolete ancestor.
 :suspended:    an obsolete changeset with unstable descendant.
-:extinct:      an obsolete changeset without unstable descendant
+:extinct:      an obsolete changeset without unstable descendant.
                (subject to garbage collection)
 
 Another name for unstable could be out of sync.
 
 
-
 Usage and Feature
 =================
 
-
 Display and Exchange
-....................
+--------------------
 
 obsolete changesets are hidden. (except if they have non obsolete changeset)
 
-obsolete changesets are currently not exchange. This will probably change later
-but it was the simpler solution for now.
+obsolete changesets are not exchanged. This will probably change later but it
+was the simpler solution for now.
 
 New commands
-............
+------------
 
-a ``debugobsolete`` command has been added.
-
-It add an obsolete relation between too relation.
+A ``debugobsolete`` command was added. It adds an obsolete relation between two
+nodes.
 
 Context object
-..............
+--------------
 
-Context gain a ``obsolete`` method that return True if a changeset is obsolete
-False otherwise.
+Context gains a ``obsolete`` method that will return True if a changeset is
+obsolete False otherwise.
 
 revset
-......
+------
 
 Add an ``obsolete()`` entry.
 
 repo extension
-..............
+--------------
 
 To Do
------
+~~~~~
 
-* refuse to obsolete published changesets
+- refuse to obsolete published changesets
 
-* handle split
+- handle split
 
-* handle conflict
+- handle conflict
 
-* handle unstable // out of sync
+- handle unstable // out of sync
 
 """
+
 import os
 try:
     from cStringIO import StringIO
                     journalpath = self.sjoin(journalname)
                     util.copyfile(filepath, journalpath)
 
-        else: # XXX remove this bloc while breaking support to Hg 2.1
+        else: # XXX removing this bloc will break Hg 2.1 support
             def _writejournal(self, desc):
                 """wrapped version of _writejournal that save obsolete data"""
                 entries = list(o_writejournal(desc))
 
         @storecache('00changelog.i')
         def changelog(self):
-            # << copy pasted from mercurila source
+            # << copy pasted from mercurial source
             c = changelog.changelog(self.sopener)
             if 'HG_PENDING' in os.environ:
                 p = os.environ['HG_PENDING']
                 phases.retractboundary(repo, 2, expobs)
             finally:
                 lock.release()
-
-
+"""synchronize patches queues and evolving changesets"""
 
 import re
 from cStringIO import StringIO
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.