evolve: store the obsmarkers to be deleted in evolvestate
Sometimes, we don't create a new node and obsolete one of the old node in favour
of an existing node. When user calls, `hg evolve --abort`, we need to strip that
obsmarker to go back in the same old state. The obsmarker created for new node
are stripped when the new nodes are stripped.
This patch start storing such obsmarkers in the evolvestate so that we can delete
them later if required. Right now we just store successsor and predecessor
information, we might need a better obsmarker serialization techinque in future
to make it more robust.
==============TopicTutorial==============ThisMercurialconfigurationexampleisusedfortesting...Varioussetup$."$TESTDIR/testlib/topic_setup.sh"$cat>>$HGRCPATH<<EOF>[experimental]>evolution=all>[extensions]>evolve=>EOF$hginitserver$cdserver$cat>>.hg/hgrc<<EOF>[ui]>user=ShoppingMaster>EOF$cat>>shopping<<EOF>Spam>Whizzobutter>Albatross>Rat(ratheralot)>Juggedfish>Blancmange>Salmonmousse>EOF$hgcommit-A-m"Shopping list"addingshopping$cd..$hgcloneserverclientupdatingtobranchdefault1filesupdated,0filesmerged,0filesremoved,0filesunresolved$cdclient$cat>>.hg/hgrc<<EOF>[ui]>user=TutorialUser>EOF#if docgraph-ext$."$TESTDIR/testlib/docgraph_setup.sh"#rest-ignore#endifTopicbranchesarelightweightbrancheswhichdisappearwhenchangesarefinalized(movedtothepublicphase).Theycanhelpuserstoorganizeandsharetheirunfinishedwork.Inthistutorial,weexplainhowtousetopicsforlocaldevelopment.Inthefirstpart,thereisacentral*publishing*server.Anythingpushedtothecentralserverwillbecomepublicandimmutable.Thismeansnounfinishedworkshouldescapethelocalrepository.TopicBasics============Let's say we use Mercurial to manage our shopping list: $ hg log --graph @ changeset: 0:38da43f0a2ea tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: Shopping list#if docgraph-ext $ hg docgraph -r "all()" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 0 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=0, pin=true, pos="1,0!", shape=circle, style=filled, width=1]; }#endifWe are about to make some additions to this list and would like to do themwithin a topic. Creating a new topic is done using the ``topic`` command: $ hg topics food marked working directory as topic: foodMuch like a named branch, our topic is active but it does not contain anychangeset yet: $ hg topics * food (0 changesets) $ hg summary parent: 0:38da43f0a2ea tip Shopping list branch: default commit: (clean) update: (current) topic: food $ hg log --graph @ changeset: 0:38da43f0a2ea tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: Shopping list#if docgraph-ext $ hg docgraph -r "all()" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 0 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=0, pin=true, pos="1,0!", shape=circle, style=filled, width=1]; }#endifOur next commit will be part of the active topic: $ cat >> shopping <<EOF>Egg>Suggar>Vinegar>Oil>EOF$hgcommit-m"adding condiments"activetopic'food'grewitsfirstchangeset(see'hg help topics'formoreinformation)$hglog--graph--rev'topic("food")'@changeset:1:13900241408b|tag:tip~topic:fooduser:testdate:ThuJan0100:00:001970+0000summary:addingcondiments#if docgraph-ext$hgdocgraph-r"topic("food")"--sphinx-directive--rankdirLR#rest-ignore..graphviz::strictdigraph"Mercurial graph"{graph[rankdir=LR,splines=polyline];node[label="\N"];1[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=1,pin=true,pos="1,1!",shape=pentagon,style=filled,width=1];}#endifAndfuturecommitswillbepartofthattopictoo:$cat>> shopping <<EOF>Bananas>Pear>Apple>EOF$hgcommit-m"adding fruits"$hglog--graph--rev'topic("food")'@changeset:2:287de11b401f|tag:tip|topic:food|user:test|date:ThuJan0100:00:001970+0000|summary:addingfruits|ochangeset:1:13900241408b|topic:food~user:testdate:ThuJan0100:00:001970+0000summary:addingcondiments#if docgraph-ext$hgdocgraph-r"topic("food")"--sphinx-directive--rankdirLR#rest-ignore..graphviz::strictdigraph"Mercurial graph"{graph[rankdir=LR,splines=polyline];node[label="\N"];1[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=1,pin=true,pos="1,1!",shape=pentagon,style=filled,width=1];2[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=2,pin=true,pos="1,2!",shape=pentagon,style=filled,width=1];1->2[arrowhead=none,penwidth=2.0];}#endifWecangetacompactviewofthecontentofourtopicusingthe``stack``command:$hgstack ### topic: food ### target: default (branch)t2@addingfruits(current)t1:addingcondimentst0^Shoppinglist(base)Thetopicdeactivateswhenweupdateawayfromit:$hgupdatedefault1filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgtopicsfood(2changesets)Notethat``default``(nameofthebranch)nowreferstothetipmostchangesetofdefaultwithoutatopic:$hglog--graphochangeset:2:287de11b401f|tag:tip|topic:food|user:test|date:ThuJan0100:00:001970+0000|summary:addingfruits|ochangeset:1:13900241408b|topic:food|user:test|date:ThuJan0100:00:001970+0000|summary:addingcondiments|@changeset:0:38da43f0a2eauser:testdate:ThuJan0100:00:001970+0000summary:Shoppinglist#if docgraph-ext$hgdocgraph-r"all()"--sphinx-directive--rankdirLR#rest-ignore..graphviz::strictdigraph"Mercurial graph"{graph[rankdir=LR,splines=polyline];node[label="\N"];0[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=0,pin=true,pos="1,0!",shape=circle,style=filled,width=1];1[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=1,pin=true,pos="1,1!",shape=pentagon,style=filled,width=1];0->1[arrowhead=none,penwidth=2.0];2[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=2,pin=true,pos="1,2!",shape=pentagon,style=filled,width=1];1->2[arrowhead=none,penwidth=2.0];}#endifAndupdatingbacktothetopicreactivatesit:$hgupdatefoodswitchingtotopicfood1filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgtopics*food(2changesets)Updatingtoanychangesetthatispartofatopicactivatesthetopicregardlessofhowtherevisionwasspecified:$hgupdatedefault1filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgupdate--rev'desc("condiments")'switchingtotopicfood1filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgtopics*food(2changesets)..Serversideactivity:$cd../server/$cat>shopping<<EOF>T-Shirt>Trousers>Spam>Whizzobutter>Albatross>Rat(ratheralot)>Juggedfish>Blancmange>Salmonmousse>EOF$hgcommit-A-m"Adding clothes"$cd../clientThetopicwillalsoaffecttherebaseandthemergedestinations.Let's pullthe latest update from the main server: $ hg pull pulling from $TESTTMP/server (glob) searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) new changesets 6104862e8b84 (run 'hgheads' to see heads) $ hg log -G o changeset: 3:6104862e8b84 | tag: tip | parent: 0:38da43f0a2ea | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding clothes | | o changeset: 2:287de11b401f | | topic: food | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: adding fruits | | | @ changeset: 1:13900241408b |/ topic: food | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: adding condiments | o changeset: 0:38da43f0a2ea user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: Shopping list#if docgraph-ext $ hg docgraph -r "all()" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 0 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=0, pin=true, pos="1,0!", shape=circle, style=filled, width=1]; 1 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=1, pin=true, pos="1,1!", shape=pentagon, style=filled, width=1]; 0 -> 1 [arrowhead=none, penwidth=2.0]; 3 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=3, pin=true, pos="1,3!", shape=circle, style=filled, width=1]; 0 -> 3 [arrowhead=none, penwidth=2.0]; 2 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=2, pin=true, pos="1,2!", shape=pentagon, style=filled, width=1]; 1 -> 2 [arrowhead=none, penwidth=2.0]; }#endifThe topic head will not be considered when merging from the new head of thebranch: $ hg update default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge abort: branch 'default' has one head - please merge with an explicit rev (run 'hgheads' to see all heads) [255]But the topic will see that branch head as a valid destination: $ hg update food switching to topic food 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg rebase rebasing 1:13900241408b "adding condiments" (food) merging shopping switching to topic food rebasing 2:287de11b401f "adding fruits" (food) merging shopping $ hg log --graph @ changeset: 5:2d50db8b5b4c | tag: tip | topic: food | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: adding fruits | o changeset: 4:4011b46eeb33 | topic: food | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: adding condiments | o changeset: 3:6104862e8b84 | parent: 0:38da43f0a2ea | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding clothes | o changeset: 0:38da43f0a2ea user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: Shopping list#if docgraph-ext $ hg docgraph -r "all()" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 0 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=0, pin=true, pos="1,0!", shape=circle, style=filled, width=1]; 3 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=3, pin=true, pos="1,3!", shape=circle, style=filled, width=1]; 0 -> 3 [arrowhead=none, penwidth=2.0]; 4 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=4, pin=true, pos="1,4!", shape=pentagon, style=filled, width=1]; 3 -> 4 [arrowhead=none, penwidth=2.0]; 5 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=5, pin=true, pos="1,5!", shape=pentagon, style=filled, width=1]; 4 -> 5 [arrowhead=none, penwidth=2.0]; }#endifThere exists a template keyword named "topic" which can be used $ hg log -GT "{rev}:{node|short}{topic}\n{desc}" @ 5:2d50db8b5b4c food | adding fruits o 4:4011b46eeb33 food | adding condiments o 3:6104862e8b84 | Adding clothes o 0:38da43f0a2ea Shopping listThe topic information will disappear when we publish the changesets: $ hg topics * food (2 changesets) $ hg push pushing to $TESTTMP/server (glob) searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files 2 new obsolescence markers active topic 'food' is now empty (use 'hgtopic--clear' to clear it if needed) $ hg topics * food (0 changesets)The topic still exists, and any new commit will be in the topic. Butnote that it is now devoid of any commit. $ hg topics --list ### topic: food ### target: default (branch) (stack is empty) t0^ adding fruits (base current) $ hg log --graph @ changeset: 5:2d50db8b5b4c | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: adding fruits | o changeset: 4:4011b46eeb33 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: adding condiments | o changeset: 3:6104862e8b84 | parent: 0:38da43f0a2ea | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding clothes | o changeset: 0:38da43f0a2ea user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: Shopping list#if docgraph-ext $ hg docgraph -r "all()" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 0 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=0, pin=true, pos="1,0!", shape=circle, style=filled, width=1]; 3 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=3, pin=true, pos="1,3!", shape=circle, style=filled, width=1]; 0 -> 3 [arrowhead=none, penwidth=2.0]; 4 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=4, pin=true, pos="1,4!", shape=circle, style=filled, width=1]; 3 -> 4 [arrowhead=none, penwidth=2.0]; 5 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=5, pin=true, pos="1,5!", shape=circle, style=filled, width=1]; 4 -> 5 [arrowhead=none, penwidth=2.0]; }#endifIf we update to the *default* head, we will leave the topic behind,and since it is commit-less, it will vanish. $ hg update default clearing empty topic "food" 0 files updated, 0 files merged, 0 files removed, 0 files unresolvedFrom there, the topic has been completely forgotten. $ hg topicsKeep working within topics==========================Making sure all your new local commit are made within a topic will help youorganize your work. It is possible to ensure this through the Mercurialconfiguration.For this tutorial, we'lladdtheconfigattherepositorylevel:$cat<<EOF>> .hg/hgrc > [experimental] > topic-mode = enforce > EOFYou can also use `hg config --edit` to update your mercurial configuration.Once enforcement is turned on. New local commit will be denied if no topic is active. $ echo sickle >> shopping $ hg commit -m 'Addingsickle' abort: no active topic (see 'hghelp-etopic.topic-mode' for details) [255]Ok, let'scleanthisupanddelveintomultipletopics.$hgrevert.revertingshoppingWorkingwithMultipleTopics============================Intheaboveexample,topicsdonotbringmanybenefitssinceyouonlyhaveonelineofdevelopment.Topicsstarttobemoreusefulwhenyouhavetoworkonmultiplefeaturesatthesametime.Wemightgoshoppinginahardwarestoreinthesamego,solet's add sometools to the shopping list within a new topic: $ hg topics tools marked working directory as topic: tools $ echo hammer >> shopping $ hg commit -m 'Addinghammer' active topic 'tools' grew its first changeset (see 'hghelptopics' for more information) $ echo saw >> shopping $ hg commit -m 'Addingsaw' $ echo drill >> shopping $ hg commit -m 'Addingdrill'But we are not sure we will actually go to the hardware store, so in themeantime, we want to extend the list with drinks. We go back to the officialdefault branch and start a new topic: $ hg update default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg topics drinks marked working directory as topic: drinks $ echo 'applejuice' >> shopping $ hg commit -m 'Addingapplejuice' active topic 'drinks' grew its first changeset (see 'hghelptopics' for more information) $ echo 'orangejuice' >> shopping $ hg commit -m 'Addingorangejuice'We now have two topics: $ hg topics * drinks (2 changesets) tools (3 changesets)The information displayed by ``hg stack`` adapts to the active topic: $ hg stack ### topic: drinks ### target: default (branch) t2@ Adding orange juice (current) t1: Adding apple juice t0^ adding fruits (base) $ hg update tools switching to topic tools 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg stack ### topic: tools ### target: default (branch) t3@ Adding drill (current) t2: Adding saw t1: Adding hammer t0^ adding fruits (base)They are seen as independent branches by Mercurial. No rebase or mergebetween them will be attempted by default: $ hg rebase nothing to rebase [1]We simulate independant contributions to the repo with thisactivity: $ cd ../server $ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ mv shopping foo $ echo 'Coat' > shopping $ cat foo >> shopping $ hg commit -m 'addacoat' $ echo 'Coat' > shopping $ echo 'Shoes' >> shopping $ cat foo >> shopping $ rm foo $ hg commit -m 'addapairofshoes' $ cd ../clientLet'sdiscoverwhatotherpeopledidcontribute:$hgpullpullingfrom$TESTTMP/server(glob)searchingforchangesaddingchangesetsaddingmanifestsaddingfilechangesadded2changesetswith2changesto1files(+1heads)newchangesetsf2d6cacc6115:fbff9bc37a43(run'hg heads'toseeheads)Therearenewchanges!Wecansimplyuse``hgrebase``toupdateourchangesetontopofthelatest:$hglog-Gochangeset:12:fbff9bc37a43|tag:tip|user:test|date:ThuJan0100:00:001970+0000|summary:addapairofshoes|ochangeset:11:f2d6cacc6115|parent:5:2d50db8b5b4c|user:test|date:ThuJan0100:00:001970+0000|summary:addacoat||ochangeset:10:70dfa201ed73||topic:drinks||user:test||date:ThuJan0100:00:001970+0000||summary:Addingorangejuice|||ochangeset:9:8dfa45bd5e0c|/topic:drinks|parent:5:2d50db8b5b4c|user:test|date:ThuJan0100:00:001970+0000|summary:Addingapplejuice||@changeset:8:34255b455dac||topic:tools||user:test||date:ThuJan0100:00:001970+0000||summary:Addingdrill|||ochangeset:7:cffff85af537||topic:tools||user:test||date:ThuJan0100:00:001970+0000||summary:Addingsaw|||ochangeset:6:183984ef46d1|/topic:tools|user:test|date:ThuJan0100:00:001970+0000|summary:Addinghammer|ochangeset:5:2d50db8b5b4c|user:test|date:ThuJan0100:00:001970+0000|summary:addingfruits|ochangeset:4:4011b46eeb33|user:test|date:ThuJan0100:00:001970+0000|summary:addingcondiments|ochangeset:3:6104862e8b84|parent:0:38da43f0a2ea|user:test|date:ThuJan0100:00:001970+0000|summary:Addingclothes|ochangeset:0:38da43f0a2eauser:testdate:ThuJan0100:00:001970+0000summary:Shoppinglist#if docgraph-ext$hgdocgraph-r"all()"--sphinx-directive--rankdirLR#rest-ignore..graphviz::strictdigraph"Mercurial graph"{graph[rankdir=LR,splines=polyline];node[label="\N"];0[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=0,pin=true,pos="1,0!",shape=circle,style=filled,width=1];3[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=3,pin=true,pos="1,3!",shape=circle,style=filled,width=1];0->3[arrowhead=none,penwidth=2.0];4[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=4,pin=true,pos="1,4!",shape=circle,style=filled,width=1];3->4[arrowhead=none,penwidth=2.0];5[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=5,pin=true,pos="1,5!",shape=circle,style=filled,width=1];4->5[arrowhead=none,penwidth=2.0];6[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=6,pin=true,pos="1,6!",shape=pentagon,style=filled,width=1];5->6[arrowhead=none,penwidth=2.0];9[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=9,pin=true,pos="1,9!",shape=pentagon,style=filled,width=1];5->9[arrowhead=none,penwidth=2.0];11[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=11,pin=true,pos="1,11!",shape=circle,style=filled,width=1];5->11[arrowhead=none,penwidth=2.0];7[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=7,pin=true,pos="1,7!",shape=pentagon,style=filled,width=1];6->7[arrowhead=none,penwidth=2.0];8[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=8,pin=true,pos="1,8!",shape=pentagon,style=filled,width=1];7->8[arrowhead=none,penwidth=2.0];10[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=10,pin=true,pos="1,10!",shape=pentagon,style=filled,width=1];9->10[arrowhead=none,penwidth=2.0];12[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=12,pin=true,pos="1,12!",shape=circle,style=filled,width=1];11->12[arrowhead=none,penwidth=2.0];}#endif$hgrebaserebasing6:183984ef46d1"Adding hammer"(tools)mergingshoppingswitchingtotopictoolsrebasing7:cffff85af537"Adding saw"(tools)mergingshoppingrebasing8:34255b455dac"Adding drill"(tools)mergingshoppingButwhatabouttheothertopic?Youcanuse'hg topics --verbose'toseeinformationaboutallthetopics:$hgtopics--verbosedrinks(onbranch:default,2changesets,2behind)*tools(onbranch:default,3changesets)The"2 behind"istellingyouthatthereare2newchangesetsoverthebaseofthetopic.Pushingthattopicwouldcreateanewhead,andthereforewillbeprevented:$hgpush--revdrinkspushingto$TESTTMP/server(glob)searchingforchangesabort:pushcreatesnewremotehead70dfa201ed73!(mergeorsee'hg help push'fordetailsaboutpushingnewheads)[255]Evenafterarebase,pushingallactivetopicsatthesametimewouldpublishthemtothedefaultbranch,andthenmercurialwouldcomplainaboutthemultiple*public*headsitwouldcreateonthatbranch:$hgrebase-bdrinksrebasing9:8dfa45bd5e0c"Adding apple juice"(drinks)mergingshoppingswitchingtotopicdrinksrebasing10:70dfa201ed73"Adding orange juice"(drinks)mergingshoppingswitchingtotopictools$hgpushpushingto$TESTTMP/server(glob)searchingforchangesabort:pushcreatesnewremotehead4cd7c1591a67!(mergeorsee'hg help push'fordetailsaboutpushingnewheads)[255]Publishingonlyoneofthemisallowed(aslongasitdoesnotcreateanewbranchheadaswejustsawinthepreviouscase):$hgpush-rdrinkspushingto$TESTTMP/server(glob)searchingforchangesaddingchangesetsaddingmanifestsaddingfilechangesadded2changesetswith2changesto1files2newobsolescencemarkersThepublishedtopichasnowdisappeared,andtheotherisnowmarkedas"behind":$hgtopics--verbose*tools(onbranch:default,3changesets,2behind)$hgstack###topic:tools ### target: default (branch), 2 behindt3@Addingdrill(current)t2:Addingsawt1:Addinghammert0^addapairofshoes(base)WorkingWithinYourStack===========================Navigatingwithinyourstack----------------------------Aswesawbefore`stack`displayschangesetsonyourcurrenttopicinacleanway:$hgtopics--verbose*tools(onbranch:default,3changesets,2behind)$hgstack###topic:tools ### target: default (branch), 2 behindt3@Addingdrill(current)t2:Addingsawt1:Addinghammert0^addapairofshoes(base)Youcannavigateinyourcurrentstackwith`previous`and`next`.`previous`willbringyoubacktotheparentofthetopichead.$hgprevious1filesupdated,0filesmerged,0filesremoved,0filesunresolved[14]Addingsaw$hgstack ### topic: tools ### target: default (branch), 2 behindt3:Addingdrillt2@Addingsaw(current)t1:Addinghammert0^addapairofshoes(base)`next`willmoveyouforwardtothetopichead.$hgnext1filesupdated,0filesmerged,0filesremoved,0filesunresolved[15]Addingdrill$hgstack ### topic: tools ### target: default (branch), 2 behindt3@Addingdrill(current)t2:Addingsawt1:Addinghammert0^addapairofshoes(base)Youcanalsodirectlyjumptoachangesetwithinyourstackwiththerevset`t#`.$hgupdatet11filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgstack ### topic: tools ### target: default (branch), 2 behindt3:Addingdrillt2:Addingsawt1@Addinghammer(current)t0^addapairofshoes(base)Editingyourworkmid-stack---------------------------It's easy to edit your work inside your stack: $ hg stack ### topic: tools ### target: default (branch), 2 behind t3: Adding drill t2: Adding saw t1@ Adding hammer (current) t0^ add a pair of shoes (base) $ hg amend -m "Adding hammer to the shopping list" 2 new orphan changesetsUnderstanding the current situation with hg log is not so easy, becauseit shows too many things: $ hg log -G -r "t0::" @ changeset: 18:b7509bd417f8 | tag: tip | topic: tools | parent: 12:fbff9bc37a43 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding hammer to the shopping list | | o changeset: 17:4cd7c1591a67 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Adding orange juice | | | o changeset: 16:20759cb47ff8 |/ parent: 12:fbff9bc37a43 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding apple juice | | * changeset: 15:bb1e6254f532 | | topic: tools | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | instability: orphan | | summary: Adding drill | | | * changeset: 14:d4f97f32f8a1 | | topic: tools | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | instability: orphan | | summary: Adding saw | | | x changeset: 13:a8ab3599d53d |/ topic: tools | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | obsolete: reworded using amend as 18:b7509bd417f8 | summary: Adding hammer | o changeset: 12:fbff9bc37a43 | user: test ~ date: Thu Jan 01 00:00:00 1970 +0000 summary: add a pair of shoes#if docgraph-ext $ hg docgraph -r "t0::" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 12 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=12, pin=true, pos="1,12!", shape=circle, style=filled, width=1]; 13 [fillcolor="#DFDFFF", fixedsize=true, group=default_alt, height=1, label=13, pin=true, pos="2,13!", shape=pentagon, style="dotted, filled", width=1]; 12 -> 13 [arrowhead=none, penwidth=2.0]; 18 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=18, pin=true, pos="1,18!", shape=pentagon, style=filled, width=1]; 12 -> 18 [arrowhead=none, penwidth=2.0]; 16 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=16, pin=true, pos="1,16!", shape=circle, style=filled, width=1]; 12 -> 16 [arrowhead=none, penwidth=2.0]; 13 -> 18 [arrowtail=none, dir=back, minlen=0, penwidth=2.0, style=dashed]; 14 [fillcolor="#FF4F4F", fixedsize=true, group=default_alt, height=1, label=14, pin=true, pos="2,14!", shape=pentagon, style=filled, width=1]; 13 -> 14 [arrowhead=none, penwidth=2.0]; 15 [fillcolor="#FF4F4F", fixedsize=true, group=default_alt, height=1, label=15, pin=true, pos="2,15!", shape=pentagon, style=filled, width=1]; 14 -> 15 [arrowhead=none, penwidth=2.0]; 17 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=17, pin=true, pos="1,17!", shape=circle, style=filled, width=1]; 16 -> 17 [arrowhead=none, penwidth=2.0]; }#endifFortunately stack shows you a better visualization: $ hg stack ### topic: tools ### target: default (branch), 2 behind t3$ Adding drill (unstable) t2$ Adding saw (unstable) t1@ Adding hammer to the shopping list (current) t0^ add a pair of shoes (base)It'seasytostabilizethesituation,`next`hasan`--evolve`option.Itwilldothenecessaryrelocationof`t2`and`t3`overthenew`t1`withouthavingtodothatrebasebyhand.:$hgnext--evolvemove:[14]Addingsawatop:[18]Addinghammertotheshoppinglistworkingdirectorynowatd5c51ee5762a$hgstack ### topic: tools ### target: default (branch), 2 behindt3$Addingdrill(unstable)t2@Addingsaw(current)t1:Addinghammertotheshoppinglistt0^addapairofshoes(base)Onemoretogo:$hgnext--evolvemove:[15]Addingdrillatop:[19]Addingsawworkingdirectorynowatbae3758e46bf$hgstack ### topic: tools ### target: default (branch), 2 behindt3@Addingdrill(current)t2:Addingsawt1:Addinghammertotheshoppinglistt0^addapairofshoes(base)Let's take a look at `hg log` once again: $ hg log -G -r "t0::" @ changeset: 20:bae3758e46bf | tag: tip | topic: tools | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding drill | o changeset: 19:d5c51ee5762a | topic: tools | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding saw | o changeset: 18:b7509bd417f8 | topic: tools | parent: 12:fbff9bc37a43 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding hammer to the shopping list | | o changeset: 17:4cd7c1591a67 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Adding orange juice | | | o changeset: 16:20759cb47ff8 |/ parent: 12:fbff9bc37a43 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Adding apple juice | o changeset: 12:fbff9bc37a43 | user: test ~ date: Thu Jan 01 00:00:00 1970 +0000 summary: add a pair of shoes#if docgraph-ext $ hg docgraph -r "t0::" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { graph [rankdir=LR, splines=polyline ]; node [label="\N"]; 12 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=12, pin=true, pos="1,12!", shape=circle, style=filled, width=1]; 16 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=16, pin=true, pos="1,16!", shape=circle, style=filled, width=1]; 12 -> 16 [arrowhead=none, penwidth=2.0]; 18 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=18, pin=true, pos="1,18!", shape=pentagon, style=filled, width=1]; 12 -> 18 [arrowhead=none, penwidth=2.0]; 17 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=17, pin=true, pos="1,17!", shape=circle, style=filled, width=1]; 16 -> 17 [arrowhead=none, penwidth=2.0]; 19 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=19, pin=true, pos="1,19!", shape=pentagon, style=filled, width=1]; 18 -> 19 [arrowhead=none, penwidth=2.0]; 20 [fillcolor="#7F7FFF", fixedsize=true, group=default, height=1, label=20, pin=true, pos="1,20!", shape=pentagon, style=filled, width=1]; 19 -> 20 [arrowhead=none, penwidth=2.0]; }#endifMulti-headed stack------------------Stack is also very helpful when you have a multi-headed stack: $ hg up t1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo "nails" > new_shopping $ cat shopping >> new_shopping $ mv new_shopping shopping $ hg commit -m 'Addingnails' $ hg stack ### topic: tools (2 heads) ### target: default (branch), 2 behind t4: Adding drill t3: Adding saw t1^ Adding hammer to the shopping list (base) t2@ Adding nails (current) t1: Adding hammer to the shopping list t0^ add a pair of shoes (base)Solving this situation is easy with a topic: use merge or rebase.Merge within a multi-headed stack will use the other topic head asdestination if the topic has two heads. But rebasing will yield acompletely linear history so it'swhatwewilldo.$hglog-G@changeset:21:f936c6da9d61|tag:tip|topic:tools|parent:18:b7509bd417f8|user:test|date:ThuJan0100:00:001970+0000|summary:Addingnails||ochangeset:20:bae3758e46bf||topic:tools||user:test||date:ThuJan0100:00:001970+0000||summary:Addingdrill|||ochangeset:19:d5c51ee5762a|/topic:tools|user:test|date:ThuJan0100:00:001970+0000|summary:Addingsaw|ochangeset:18:b7509bd417f8|topic:tools|parent:12:fbff9bc37a43|user:test|date:ThuJan0100:00:001970+0000|summary:Addinghammertotheshoppinglist||ochangeset:17:4cd7c1591a67||user:test||date:ThuJan0100:00:001970+0000||summary:Addingorangejuice|||ochangeset:16:20759cb47ff8|/parent:12:fbff9bc37a43|user:test|date:ThuJan0100:00:001970+0000|summary:Addingapplejuice|ochangeset:12:fbff9bc37a43|user:test|date:ThuJan0100:00:001970+0000|summary:addapairofshoes|ochangeset:11:f2d6cacc6115|parent:5:2d50db8b5b4c|user:test|date:ThuJan0100:00:001970+0000|summary:addacoat|ochangeset:5:2d50db8b5b4c|user:test|date:ThuJan0100:00:001970+0000|summary:addingfruits|ochangeset:4:4011b46eeb33|user:test|date:ThuJan0100:00:001970+0000|summary:addingcondiments|ochangeset:3:6104862e8b84|parent:0:38da43f0a2ea|user:test|date:ThuJan0100:00:001970+0000|summary:Addingclothes|ochangeset:0:38da43f0a2eauser:testdate:ThuJan0100:00:001970+0000summary:Shoppinglist#if docgraph-ext$hgdocgraph-r"all()"--sphinx-directive--rankdirLR#rest-ignore..graphviz::strictdigraph"Mercurial graph"{graph[rankdir=LR,splines=polyline];node[label="\N"];0[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=0,pin=true,pos="1,0!",shape=circle,style=filled,width=1];3[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=3,pin=true,pos="1,3!",shape=circle,style=filled,width=1];0->3[arrowhead=none,penwidth=2.0];4[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=4,pin=true,pos="1,4!",shape=circle,style=filled,width=1];3->4[arrowhead=none,penwidth=2.0];5[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=5,pin=true,pos="1,5!",shape=circle,style=filled,width=1];4->5[arrowhead=none,penwidth=2.0];11[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=11,pin=true,pos="1,11!",shape=circle,style=filled,width=1];5->11[arrowhead=none,penwidth=2.0];12[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=12,pin=true,pos="1,12!",shape=circle,style=filled,width=1];11->12[arrowhead=none,penwidth=2.0];16[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=16,pin=true,pos="1,16!",shape=circle,style=filled,width=1];12->16[arrowhead=none,penwidth=2.0];18[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=18,pin=true,pos="1,18!",shape=pentagon,style=filled,width=1];12->18[arrowhead=none,penwidth=2.0];17[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=17,pin=true,pos="1,17!",shape=circle,style=filled,width=1];16->17[arrowhead=none,penwidth=2.0];19[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=19,pin=true,pos="1,19!",shape=pentagon,style=filled,width=1];18->19[arrowhead=none,penwidth=2.0];21[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=21,pin=true,pos="1,21!",shape=pentagon,style=filled,width=1];18->21[arrowhead=none,penwidth=2.0];20[fillcolor="#7F7FFF",fixedsize=true,group=default,height=1,label=20,pin=true,pos="1,20!",shape=pentagon,style=filled,width=1];19->20[arrowhead=none,penwidth=2.0];}#endif$hgupt41filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgrebaserebasing19:d5c51ee5762a"Adding saw"(tools)mergingshoppingrebasing20:bae3758e46bf"Adding drill"(tools)mergingshopping$hgstack ### topic: tools ### target: default (branch), 2 behindt4@Addingdrill(current)t3:Addingsawt2:Addingnailst1:Addinghammertotheshoppinglistt0^addapairofshoes(base)Collaboratingthroughanon-publishingserver=============================================..setup:..Let's create a non-publishing server: $ cd .. $ hg clone server non-publishing-server updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd non-publishing-server $ cat >> .hg/hgrc <<EOF>[phases]>publish=false>EOF..Andanotherclient:$cd..$hgcloneserverother-clientupdatingtobranchdefault1filesupdated,0filesmerged,0filesremoved,0filesunresolved$cdclientWecannowsharethesedraftchangesets:$hgpush../non-publishing-server-rtoolspushingto../non-publishing-serversearchingforchangesaddingchangesetsaddingmanifestsaddingfilechangesadded4changesetswith4changesto1files(+1heads)8newobsolescencemarkersPushingthenewtopicbranchtoanon-publishingserverdidnotrequire--force.Aslongasnewheadsareontheirowntopic,Mercurialwillnotcomplainaboutthem.Fromanotherclient,wewillgetthemwiththeirtopic:$cd../other-client$hgpull../non-publishing-serverpullingfrom../non-publishing-serversearchingforchangesaddingchangesetsaddingmanifestsaddingfilechangesadded4changesetswith4changesto1files(+1heads)8newobsolescencemarkersnewchangesetsb7509bd417f8:2d084ac00115(run'hg heads'toseeheads)$hgtopics--verbosetools(onbranch:default,4changesets,2behind)$hguptoolsswitchingtotopictools1filesupdated,0filesmerged,0filesremoved,0filesunresolved$hgstack ### topic: tools ### target: default (branch), 2 behindt4@Addingdrill(current)t3:Addingsawt2:Addingnailst1:Addinghammertotheshoppinglistt0^addapairofshoes(base)Wecanalsoaddnewchangesetsandsharethem:$echoscrews>> shopping $ hg commit -A -m "Adding screws" $ hg push ../non-publishing-server pushing to ../non-publishing-server searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 filesAnd retrieve them from the first client: $ cd ../client $ hg pull ../non-publishing-server pulling from ../non-publishing-server searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files new changesets 0d409663a1fd (run 'hgupdate' to get a working copy) $ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg stack ### topic: tools ### target: default (branch), 2 behind t5@ Adding screws (current) t4: Adding drill t3: Adding saw t2: Adding nails t1: Adding hammer to the shopping list t0^ add a pair of shoes (base)