diff -r 24346b78cd99 -r 4e3f25ba5401 doc/simple-tuto.t --- a/doc/simple-tuto.t Wed Mar 21 11:57:03 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,702 +0,0 @@ -Mutable History and collaboration -===================================================================== - - -History mutation -===================== - -.. Albert Beugras - -.. René de Robert - - -Here is small introduction of - -Single Developer Usage -====================== - -This tutorial shows how to use evolution to replace the basics of *mq*. - - -Amending a changeset ---------------------- - - -First there is some setup phase you will understand later. - -there is a local repository and a remote one. - -Please close your eyes. - - $ hg init local - $ cat >> local/.hg/hgrc << EOF - > [paths] - > remote = ../remote - > [ui] - > user = Albert Beugras - > [diff] - > git = 1 - > [alias] - > amend = amend -d '0 0' - > tlog = log --template "{node|short}: '{desc}'\n" - > ttlog = log --template "{node|short}: '{desc}' ({state})\n" - > tglog = log -G --template "{node|short}: '{desc}' {branches}\n" - > [extensions] - > hgext.graphlog= - > hgext.rebase= - > EOF - $ echo "states=$(echo $(dirname $TESTDIR))/hgext/states.py" >> local/.hg/hgrc - $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> local/.hg/hgrc - $ echo "evolution=$(echo $(dirname $TESTDIR))/hgext/evolution.py" >> local/.hg/hgrc - $ hg init remote - $ cat >> remote/.hg/hgrc << EOF - > [paths] - > local = ../local - > [ui] - > user = René de Robert - > [diff] - > git = 1 - > [alias] - > amend = amend -d '0 0' - > tlog = log --template "{node|short}: '{desc}' {branches}\n" - > ttlog = log --template "{node|short}: '{desc}' {state}\n" - > tglog = log -G --template "{node|short}: '{desc}' {branches}\n" - > [extensions] - > hgext.graphlog= - > hgext.rebase= - > EOF - $ echo "states=$(echo $(dirname $TESTDIR))/hgext/states.py" >> remote/.hg/hgrc - $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> remote/.hg/hgrc - $ echo "evolution=$(echo $(dirname $TESTDIR))/hgext/evolution.py" >> remote/.hg/hgrc - $ cd local - -You can reopen you eyes. - -Now we make a first version of our shopping list. - - $ cat >> shopping << EOF - > Spam - > Whizzo butter - > Albatross - > Rat (rather a lot) - > Jugged fish - > Blancmange - > Salmon mousse - > EOF - $ hg commit -A -m "Monthy Python Shopping list" - adding shopping - -We share this first version with the outside. - - $ hg push remote - pushing to $TESTTMP/remote - searching for changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - -Later I add additional item to my list - - $ cat >> shopping << EOF - > Egg - > Suggar - > Vinegar - > Oil - > EOF - $ hg commit -m "adding condiment" - $ cat >> shopping << EOF - > Bananos - > Pear - > Apple - > EOF - $ hg commit -m "adding fruit" - -I now have the following history: - - $ hg tlog - d85de4546133: 'adding fruit' - 4d5dc8187023: 'adding condiment' - 7e82d3f3c2cb: 'Monthy Python Shopping list' - -But, I just notice, I made a typo in Banana. - - $ hg export tip - # HG changeset patch - # User test - # Date 0 0 - # Node ID d85de4546133030c82d257bbcdd9b1b416d0c31c - # Parent 4d5dc81870237d492284826e21840b2ca00e26d1 - adding fruit - - diff --git a/shopping b/shopping - --- a/shopping - +++ b/shopping - @@ -9,3 +9,6 @@ - Suggar - Vinegar - Oil - +Bananos - +Pear - +Apple - -hopefully. I can use hg amend to rewrite my faulty changeset! - - $ sed -i'' -e s/Bananos/Banana/ shopping - $ hg diff - diff --git a/shopping b/shopping - --- a/shopping - +++ b/shopping - @@ -9,6 +9,6 @@ - Suggar - Vinegar - Oil - -Bananos - +Banana - Pear - Apple - $ hg amend - abort: can not rewrite immutable changeset d85de4546133 - [255] - -By default all changeset are considered "published" and can't be rewrittent. - - $ hg ttlog - -You need to enable a mutable state in your repo the "ready" one - - $ hg states ready --clever - $ hg ttlog - d85de4546133: 'adding fruit' (ready) - 4d5dc8187023: 'adding condiment' (ready) - 7e82d3f3c2cb: 'Monthy Python Shopping list' (published) - -Notice that changeset you already shared with the outside have been keep -published. - -The changeset we want to rewrite is now in a mutable state. - - $ hg amend - -A new changeset with the right diff replace the wrong one. - - $ hg tlog - 0cacb48f4482: 'adding fruit' - 4d5dc8187023: 'adding condiment' - 7e82d3f3c2cb: 'Monthy Python Shopping list' - $ hg export tip - # HG changeset patch - # User test - # Date 0 0 - # Node ID 0cacb48f44828d2fd31c4e45e18fde32a5b2f07b - # Parent 4d5dc81870237d492284826e21840b2ca00e26d1 - adding fruit - - diff --git a/shopping b/shopping - --- a/shopping - +++ b/shopping - @@ -9,3 +9,6 @@ - Suggar - Vinegar - Oil - +Banana - +Pear - +Apple - -Getting Ride of branchy history ----------------------------------- - -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 - - $ 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) - -I now have a new heads. Note that the remote head is immutable - - $ hg ttlog - 9ca060c80d74: 'SPAM' (published) - 0cacb48f4482: 'adding fruit' (ready) - 4d5dc8187023: 'adding condiment' (ready) - 7e82d3f3c2cb: 'Monthy Python Shopping list' (published) - $ hg tglog -r "::(9ca060c80d74 + 0cacb48f4482)" - o 9ca060c80d74: 'SPAM' - | - | @ 0cacb48f4482: 'adding fruit' - | | - | o 4d5dc8187023: 'adding condiment' - |/ - o 7e82d3f3c2cb: 'Monthy Python Shopping list' - - -instead of merging my head with the new one. I'm going to rebase my work - - $ hg diff - $ hg rebase -d 9ca060c80d74 -s 4d5dc8187023 - merging shopping - merging shopping - merging shopping - merging shopping - - -My local work is now rebase on the remote one. - - $ hg kill e7a71e229632 ad97bbd3e37d # XXX fix me instead - $ hg ttlog - 387187ad9bd9: 'adding fruit' (ready) - dfd3a2d7691e: 'adding condiment' (ready) - 9ca060c80d74: 'SPAM' (published) - 7e82d3f3c2cb: 'Monthy Python Shopping list' (published) - $ hg tglog -r '::.' - @ 387187ad9bd9: 'adding fruit' - | - o dfd3a2d7691e: 'adding condiment' - | - o 9ca060c80d74: 'SPAM' - | - o 7e82d3f3c2cb: 'Monthy Python Shopping list' - - -Removing changeset ------------------------- - -I add new item to my list - - $ cat >> shopping << EOF - > car - > bus - > plane - > boat - > EOF - $ hg ci -m 'transport' - $ hg ttlog - d58c77aa15d7: 'transport' (ready) - 387187ad9bd9: 'adding fruit' (ready) - dfd3a2d7691e: 'adding condiment' (ready) - 9ca060c80d74: 'SPAM' (published) - 7e82d3f3c2cb: 'Monthy Python Shopping list' (published) - -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. - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - working directory now at 387187ad9bd9 - -The silly changeset is gone. - - $ hg ttlog - 387187ad9bd9: 'adding fruit' (ready) - dfd3a2d7691e: 'adding condiment' (ready) - 9ca060c80d74: 'SPAM' (published) - 7e82d3f3c2cb: 'Monthy Python Shopping list' (published) - -Reordering changeset ------------------------- - - -We create two changeset. - - - $ cat >> shopping << EOF - > Shampoo - > Toothbrush - > ... More bathroom stuff to come - > Towel - > Soap - > EOF - $ hg ci -m 'bathroom stuff' -q # XXX remove the -q - - $ sed -i'' -e 's/Spam/Spam Spam Spam/g' shopping - $ hg ci -m 'SPAM SPAM' - $ hg ttlog - c48f32fb1787: 'SPAM SPAM' (ready) - 8d39a843582d: 'bathroom stuff' (ready) - 387187ad9bd9: 'adding fruit' (ready) - dfd3a2d7691e: 'adding condiment' (ready) - 9ca060c80d74: 'SPAM' (published) - 7e82d3f3c2cb: 'Monthy Python Shopping list' (published) - -.. 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" - -You can use rebase or relocate for that: - - $ hg relocate 'p1(8d39a843582d)' --traceback - merging shopping - $ hg tglog -r '::(. + 8d39a843582d)' - @ 02e33960e937: 'SPAM SPAM' - | - | o 8d39a843582d: 'bathroom stuff' - |/ - o 387187ad9bd9: 'adding fruit' - | - o dfd3a2d7691e: 'adding condiment' - | - o 9ca060c80d74: 'SPAM' - | - o 7e82d3f3c2cb: 'Monthy Python Shopping list' - - -We have a new SPAM SPAM version without the bathroom stuff - - $ grep Spam shopping # enouth spamm - Spam Spam Spam Spam Spam Spam Spam Spam Spam - $ grep Toothbrush shopping # no Toothbrush - [1] - $ hg export . - # HG changeset patch - # User test - # Date 0 0 - # Node ID 02e33960e937ad1bd59241ebdafd7a2494240ddf - # Parent 387187ad9bd9d8f9a00a9fa804a26231db547429 - SPAM SPAM - - diff --git a/shopping b/shopping - --- a/shopping - +++ b/shopping - @@ -1,4 +1,4 @@ - -Spam Spam Spam - +Spam Spam Spam Spam Spam Spam Spam Spam Spam - Whizzo butter - Albatross - Rat (rather a lot) - -we can now push our change: - - $ hg push -r . remote - pushing to $TESTTMP/remote - searching for changes - adding changesets - adding manifests - 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 ----------------------------- - -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. - -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 -