# HG changeset patch # User Pierre-Yves David # Date 1332862156 -7200 # Node ID 7151691b85efdd0bf2d2bcbbff7820e8a2de15bf # Parent 37d3300786a744c34a22f610ddc741a9ece3bac8# Parent 06c942f9bac6c4b80f8947ab6cbee58f5762a195 merge with auc improvement diff -r 06c942f9bac6 -r 7151691b85ef docs/conf.py --- a/docs/conf.py Tue Mar 27 17:28:47 2012 +0200 +++ b/docs/conf.py Tue Mar 27 17:29:16 2012 +0200 @@ -65,7 +65,7 @@ # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = project -#html_theme = +html_theme = 'haiku' html_theme_path = ['.'] # A shorter title for the navigation bar. Default is the same as html_title. diff -r 06c942f9bac6 -r 7151691b85ef docs/evolve-collaboration.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/evolve-collaboration.rst Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,81 @@ + +------------------------------------------------ +Collaboration Using Evolve: A user story +------------------------------------------------ + + +After having written some code for ticket #42, M W. start a patch (this +will be kind of like a 'work-in-progress' checkpoint initially):: + + $ ci -m '[entities] remove magic' + +Instant patch ! Note how the default phase of this changeset is (still) +in "draft" state. + +This is easily checkable:: + + $ hg phase tip + 827: draft + +See ? Until the day it becomes a "public" changeset, this can be altered +to no end. How ? It happens with an explicit:: + + $ hg phase -p + +In practice, pushing to a "publishing" repository can also turn draft +changesets into public ones. Older mercurial releases are automatically +"publishing" since they do not have the notion of non-public changesets +(or mutable history). + +In the transition ... phase from older mercurial servers, this will +happen often, so be careful. + +Now let's come back to our patch. Next hour sees good progress and W. +wants to complete the patch with the recent stuff (all that's shown by +an "hg diff") to share with a co-worker (let's call him C.W.):: + + $ hg amend -m '[entities] fix frobulator (closes #42)' + +Note that we also fix the commit message. (For recovering mq users: this +is just like "hg qrefresh -m"). + +Before leaving, let's push to the central shared repository. That will +give C.W. the signal that something is ripe for review / further amendments:: + + $ hg push # was done with a modern mercurial, draft phase is preserved + +The next day, Mr C.W, which arrives very very early, can immediately +work out some glitches in the patch. + +He then starts another one, for ticket #43 and finally commits it. +Then, as original worker arrives, he pushes his stuff. + +M W., now equipped with enough properly sugared coffee to survive the +next two hours:: + + $ hg pull + +Then:: + + $ hg up "tip ~ 1" + +brings him to yesterday's patch. Indeed the patch serial number has +increased (827 still exists but has been obsoleted). + +He understands that his original patch has been altered. But how did it +evolve ? + +The enhanced hgview shows the two patches. By default only the most +recent version of a patch is shown. + +Now, when W. installed the mutable-history extensions, he got an alias +that allows him to see the diff between two amendments, defined like this:: + + odiff=diff --rev 'limit(obsparents(.),1)' --rev . + +He can see exactly how C.W. amended his work. + +* odiff + + + diff -r 06c942f9bac6 -r 7151691b85ef docs/evolve-intro.rst --- a/docs/evolve-intro.rst Tue Mar 27 17:28:47 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ ----------------------------------------- -Introduction to the evolve extension ----------------------------------------- - -An history rewriting extension - -* Using the obsolete marker concept - -* Inspired from mq - -it is simple to enable:: - - $ hg clone http://hg-dev.octopoid.net/hgwebdir.cgi/mutable-history/ - $ mutable-history/enable.sh > ~/.hgrc diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/error-conflicting.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/error-conflicting.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-18 23:47ZCanvas 1Layer 1A’AA’’Conflicting diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/error-extinct.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/error-extinct.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-18 23:47ZCanvas 1Layer 1ABBAA'CC'CObsoleteUnstableextinctsuspended diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/error-obsolete.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/error-obsolete.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-18 23:47ZCanvas 1Layer 1ACBB’C’Obsolete diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/error-unstable.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/error-unstable.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-18 23:47ZCanvas 1Layer 1ABAA'ObsoleteUnstableB diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/example-1-update.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/example-1-update.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-21 08:32ZCanvas 1Layer 1AA’A diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/example-2-split.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/example-2-split.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-21 08:32ZCanvas 1Layer 1AA1A2A diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/simple-3-merge.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/simple-3-merge.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-21 08:32ZCanvas 1Layer 1AABBC diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/simple-4-reorder.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/simple-4-reorder.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-21 08:32ZCanvas 1Layer 1AABBA'B' diff -r 06c942f9bac6 -r 7151691b85ef docs/figures/simple-5-delete.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/figures/simple-5-delete.svg Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,3 @@ + + +2012-03-21 08:32ZCanvas 1Layer 1AA diff -r 06c942f9bac6 -r 7151691b85ef docs/index.rst --- a/docs/index.rst Tue Mar 27 17:28:47 2012 +0200 +++ b/docs/index.rst Tue Mar 27 17:29:16 2012 +0200 @@ -4,55 +4,148 @@ Here are various Materials on planned improvement to mercurial regarding -rewriting mutable history. +rewriting history. + +The effort splits in two parts: + + * The **obsolete marker** concept aims to provide and alternative to ``strip`` + to get ride of changesets. + + * The **evolve** mercurial extension to rewrite history using *obsolete marker* + under the hood. + -The effort is splitted in two part: +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. + + +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 +them: + +* sticks to "Work where you are" philosophy (I'll need better wording + for that) - * The **obsolete marker** concept that - - - - add an alternative to strip to remove changeset from a repository. +* Handle **non-linear history with branches and merges** + +* Use **robust merge** mechanism of mercurial. + + 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. + +* 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. + (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 + implication of the **obsolete marker** concept. I do not recommend + non power user to test this at this stage. + + Production ready version should hide such details to normal user. - * The changeset evolution UI +To enable the evolve extension use:: + + $ 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) + + $ hg clone http://hg-dev.octopoid.net/hgwebdir.cgi/hgview/ + $ cd hgview + $ python setup.py install --user + + + --- + +For more information see documents below + +.. toctree:: + :maxdepth: 2 + + tutorial + evolve-faq + from-mq + evolve-collaboration + +Smart changeset deletion: Obselete Marker +========================================== - to replace mq. - - - adding in mercurial core an new concept of **obsolete marker** in mercurial - core, +Obsolete marker is a powerful concept that allow mercurial to safely handle +history rewriting operations. It is a new type of relation between Mercurial +changesets that track the result of history rewriting operations. + +This concept is simple to define and provides a very solid base to: + +- Very fast history rewriting operations, + +- auditable and reversible history rewritting process, + +- clean final history, + +- share and collaborate on mutable part of the history, - * +- gracefully handle history rewriting conflict, + +- allows various history rewriting UI to collaborate with a underlying common API. + + --- + +For more information see documents below + +.. toctree:: + :maxdepth: 2 + + obs-concept + obs-implementation -Evolve: A new UI to replace MQ + +Know canveas ================================= -For user +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 update`` can move an obsolete parent + +* you need to provideto graft --continue -O if you started you graft using -O. + +* hg graphlog show extinct changeset + +* hg heads show extinct changeset + +* hg merge considered extinct head as valid target. requiring you to manually + specify target all the time. + + + + + +Anexe +================================= .. toctree:: - :maxdepth: 1 - - evolve-intro - tutorial - evolve-faq - from-mq - -A new UI to replace MQ -================================= - -for dev and advanced user - - -.. toctree:: - :maxdepth: 1 - - obs-concept glossary - obs-implementation - - -Big flasshy warning on current remaining issue diff -r 06c942f9bac6 -r 7151691b85ef docs/obs-concept.rst --- a/docs/obs-concept.rst Tue Mar 27 17:28:47 2012 +0200 +++ b/docs/obs-concept.rst Tue Mar 27 17:29:16 2012 +0200 @@ -1,26 +1,99 @@ -------------------------- -Obsolete Marker Concept -------------------------- +----------------------------------------------------------- +Why Do We Need a New Concept +----------------------------------------------------------- + +Current DVCS are great tool to forge a series of flawless changeset on your own. +But they perform poorly whe is comes to **share** work in progress and +**collaborate** on such work in progress. + +When people forge new version of a changeset they create a new changeset and get +ride of the original changeset. Difficultis to collaborate mostly came from the +way old content are *removed* from repository. + +Mercurial Approach: Strip +----------------------------------------------------- + +With current version of mercurial, every changesets that exist in your +repository are *visible* and *meaningful*. To get ride of old changeset you +rewrote mercurial remove them from the repository storage. with an operation +called *strip*. After the *strip* the repository looks like if the changeset +never existed. + +This approach is simple and effective but have a very big drawnback: You can +remove changesets from **your repository only**. If strip exists in other +repositories it will show of again and again. This only cure for this is to +strip the offending changeset from all repository. And operation at best +impractical and in most case impossible! -Obsolete marker is a powerful concept that allow mercurial to safely handle -history rewriting operations. It is a new type of relation between Mercurial -changesets that track the result of history rewriting operations. +As consequence, **you can not rewrite something once you exchange it with +others**. The old version will still exists along side the new one [#]_. -This concept is simple to define and provides a very solid base to: +Moreover backup are create stripped changeset in most case. This allow +restoration of old changeset but the process is painful. + +Finally, as the repository format is not optimized for deletion. stripping a +changeset may be slow in some situation. -- Very fast history rewriting operations, +To sum up, the strip approach is very simple but does not handle interaction +with the outer world. Which is unfortunate for a *Distributed* VCS. + +.. [#] various work around exists but they are work around with their own flow. + +Git Approach: Overwrite Reference +----------------------------------------------------- + +Git approach for repository is a bit more complex: They can be any amount of +changeset can exist in a repository. but **only changesets referenced by a git +branch** are *visible* and *meaningful*. + -- auditable and reversible history rewritting process, +.. warning:: add a schema:: -- clean final history, + C + | B--- + |/ + | + A + + Only B and A are visible. + +This ease the process of getting ride of old changeset. You can just leave them +in place and move the reference on the new one. You can then propagate those +change by moving the git-branch on remote host, newer version overwritting the +older one. -- share and collaborate on mutable part of the history, +This approach goes a bit further but still have major drawback: + + +Because you **overwrite** git-branch you have no conflit resolution. The last +to spoke win. This make collaboration on multiple changeset difficult because +you can't merge concurent update on changeset. + +Every overwrite is forced operation where the operator say "Yes I want this to +replace that. On higly distributed environment user may end with conflicting +reference with and no proper way to choose. + +Because of this way to visualize a repository, git-branches are a very core +part of git. This make user interface more complicated and move through history +more constrainted. -- gracefully handle history rewriting conflict, +Finally, even if all older changeset still exist in the repository acces to them +is still painful. + + +----------------------------------------------------- +The Obsolete Marker Concept +----------------------------------------------------- -- allows various history rewriting UI to collaborate with a underlying common API. + + + + +As None of the concept was powerful enough to embrace the need to safely rewrite +history, easily share and collaborate on mutable history we needed another one. + Basic concept @@ -30,12 +103,10 @@ Every history rewriting operation stores the information that old rewritten changesets has newer version available in a set of changeset. -This simple rules allows to express any possible history rewriting operation: +All basic history rewriting operation can create a appropriate obsolete marker. - - -.. figure:: ./figures/example-1-update.png +.. figure:: ./figures/example-1-update.* *Updating* a changeset @@ -43,20 +114,20 @@ -.. figure:: ./figures/example-2-split.png +.. figure:: ./figures/example-2-split.* *Splitting* a changeset in multiple one Create one obsolete marker ``([B1, B2] obsolete B)]`` -.. figure:: ./figures/example-3-merge.png +.. figure:: ./figures/example-3-merge.* *Merging* multiple changeset in a single one Create two obsolete markers ``([C] obsolete A), ([C] obsolete B)`` -.. figure:: ./figures/example-4-reorder.png +.. figure:: ./figures/example-4-reorder.* *Moving* changeset around @@ -65,7 +136,7 @@ -.. figure:: ./figures/example-5-delete.png +.. figure:: ./figures/example-5-delete.* *Removing* a changeset: @@ -122,7 +193,7 @@ With current version of mercurial, this *obsolete* part is stripped from the repository before the end of every rewritting operation. -.. figure:: ./figures/error-obsolete.png +.. figure:: ./figures/error-obsolete.* Rebasing `B` and `C` on `A` (as `B'`, `C'`) @@ -148,7 +219,7 @@ *Non-obsolete* changeset based on *obsolete* one are said **unstable** -.. figure:: ./figures/error-unstable.png +.. figure:: ./figures/error-unstable.* Amend `A` into `A'` leaving `B` behind. @@ -187,7 +258,7 @@ * *obsolete* changeset with *unstable* descendants, said **suspended**. -.. figure:: ./figures/error-extinct.png +.. figure:: ./figures/error-extinct.* Amend `A` and `C` leaving `B` behind. @@ -210,7 +281,7 @@ different versions. -.. figure:: ./figures/error-conflicting.png +.. figure:: ./figures/error-conflicting.* Conflicting rewriting of `A` into `A'` and `A''` @@ -252,3 +323,65 @@ .. warning:: add a schema + +Conclusion +---------------- + +Obsolete marker is a powerful concept that allow mercurial to safely handle +history rewriting operations. It is a new type of relation between Mercurial +changesets that track the result of history rewriting operations. + +This concept is simple to define and provides a very solid base to: + + +- Very fast history rewriting operations, + +- auditable and reversible history rewritting process, + +- clean final history, + +- share and collaborate on mutable part of the history, + +- gracefully handle history rewriting conflict, + +- allows various history rewriting UI to collaborate with a underlying common API. + +.. list-table:: Comparison on solution [#]_ + :header-rows: 1 + + * - Solution + - Remove changeset locally + - Works on any point of your history + - Propagation + - Collaboration + - Speed + - Access to older version + + * - Strip + - `+` + - `+` + - \ + - \ + - \ + - `- -` + + * - Reference + - `+` + - \ + - `+` + - \ + - `+` + - `-` + + * - Obsolete + - `+` + - `+` + - `++` + - `++` + - `+` + - `+` + + + +.. [#] To preserve good tradition in comparison table, an overwhelming advantage + goes to the defended solution. diff -r 06c942f9bac6 -r 7151691b85ef docs/tutorials/tutorial.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/tutorials/tutorial.t Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,677 @@ +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 +--------------------- + + +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 diff -r 06c942f9bac6 -r 7151691b85ef tests/test-tutorial.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-tutorial.t Tue Mar 27 17:29:16 2012 +0200 @@ -0,0 +1,1 @@ +../docs/tutorials/tutorial.t \ No newline at end of file diff -r 06c942f9bac6 -r 7151691b85ef tests/tutorial.t --- a/tests/tutorial.t Tue Mar 27 17:28:47 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,677 +0,0 @@ -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 ---------------------- - - -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