changeset 95:5dcece86aeb0

improve tuto
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Wed, 21 Sep 2011 03:52:13 +0200
parents 780a222d547d
children d5170cc7881c
files doc/simple-tuto.t hgext/obsolete.py
diffstat 2 files changed, 326 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/doc/simple-tuto.t
+++ b/doc/simple-tuto.t
@@ -142,7 +142,7 @@
 
 hopefully. I can use hg amend to rewrite my faulty changeset!
 
-  $ sed -i'' s/Bananos/Banana/ shopping
+  $ sed -i'' -e s/Bananos/Banana/ shopping
   $ hg diff
   diff --git a/shopping b/shopping
   --- a/shopping
@@ -212,7 +212,7 @@
 
   $ cd ../remote
   $ hg up -q
-  $ sed -i'' 's/Spam/Spam Spam Spam/' shopping
+  $ sed -i'' -e 's/Spam/Spam Spam Spam/' shopping
   $ hg ci -m 'SPAM'
   $ cd ../local
 
@@ -273,7 +273,7 @@
   
 
 Removing changeset
-========================
+------------------------
 
 I add new item to my list
 
@@ -307,24 +307,26 @@
   7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
 
 Reordering changeset
-========================
+------------------------
 
 
 We create two changeset.
 
 
   $ cat >> shopping << EOF
+  > Shampoo
   > Toothbrush
+  > ... More bathroom stuff to come
   > Towel
-  > ... More bathroom stuff to come
+  > Soap
   > EOF
   $ hg ci -m 'bathroom stuff' -q # XXX remove the -q
 
-  $ sed -i'' 's/Spam/Spam Spam Spam/g' shopping
+  $ sed -i'' -e 's/Spam/Spam Spam Spam/g' shopping
   $ hg ci -m 'SPAM SPAM'
   $ hg ttlog
-  d19fa1996cc7: 'SPAM SPAM' (ready)
-  e64eb196cfd1: 'bathroom stuff' (ready)
+  c48f32fb1787: 'SPAM SPAM' (ready)
+  8d39a843582d: 'bathroom stuff' (ready)
   387187ad9bd9: 'adding fruit' (ready)
   dfd3a2d7691e: 'adding condiment' (ready)
   9ca060c80d74: 'SPAM' (published)
@@ -339,12 +341,12 @@
 
 You can use rebase or relocate for that:
 
-  $ hg relocate 'p1(e64eb196cfd1)' --traceback
+  $ hg relocate 'p1(8d39a843582d)' --traceback
   merging shopping
-  $ hg tglog -r '::(. + e64eb196cfd1)'
-  @  e96fa9b78e3d: 'SPAM SPAM'
+  $ hg tglog -r '::(. + 8d39a843582d)'
+  @  02e33960e937: 'SPAM SPAM'
   |
-  | o  e64eb196cfd1: 'bathroom stuff'
+  | o  8d39a843582d: 'bathroom stuff'
   |/
   o  387187ad9bd9: 'adding fruit'
   |
@@ -365,7 +367,7 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID e96fa9b78e3d2e21b604d4e05582bb1906a9bc59
+  # Node ID 02e33960e937ad1bd59241ebdafd7a2494240ddf
   # Parent  387187ad9bd9d8f9a00a9fa804a26231db547429
   SPAM SPAM
   
@@ -389,12 +391,312 @@
   adding file changes
   added 3 changesets with 3 changes to 1 files
 
+for simplicity shake we relocate the bathroom changeset
+
+  $ hg relocate -r 8d39a843582d 02e33960e937
+  merging shopping
+
+
+Splitting change
+------------------
+
+To be done (currently achieve with "two commit + debugobsolete")
+
+Collapsing change
+------------------
+
+To be done (currently achieve with "revert + debugobsolete" or "rebase --collapse")
+
 collaboration
 ====================
 
 
+sharing mutable changeset
+----------------------------
 
-We create a central repo (because most workflow include this central repo
+To share mutable changeset with other just check that both have the "ready"
+state activated. Otherwise you will get the previously observe behavior where
+exchanged changeset are automatically published.
+
+  $ cd ../remote
+  $ hg states 
+  published
+
+The remote repository have only the immutable "published" state activated. Any
+changeset echanged from "local" to "remote" will be set in the publised state:
+
+  $ hg -R ../local push -f remote # XXX we should pull but the support is awful
+  pushing to $TESTTMP/remote
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ hg ttlog
+  a3515e5d0332: 'bathroom stuff' published
+  02e33960e937: 'SPAM SPAM' published
+  387187ad9bd9: 'adding fruit' published
+  dfd3a2d7691e: 'adding condiment' published
+  9ca060c80d74: 'SPAM' published
+  7e82d3f3c2cb: 'Monthy Python Shopping list' published
+
+
+
+We do not want to publish the "bathroom changeset". Let's rollback the last transaction
+
+  $ hg rollback
+  repository tip rolled back to revision 4 (undo push)
+  working directory now based on revision 1
+  $ hg ttlog
+  02e33960e937: 'SPAM SPAM' published
+  387187ad9bd9: 'adding fruit' published
+  dfd3a2d7691e: 'adding condiment' published
+  9ca060c80d74: 'SPAM' published
+  7e82d3f3c2cb: 'Monthy Python Shopping list' published
+  $ rm ../local/.hg/states/published-heads     # XXX USE --exact
+  $ hg -R ../local publish 02e33960e937 # XXX FIX THE BUG
+
+To enable the mutable "ready" state in a repository, use the states command.
+
+  $ hg states ready
+  $ hg states 
+  published
+  ready
+
+I can nom exchange mutable changeset between "remote" and "local" repository.
+
+  $ hg pull local # XXX We pull too much stuff
+  pulling from $TESTTMP/local
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 10 changesets with 10 changes to 1 files (+5 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg ttlog
+  a3515e5d0332: 'bathroom stuff' ready
+  02e33960e937: 'SPAM SPAM' published
+  387187ad9bd9: 'adding fruit' published
+  dfd3a2d7691e: 'adding condiment' published
+  9ca060c80d74: 'SPAM' published
+  7e82d3f3c2cb: 'Monthy Python Shopping list' published
+
+Rebasing out-of-sync change after update
+----------------------------------------------
+
+Remotely someone add a new changeset on top of our mutable "bathroom" on.
+
+  $ hg up a3515e5d0332 -q
+  $ cat >> shopping << EOF
+  > Giraffe
+  > Rhino
+  > Lion
+  > Bear
+  > EOF
+  $ hg ci -m 'animals' -q # XXX remove the -q
+
+While this time locally, we rebase the updated the "bathroom changeset"
+
+  $ cd ../local
+  $ hg up a3515e5d0332 -q
+  $ sed -i'' -e 's/... More bathroom stuff to come/Bath Robe/' shopping
+  $ hg amend
+  $ hg tlog
+  962d3a7d27ad: 'bathroom stuff'
+  02e33960e937: 'SPAM SPAM'
+  387187ad9bd9: 'adding fruit'
+  dfd3a2d7691e: 'adding condiment'
+  9ca060c80d74: 'SPAM'
+  7e82d3f3c2cb: 'Monthy Python Shopping list'
+
+
+When we pull from remote again we get an unstable state!
+
+  $ hg pull remote
+  pulling from $TESTTMP/remote
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
+  $ hg tlog
+  0b061760b677: 'animals'
+  962d3a7d27ad: 'bathroom stuff'
+  a3515e5d0332: 'bathroom stuff'
+  02e33960e937: 'SPAM SPAM'
+  387187ad9bd9: 'adding fruit'
+  dfd3a2d7691e: 'adding condiment'
+  9ca060c80d74: 'SPAM'
+  7e82d3f3c2cb: '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.
+
+  $ hg tglog -r '::(962d3a7d27ad + 0b061760b677)'
+  o  0b061760b677: 'animals'
+  |
+  | @  962d3a7d27ad: 'bathroom stuff'
+  | |
+  o |  a3515e5d0332: 'bathroom stuff'
+  |/
+  o  02e33960e937: 'SPAM SPAM'
+  |
+  o  387187ad9bd9: 'adding fruit'
+  |
+  o  dfd3a2d7691e: 'adding condiment'
+  |
+  o  9ca060c80d74: 'SPAM'
+  |
+  o  7e82d3f3c2cb: 'Monthy Python Shopping list'
+  
+
+In hgviewn there is a nice doted relation highlighting 962d3a7d27ad  is a new
+version of a3515e5d0332. this is not yet ported to graphlog.
 
-  $ cd ..
-  $ hg init central
+To resolve this unstable state, you need to relocate 0b061760b677 onto
+962d3a7d27ad the "hg evolve" will make the thinking for you and suggest it to
+you.
+
+  $ hg evolve
+  hg relocate --rev 0b061760b677 962d3a7d27ad
+
+Let's do it
+
+  $ hg relocate --rev 0b061760b677 962d3a7d27ad
+  merging shopping
+
+The old vesion of bathroom is hidden again now.
+
+  $ hg tlog
+  39a85a192689: 'animals'
+  962d3a7d27ad: 'bathroom stuff'
+  02e33960e937: 'SPAM SPAM'
+  387187ad9bd9: 'adding fruit'
+  dfd3a2d7691e: 'adding condiment'
+  9ca060c80d74: 'SPAM'
+  7e82d3f3c2cb: 'Monthy Python Shopping list'
+
+We can push this evolution to remote
+
+  $ hg push -f remote # XXX should not require -f
+  pushing to $TESTTMP/remote
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 1 files (+1 heads)
+
+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
+  Working directory parent is obsolete
+
+  $ hg up 39a85a192689
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Relocating out-of-sync change after kill
+----------------------------------------------
+
+The remote guy keep working
+
+  $ sed -i'' -e 's/Spam/Spam Spam Spam Spam/g' shopping
+  $ hg commit -m "SPAM SPAM SPAM"
+
+Work I can keep getting localy
+
+  $ cd ../local
+  $ hg pull remote
+  pulling from $TESTTMP/remote
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  (run 'hg update' to get a working copy)
+  $ hg tlog
+  e768beeb835c: 'SPAM SPAM SPAM'
+  39a85a192689: 'animals'
+  962d3a7d27ad: 'bathroom stuff'
+  02e33960e937: 'SPAM SPAM'
+  387187ad9bd9: 'adding fruit'
+  dfd3a2d7691e: 'adding condiment'
+  9ca060c80d74: 'SPAM'
+  7e82d3f3c2cb: '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:
+
+  $ hg kill 39a85a192689 # issue warning here
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory now at 962d3a7d27ad
+
+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 tlog 
+  e768beeb835c: 'SPAM SPAM SPAM'
+  39a85a192689: 'animals'
+  962d3a7d27ad: 'bathroom stuff'
+  02e33960e937: 'SPAM SPAM'
+  387187ad9bd9: 'adding fruit'
+  dfd3a2d7691e: 'adding condiment'
+  9ca060c80d74: 'SPAM'
+  7e82d3f3c2cb: 'Monthy Python Shopping list'
+  $ hg tglog  -r '::e768beeb835c'
+  o  e768beeb835c: 'SPAM SPAM SPAM'
+  |
+  o  39a85a192689: 'animals'
+  |
+  @  962d3a7d27ad: 'bathroom stuff'
+  |
+  o  02e33960e937: 'SPAM SPAM'
+  |
+  o  387187ad9bd9: 'adding fruit'
+  |
+  o  dfd3a2d7691e: 'adding condiment'
+  |
+  o  9ca060c80d74: 'SPAM'
+  |
+  o  7e82d3f3c2cb: 'Monthy Python Shopping list'
+  
+
+#  $ hg evolve # XXX not ready yet
+#  hg relocate --rev  e768beeb835c 962d3a7d27ad
+
+  $ hg relocate -r  e768beeb835c 'p1(39a85a192689)'
+  merging shopping
+
+  $ hg tlog 
+  19098f8178f3: 'SPAM SPAM SPAM'
+  962d3a7d27ad: 'bathroom stuff'
+  02e33960e937: 'SPAM SPAM'
+  387187ad9bd9: 'adding fruit'
+  dfd3a2d7691e: 'adding condiment'
+  9ca060c80d74: 'SPAM'
+  7e82d3f3c2cb: '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
+
+collaboration
+====================
+
+Turning changeset immutable
+----------------------------------------------
+
+* push on published//only repo
+
+* tag
+
+* explicite published command
+
+Handling Invalid amend on published changeset
+----------------------------------------------
+
+you can't amend published changeset. changeset that do this will have an "invalid amend" obsolete-status
+
--- a/hgext/obsolete.py
+++ b/hgext/obsolete.py
@@ -339,9 +339,14 @@
             self._obsobjrels.setdefault(obj, set()).add(sub)
             try:
                 if not self.nodestate(obj).mutable:
-                    self.ui.warn(
-                        _("%(sub)s try to obsolete immutable changeset %(obj)s\n")
-                        % {'sub': short(sub), 'obj': short(obj)})
+                    if sub is None:
+                        self.ui.warn(
+                            _("trying to kill immutable changeset %(obj)s\n")
+                            % {'obj': short(obj)})
+                    if sub is not None:
+                        self.ui.warn(
+                            _("%(sub)s try to obsolete immutable changeset %(obj)s\n")
+                            % {'sub': short(sub), 'obj': short(obj)})
                 self.changelog.hiddenrevs.add(repo[obj].rev())
             except (error.RepoLookupError, error.LookupError):
                 pass #unknow revision (but keep propagating the data