Mercurial > evolve
view docs/tutorials/tutorial.t @ 729:2e46caeb2890
push obsolescence marker before anything else
author | Pierre-Yves David <pierre-yves.david@logilab.fr> |
---|---|
date | Mon, 03 Jun 2013 15:03:55 +0200 |
parents | c56109c9aebf |
children | 4a74288c671c |
line wrap: on
line source
Initial setup ------------- This Mercurial configuration example is used for testing. .. Various setup $ cat >> $HGRCPATH << EOF > [ui] > logtemplate ="{node|short} ({phase}): {desc}\n" > [diff] > git = 1 > [alias] > # "-d '0 0'" means that the new commit will be at January 1st 1970. > # This is used for stable hash during test > amend = amend -d '0 0' > [extensions] > hgext.graphlog= > EOF $ hg init local $ cat >> local/.hg/hgrc << EOF > [paths] > remote = ../remote > other = ../other > [ui] > user = Babar the King > EOF $ hg init remote $ cat >> remote/.hg/hgrc << EOF > [paths] > local = ../local > [ui] > user = Celestine the Queen > EOF $ hg init other $ cat >> other/.hg/hgrc << EOF > [ui] > user = Princess Flore > EOF This tutorial uses 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 $ 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 Its first version is shared 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" This history is very linear $ hg glog @ d85de4546133 (draft): adding fruit | o 4d5dc8187023 (draft): adding condiment | o 7e82d3f3c2cb (public): Monthy Python Shopping list But a typo was made in Babanas! $ 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 The faulty changeset is in the "draft" phase because it has not been exchanged with the outside. The first one has been exchanged and is "public" (immutable). $ 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! $ 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 A new changeset with the right diff replace the wrong one. $ 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 # 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 rid of branchy history ---------------------------------- While I was working on my list. someone help made a change remotly. $ cd ../remote $ hg up -q $ sed -i'' -e 's/Spam/Spam Spam Spam/' shopping $ hg ci -m 'SPAM' $ cd ../local I'll get this remote changeset when pulling $ 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 this remote head is immutable $ hg log -G o 9ca060c80d74 (public): SPAM | | @ 0cacb48f4482 (draft): adding fruit | | | o 4d5dc8187023 (draft): adding condiment |/ o 7e82d3f3c2cb (public): 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 My local work is now rebased on the remote one. $ hg log -G @ 387187ad9bd9 (draft): adding fruit | o dfd3a2d7691e (draft): adding condiment | o 9ca060c80d74 (public): SPAM | o 7e82d3f3c2cb (public): Monthy Python Shopping list Removing changesets ------------------------ I add new item to my list $ cat >> shopping << EOF > car > bus > plane > boat > EOF $ hg ci -m 'transport' $ 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 prune . # . 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 -G @ 387187ad9bd9 (draft): adding fruit | o dfd3a2d7691e (draft): adding condiment | o 9ca060c80d74 (public): SPAM | o 7e82d3f3c2cb (public): Monthy Python Shopping list Reordering changesets ------------------------ We create two changesets. $ 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 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 changes except the bathroom one, which I'm not totally happy with yet. To be able to push "SPAM SPAM" I need a version of "SPAM SPAM" which is not a child of "bathroom stuff" You can use 'rebase -r' or 'graft -O' for that: $ hg up 'p1(8d39a843582d)' # going on "bathroom stuff" parent 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg graft -O c48f32fb1787 # moving "SPAM SPAM" to the working directory parent grafting revision 10 merging shopping $ hg log -G @ a2fccc2e7b08 (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 We have a new SPAM SPAM version without the bathroom stuff $ grep Spam shopping # enough spam 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 a2fccc2e7b08bbce6af7255b989453f7089e4cf0 # 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) To make sure I do not push unready changeset by mistake I set the "bathroom stuff" changeset in the secret phase. $ hg phase --force --secret 8d39a843582d we can now push our change: $ hg push 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 get the bathroom change in line again $ hg rebase -r 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 "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 others, just check that the repo you interact with is "not publishing". Otherwise you will get the previously observe behavior where exchanged changeset are automatically published. $ cd ../remote $ hg -R ../local/ showconfig phases the localrepo does not have any specific configuration for `phases.publish`. It is ``true`` by default. $ hg pull local pulling from $TESTTMP/local 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 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 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 pull) $ 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 the local repo "non publishing" $ echo '[phases]' >> ../local/.hg/hgrc $ echo 'publish=false' >> ../local/.hg/hgrc $ echo '[phases]' >> .hg/hgrc $ echo 'publish=false' >> .hg/hgrc $ hg showconfig phases phases.publish=false $ hg -R ../local/ showconfig phases phases.publish=false I can now exchange mutable changeset between "remote" and "local" repository. $ hg pull local pulling from $TESTTMP/local 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 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 the mutable "bathroom" on. $ hg up 8a79ae8b029e -q $ cat >> shopping << EOF > Giraffe > Rhino > Lion > Bear > EOF $ hg ci -m 'animals' 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 -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! $ 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) 1 new unstables changesets The new changeset "animal" is based on an old changeset of "bathroom". You can see both version showing up in the log. $ hg log -G o 9ac5d0e790a2 (draft): animals | | @ ffa278c50818 (draft): bathroom stuff | | x | 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 The older version 8a79ae8b029e never ceased to exist in the local repo. It was just hidden and excluded from pull and push. .. note:: In hgview there is a nice dotted relation highlighting ffa278c50818 as a new version of 8a79ae8b029e. This is not yet ported to ``hg log -G``. There is now an **unstable** changeset in this history. Mercurial will refuse to share it with the outside: $ hg push other pushing to $TESTTMP/other searching for changes abort: push includes an unstable changeset: 9ac5d0e790a2! (use 'hg stabilize' to get a stable history or --force to ignore warnings) [255] To resolve this unstable state, you need to rebase 9ac5d0e790a2 onto ffa278c50818. The "hg stabilize" command will do 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 -r 9ac5d0e790a2 -d ffa278c50818 Let's do it $ hg rebase -r 9ac5d0e790a2 -d ffa278c50818 merging shopping The old version of bathroom is hidden again. $ 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 remote 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 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 1 files updated, 0 files merged, 0 files removed, 0 files unresolved Relocating unstable change after prune ---------------------------------------------- The remote guy keep working $ sed -i'' -e 's/Spam/Spam Spam Spam Spam/g' shopping $ hg commit -m "SPAM SPAM SPAM" I'm pulling its work locally. $ 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 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 prune the animal changeset: $ hg prune 437efbcaf700 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory now at ffa278c50818 1 new unstables changesets 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 -G o ae45c0c3092a (draft): SPAM SPAM SPAM | x 437efbcaf700 (draft): animals | @ 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 $ hg log -r 'unstable()' ae45c0c3092a (draft): SPAM SPAM SPAM # XXX make prune stabilization works # $ hg stabilize --any # merging shopping $ hg graft -O ae45c0c3092a grafting revision 17 merging shopping $ 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 amendments have been made. There will be a "evol-merge" command to merge conflicting amendments. This command is not ready yet.