topic: merge the topic extension in the evolve repository
authorPierre-Yves David <pierre-yves.david@ens-lyon.org>
Thu, 02 Mar 2017 18:07:46 +0100
changeset 2020 143c8e4dc22d
parent 2019 996a562b6c9f (current diff)
parent 1838 6942750831bb (diff)
child 2021 e6db5d48ebc5
topic: merge the topic extension in the evolve repository There is a lot of synergy between the two concepts. Topic is expected to be able to smooth multiple of evolution sharp edge. Having them both in the same repository will make this collaboration easier.
.hgignore
COPYING
Makefile
README
README.md
hgext3rd/__init__.py
setup.cfg
setup.py
tests/test-check-pyflakes.t
tests/test-evolve-topic.t
--- a/.hgignore	Thu Feb 23 15:19:31 2017 +0100
+++ b/.hgignore	Thu Mar 02 18:07:46 2017 +0100
@@ -1,5 +1,15 @@
-syntax: glob
-*.orig
-*.pyc
-tests/*.err
-tests/.testtimes
+syntax: re
+/figures/[^/]+\.png$
+^html/
+\.pyc$
+~$
+\.swp$
+\.orig$
+\.rej$
+\.err$
+^tests/easy_run.sh$
+^build/
+^MANIFEST$
+^docs/tutorials/.*\.rst$
+\.ico$
+tests/\.testtimes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgtags	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,48 @@
+6c6bb7a23bb5125bf06da73265f039dd3447dafa 0.1.0
+d3f20770b86a31dba56ae7b252089e12b34702da 0.2.0
+c046b083a5e0b21af69027f31cee141800cf894b 0.3.0
+9bbcd274689829d9239978236e16610688978233 0.4.0
+4ecbaec1d664b1e6f8ebc78292e1ced77a8e69c0 0.4.1
+7ef8ab8c6feadb8a9d9e13af144a17cb23e9a38d 0.5
+4a5488c01a66be4729252175cea0ea739a88a540 0.6
+18a0d96ed559089edf90206c469f3f8c26681c64 0.7
+1b2757c1bd918509184f6c1d06b2329a847e31b0 0.7
+b18b000363550f02f413aed008f8e306318c608c 1.0.0
+ca5bb72d14aeb6e6053e3a53c064a2b7dc8010e5 1.0.1
+b1bdcb4506defef0e857e2710633f7686d8034a5 1.0.2
+5559e5a4b656978c592d364f242edc62369d7e84 1.0.2
+c062edbcaf13135d0312fd2039deca74573ff4f0 1.1.0
+22cacfce2a65ab965c6179ae862b148f4abc7d8a 1.1.0
+d43e80504e55db9ad4826e860e50530103a27b0f 2.0.0
+f9d305deeff3dba782e65faf4ef3fd1569995859 2.1.0
+862b6b71a35836e81f090ba7229c2888e8ed2f9f 3.0.0
+cdb52bbbe5b8770d5e68943b7e73bee4ba136ecc 3.1.0
+c3ba8a965a7a173e388d84819e936ea9bae9797f 3.2.0
+83882f2fbecba0b7e7f7e5d490b57db93bd7fa22 3.3.0
+fc04758ea9f549684989ee673b04d9724756dc85 3.3.1
+a03ea39aca2a66ea36817512d586dcbc99dbfe9b 3.3.2
+0304fc2bab158658df53a8f4edd5aa300a9497d2 4.0.0
+e914884fb7210d6350d94909cb25ebc602359680 4.0.1
+4d5d101e878f6d6264a8e036b11afdf922c4ef94 4.1.0
+c13b408c00066af78cda88734909c6f2f3505f76 5.0.0
+51e1e962172c0178394cd36652d90181319f5416 5.0.1
+0f30907852831f818bd0d01141b4ab7d8d71b821 5.0.1
+dbd0733e584073d6a7b6dea933767853e9cfe845 5.0.2
+bfe9be352453640233371cc7deb409a09decacf9 5.1.0
+9b8628e0a142e0e094e27430c388e3c12ceba513 5.1.1
+e886bc501796d53e0a19e608c6e5a6071191819e 5.1.2
+c52c15100fb2d85c3525d6d085b3663ec4f90fe6 5.1.3
+891c3ce894fa879532299910735bcc2a968245b1 5.1.4
+1377f6a7f9ecb25e9b8885fce8f6f42e0d6f3f12 5.1.5
+c79bdc8563509cd4e99946593d0b39af40271a30 5.2.0
+00026533ff9f52733a45df008e3d56a5d3a8e76a 5.2.0
+44a9dcb3fefcf8281ebe4e359e7dbb637512cf7f 5.2.0
+c15d6168412f175568dac89e6ee1cd8434fef906 5.2.1
+bd59cc2ee2039c370a0343f683488cde2a106565 5.3.0
+b21ce82e6f7640c2b38506545968650227d67e9b 5.4.0
+2ad40d972a740a613c4c559104166a015b37cac2 5.4.1
+727c7211c810d304ebf92b32db7ecf697ce46ac6 5.5.0
+99ede2d775458a236a46ad25a93aca473b676eee 5.6.0
+99ede2d775458a236a46ad25a93aca473b676eee 5.6.0
+e7b6e9c4a5d4317f56c2862910c569723b6ea71b 5.6.0
+70694b2621ba9d919bc38303f8901e84caf5da0f 5.6.1
--- a/COPYING	Thu Feb 23 15:19:31 2017 +0100
+++ b/COPYING	Thu Mar 02 18:07:46 2017 +0100
@@ -1,8 +1,8 @@
                     GNU GENERAL PUBLIC LICENSE
                        Version 2, June 1991
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+        51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -15,7 +15,7 @@
 General Public License applies to most of the Free Software
 Foundation's software and to any other program whose authors commit to
 using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
+the GNU Library General Public License instead.)  You can apply it to
 your programs, too.
 
   When we speak of free software, we are referring to freedom, not
@@ -303,9 +303,10 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
 
 Also add information on how to contact you by electronic and paper mail.
 
@@ -335,5 +336,5 @@
 This General Public License does not permit incorporating your program into
 proprietary programs.  If your program is a subroutine library, you may
 consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
+library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MANIFEST.in	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,26 @@
+exclude contrib/nopushpublish.py
+exclude hgext3rd/evolve/hack/*.py
+exclude hgext3rd/evolve/legacy.py
+exclude Makefile
+exclude tests/test-drop.t
+exclude tests/test-inhibit.t
+exclude tests/test-oldconvert.t
+include COPYING
+include docs/figures/hgview-example.png
+include docs/makefile
+include docs/*.py
+include docs/README
+include docs/*.rst
+include docs/static/*.svg
+include docs/tutorials/*.t
+include hgext3rd/__init__.py
+include hgext3rd/evolve/__init__.py
+include hgext3rd/evolve/serveronly.py
+include MANIFEST.in
+include README
+include setup.py
+include tests/*.py
+include tests/*.sh
+include tests/*.t
+prune debian
+recursive-include docs/figures *.svg
--- a/Makefile	Thu Feb 23 15:19:31 2017 +0100
+++ b/Makefile	Thu Mar 02 18:07:46 2017 +0100
@@ -1,3 +1,23 @@
+VERSION=$(shell python setup.py --version)
+
+
+help:
+	@echo 'Commonly used make targets:'
+	@echo '  deb-prepare - prepare the build of a debian package'
+
+all: help
+
+deb-prepare:
+	python setup.py sdist --dist-dir ..
+	mv -f ../hg-evolve-$(VERSION).tar.gz ../mercurial-evolve_$(VERSION).orig.tar.gz
+	tar xf ../mercurial-evolve_$(VERSION).orig.tar.gz
+	rm -rf ../mercurial-evolve_$(VERSION).orig
+	mv hg-evolve-$(VERSION) ../mercurial-evolve_$(VERSION).orig
+	cp -r debian/ ../mercurial-evolve_$(VERSION).orig/
+	@cd ../mercurial-evolve_$(VERSION).orig && echo 'debian build directory ready at' `pwd`
+
+# test targets
+
 PYTHON=python
 ifeq ($(HGROOT),)
   $(error HGROOT is not set to the root of the hg source tree)
@@ -17,6 +37,8 @@
 tests:
 	cd tests && $(PYTHON) $(HGTESTS)/run-tests.py $(TESTFLAGS)
 
+# /!\ run outside of the compatibility branch output test will likely fails
+
 test-%:
 	cd tests && $(PYTHON) $(HGTESTS)/run-tests.py $(TESTFLAGS) $@
 
@@ -25,6 +47,7 @@
 	(cd $(HGROOT) ; $(MAKE) clean ) && \
 	cd tests && $(PYTHON) $(HGTESTS)/run-tests.py $(TESTFLAGS)
 
-all-version-tests: tests-3.7 tests-@
+# build a script to extract declared version
+all-version-tests: tests-@
 
 .PHONY: tests all-version-tests
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,455 @@
+=============================
+Mutable History For Mercurial
+=============================
+
+This package supplies the ``evolve`` extension for Mercurial, which
+provides several commands to mutate history and deal with the
+resulting issues.
+
+It also:
+
+    - enables the "changeset obsolescence" feature of Mercurial
+    - issues several warning messages when trouble appears in your repository
+
+**This extension is experimental and not yet meant for production.**
+
+You can enable it by adding the line below to the ``extensions``
+section of your hgrc::
+
+    evolve = PATH/TO/evolve-main/hgext/evolve.py
+
+We recommend reading the documentation first. An online version is
+available here:
+
+    https://www.mercurial-scm.org/doc/evolution/
+
+Or see the ``doc/`` directory for a local copy.
+
+topic
+=====
+
+Topics are an experiment to see if maybe the workflow defined by git
+branches and hg bookmarks is only partially what users want - perhaps
+something that feels more like a traditional VCS branch is right, but
+that it should "dissolve" upon being finished. This extension exists
+to be a sandbox for that experimentation.
+
+# install
+
+Enable topics like any mercurial extension: download the source code to a
+local directory, and add that directory to your `.hgrc`:
+
+    [extensions]
+    topics=PATH/TO/evolve-main/hgext3rd/topic/
+
+# help
+
+See 'hg help -e topic' for a generic help.
+See 'hg help topics' and 'hg help stack' for help on specific commands.
+See the 'tests/test-topic-tutorial.t' file for a quick tutorial.
+
+Contribute
+==========
+
+Bugs are to be reported on the mercurial's bug tracker (component: evolution):
+https://bz.mercurial-scm.org/buglist.cgi?component=evolution&query_format=advanced&resolution=---
+
+Please use the patchbomb extension to send email to mercurial devel. Please
+make sure to use the evolve-ext flag when doing so. You can use a command like
+this:
+
+    hg email --to mercurial-devel@mercurial-scm.org --flag evolve-ext --rev '<your patches>'
+
+See also
+https://mercurial-scm.org/wiki/ContributingChanges#Patch_descriptions
+for guidelines on the patch description.
+
+Please don't forget to update and run the tests when you fix a bug or
+add a feature. To run the tests, you need a working copy of Mercurial,
+say in $HGSRC:
+
+    cd tests
+    python $HGSRC/tests/run-tests.py
+
+(evolve's stable and default branches correspond to Mercurial's stable
+and default branches. So to test evolve from default, you need
+Mercurial on default.)
+
+
+Changelog
+=========
+
+6.0.0 --
+
+  - drop compatibility for Mercurial < 3.8
+  - removed old (unpackaged) pushexperiment extension.
+  - move all extensions in the official 'hgext3rd' namespace package
+
+5.6.1 -- 2017-02-28
+
+ - fix a crash that sometime happened when evolving merges.
+
+5.6.0 -- 2017-02-01
+
+ - compatibility with Mercurial 4.1.
+ - improvement of prune error message.
+ - fold: require --from flag for folding revisions to working copy
+ - fix crash when trying to fold an empty revision set (issue5453)
+ - uncommit: preserve copy information of remaining files (issue5403)
+
+5.5.0 -- 2016-10-30
+
+ - The {obsolete} template now yield "obsolete" or "".
+ - compatibility with Mercurial 4.0
+ - Fix erroneous manifest computation when solving 'bumped' changeset.
+ - split: avoid crash on empty commit (issue5191),
+ - next: improve locking to avoid issue with working copy parent (issue5244)
+ - prev: improve locking to avoid issue with working copy parent (issue5244)
+ - evolve: fix abort suggestion to include '.' in 'hg update -C .'
+
+5.4.1 -- 2016-08-01
+
+ - compat with Mercurial 3.9
+
+5.4.0 -- 2016-05-06
+
+- Some collaboration with the topic experimental extensions,
+  - hg evolve --all with consider all troubles in your current topic,
+  - preserve 'topic' during evolve,
+  - 'next' and 'prev' restrict themself to the current topic by default,
+- remove the dangerous 'kill' alias for 'prune' (because 'hg kill -1' without
+the leading 'hg' will give you an hardtime)
+- during 'hg evolve' skip unsupported merge instead of aborting
+- various documentation fix and update
+- hg summary now suggest 'hg evolve --continue when appropriate`
+- compatibility with Mercurial 3.8 'hgext' namespace package.
+- small improvement to the `hg split` instruction
+- add a 'metaedit' command to rewrite changeset meta data.
+
+5.3.0 -- 2016-02-11
+
+- split: add a new command to split changesets,
+- tests: drop our copy of 'run-tests.py' use core one instead,
+- bookmark: do all bookmark movement within a transaction.
+- evolve: compatibility with Mercurial 3.7
+- evolve: support merge with a single obsolete parent (hg-3.7+ only)
+- evolve: prevent added file to be marked as unknown if evolve fails (issue4966)
+- evolve: stop relying on graftstate file for save evolve state
+          (for `hg evolve --continue`)
+- evolve: fix divergence resolution when it result in an empty commit
+          (issue4950) (hg-3.5+ only)
+- no longer lock the repository for `hg parents` (issue4895)
+- updated help for the `evolve` command
+
+5.2.1 -- 2015-11-02
+
+- add compatibility with Mercurial 3.6
+- prune: fixed possible issue with lock and bookmark
+- next/prev: fixed possible issue with lock and bookmark
+- add some progress data during changesets discovery
+- take advantage of dirstate/transaction collaboration
+
+5.2.0 -- 2015-06-25
+
+- evolve: gain a --rev option to control what revisions to evolve (issue4391)
+- evolve: revision are processed in the order they stack on destination
+- evolve: properly skip unstable revision with non-evolved unstable parent
+- evolve: gain --unstable --divergent --bumped flag to select the trouble
+- evolve: issue more useful error message and hint when evolve has nothing to
+          do as invocated.
+- evolve: bare `hg evolve` commands now abort when multiple changesets could be
+          a target.
+- evolve: `hg evolve --all` only evolve changeset that will end up as
+          descendant of the current working copy. The old behavior of `--all`
+          in now in `--all --any`.
+- evolve: add a 'experimental.evolutioncommands' for fine grained commands
+          enabling
+- next/prev: requires `--merge` to move with uncommitted changes
+- next: significantly reword error messages
+- next: add a --evolve flag to evolve aspiring children when on a head
+
+5.1.5 -- 2015-06-23
+
+- minor documentation cleanup
+- support -i option for `hg amend` if commit supports it (3.4)
+- fix the `debugrecordpruneparents` utility
+- fix some possible crash during command abort (release nonexistent transaction)
+- fix simple4server bug tracker URL
+- compatibility with bookmark API change in future Mercurial 3.5
+- prune no longer move the active bookmark for no reason (issue4559)
+- evolve: stop reporting divergence base as missing when we actually have it
+- significant performance improvement for all revsets.
+- provide a hint of how to update to the successor of an obsolete working copy
+  parent.
+
+5.1.4 -- 2015-04-23
+
+- significant documentation update
+- fix issue4616: pulling with bundle2 would crash if common marker when
+  discovered on non-served changesets.
+- fix the debugobsrelsethashtree command
+
+5.1.3 -- 2015-04-20
+
+- discovery: fix misbehaving discovery across python version
+- pull: properly install the bundle2 par generator
+  (avoid sending all markers for each pull)
+- commit: avoid potential deadlock (acquires wlock before lock)
+- graft: avoid potential deadlock (acquires wlock before lock)
+
+5.1.2 -- 2015-04-01
+
+- evolve: prevent a crash in httpclient_pushobsmarkers() when pushing
+
+5.1.1 -- 2015-03-05
+
+- debugobsconvert: fix invalid markers during conversion
+- discovery: cache some of the obs hash computation to improve performance (issue4518)
+- revset: fix some crash with (issue4515)
+
+5.1 -- 2015-01-30
+
+- evolve: explicitly disable bookmark on evolve (issue4432)
+- evolve: don't abort Mercurial on version mismatch
+- compatibility with mercurial 3.3
+
+5.0.2 -- 2014-12-14
+
+- evolve: remove dependency to the rebase extension
+
+5.0.1 -- 2014-11-25
+
+- amend: fix --logfile argument
+- evolve: preserve branch change when evolving
+- evolve: fix potential crash while solving `bumped` changesets.
+- uncommit: abort when rev specifies the current changeset
+- evolve: various message improvement
+- evolve: fix selection of changeset to evolve from the middle of a stack (issue4434)
+- evolve: make next/prev only move bookmarks optionally
+- evolve: tell user which "base of divergent changeset" is not found
+
+
+
+5.0.0 -- 2014-10-22
+
+- drop compat with Mercurial pre 3.2
+- uncommit: add a --rev argument
+- evolve: add a `working directory now at xxxxxxxxxx` message
+- evolve: automatically translate obsolete hashes when evolving
+- properly skip marker creating if patch apply cleanly
+- prune: work around a massive slowdown from lazy revset
+- grab: "fix" the grab alias on window
+
+- fix an issue where prune performance were quadratic with the number of
+  changesets pruned.
+- pull: use discovery to pull less obsmarkers through bundle2
+
+
+4.1.0 -- 2014-08-08
+
+- amend: add -D/--current-date option
+- amend: add -U/--current-user option
+- evolve: add a --tool option
+- evolve: add a --confirm option
+- mark "commit -o", "graft -o" and "graft -O" as deprecated since they are
+  unlikely to eventually make it into core.
+- push obsmarkers and phases in the same transaction than changesets
+  (when using hg >= 3.1 and bundle2-exp is enabled)
+- hide message about the obsolescence marker exchange behind a
+  `experimental.verbose-obsolescence-exchange` variable (default to False).
+
+4.0.1 -- 2014-08-08
+
+- createmarkers() accept an iterable (for compat with other extension)
+
+4.0.0 -- 2014-06-03
+
+- require Mercurial version 3.0.1 or above
+- some compatibility fixes with future 3.1.0
+- deprecated `gup` and `gdown` in favor of prev and next
+- record parent of pruned parent at prune time
+- added a `debugobsstorestat` command to gather data on obsmarker content.
+- added a `debugrecordpruneparents` command to upgrade existing prune marker
+  with parent information. Please run it once per repo after upgrading.
+- improvement to obsolescence marker exchange:
+  - added progress when pushing obsmarkers
+  - added multiple output during obsolescence markers exchange
+  - only push markers relevant to pushed subset
+  - add a new experimental way to exchange marker (when server support):
+    - added progress when pulling obsmarkers
+    - only pull markers relevant to pulled subset
+    - avoid exchanging common markers in some case
+    - use bundle2 as transport when available.
+ - add a hook related to the new commands
+
+3.3.2 -- 2014-05-14
+
+- fix a bug where evolve were creating changeset with 2 parents on windows
+  (fix issues #16, #35 and #42)
+- adds a --obsolete flag to import (requires Mercurial 3.0)
+- prune: update to successor rather than parent when pruning '.' with -s
+- fold: add missing --message and --logfile option
+- fold: add squash as an alias
+
+3.3.1 -- 2014-04-23
+
+- various language fix
+- active bookmark now move when using prev/next (#37)
+- fix some preservation of rename information on evolve (#33)
+- abort when evolve tries to move a node on top of itself (will helps on the #35 front)
+- fold: enable --date and --user options
+
+3.3.0 -- 2014-03-04
+
+- raise Mercurial's minimal requirement to 2.7
+- drop `latercomer` and `conflicting` compatibility. Those old alias are
+  deprecated for a long time now.
+- add verbose hint about how to handle corner case by hand.
+  This should help people until evolve is able to to it itself.
+- removed the qsync extension. The only user I knew about (logilab) is not
+  using it anymore. It not compatible with coming Mercurial version 2.9.
+- add progress indicator for long evolve command
+- report troubles creation from `hg import`
+
+3.2.0 -- 2013-11-15
+
+- conform to the Mercurial custom of lowercase messages
+- added a small extension to experiment with obsolescence marker push
+- amend: drop the deprecated note option
+- amend: use core mechanism for amend (fix multiple bugs)
+- parents command: add "working directory parent is obsolete" message
+- evolve command: allow updating to the successor if the parent is
+  obsolete
+- gdown and gup commands: add next and previous alias, respectively
+- make grab aliases compatible with Mercurial 2.8
+- Tested with 2.6, 2.7 and 2.8
+
+3.1.0 -- 2013-02-11
+
+- amend: drop deprecated --change option for amend
+- alias: add a grab alias to be used instead of graft -O
+- touch: add a --duplicate option to *not* obsolete the old version
+- touch: fix touching multiple revision at the same time
+- evolve: add a --all option
+- prune: various minor improvements
+- prune: add option to prune a specific bookmark
+- prune: add -u and -d option to control metadata
+
+3.0.0 -- 2013-02-02
+
+- compatibility with 2.5
+
+2.2.0 --
+
+- make evolve smarter at picking next troubled to solved without --any
+
+2.1.0 -- 2012-12-03
+
+- qsync fixes
+- have qfold ask for commit message
+
+2.0.0 -- 2012-10-26
+
+- compat with mercurial 2.4
+
+1.1.0 -- 2012-10-26
+
+- fix troubles creation reporting from rebase
+- rename latecomer to bumped
+- renamed conflicting to divergent
+- smarter divergent handling
+
+1.0.2 -- 2012-09-19
+
+- fix hg fold bug
+- fix hg pull --rebase
+- fix detection of conflict with external tools
+- adapt to core movement (caches and --amend)
+
+1.0.1 -- 2012-08-31
+
+- documentation improvement
+- fix a performance bug with hgweb
+
+1.0 -- 2012-08-29
+
+- Align with Mercurial version 2.3 (drop 2.2 support).
+- stabilize handle killed parent
+- stabilize handle late comer
+- stabilize handle conflicting
+- stabilize get a --continue switch
+- merge and update ignore extinct changeset in most case.
+- new "troubled()" revset
+- summary now reports troubles changesets
+- new touch command
+- new fold command
+- new basic olog alias
+
+- rebase refuse to work on public changeset again
+- rebase explicitly state that there is nothing to rebase because everything is
+  extinct() when that happen.
+- amend now cleanly abort when --change switch is misused
+
+
+0.7 -- 2012-08-06
+
+- hook: work around insanely huge value in obsolete pushkey call
+- pushkey: properly handle abort during obsolete markers push
+- amend: wrap the whole process in a single transaction.
+- evolve: tweak and add EOL to kill warning
+- obsolete: fix doc, rebase no longer aborts with --keep
+- obsolete/evolve: fix grammar in prerequisite messages
+- evolve: avoid duplication in graft wrapper
+- evolve: graft --continue is optional, test
+
+0.6 -- 2012-07-31
+
+- obsolete: change warning output to match mercurial core on
+- qsync: ignore nonexistent nodes
+- make compat server both compatible with "dump" and "dump%i" version
+
+0.5 -- 2012-07-16
+
+- obsolete: Detect conflicting changeset!
+- obsolete: adapt to core: marker are written in transaction now
+- evolve: add the solve alias to obsolete
+- doc: big update of terms and summary of the concept
+- evolve: switch the official name for "kill" to prune
+
+
+0.4.1 -- 2012-07-10
+
+- [convert] properly exclude null successors from conversion
+- Ignore buggy marker in newerversion
+
+
+0.4.0 -- 2012-07-06
+
+- obsolete: public changeset are no longer latecomer.
+- obsolete: move to official binary format
+- adapt for new mercurial
+- obsolete: we are not compatible with 2.1 any more
+
+0.3.0 -- 2012-06-27
+
+- obsolete:  Add "latecomer" error detection (stabilize does not handle resolution yet)
+- evolve:    Introduce a new `uncommit` command to remove change from a changeset
+- rebase:    allow the use of --keep again
+- commit:    --amend option create obsolete marker (but still strip)
+- obsolete:  fewer marker are created when collapsing revision.
+- revset:    add, successors(), allsuccessors(), precursors(), allprecursors(),
+             latecomer() and hidden()
+- evolve:    add `prune` alias to `kill`.
+- stabilize: clearly state that stabilize does not handle conflict
+- template:  add an {obsolete} keyword
+
+0.2.0 -- 2012-06-20
+
+- stabilize: improve choice of the next changeset to stabilize
+- stabilize: improve resolution of several corner case
+- rebase:    handle removing empty changesets
+- rebase:    handle --collapse
+- evolve:   add `obsolete` alias to `kill`
+- evolve:   add `evolve` alias to `stabilize`
+
+
--- a/README.md	Thu Feb 23 15:19:31 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# topics
-
-Topics are an experiment to see if maybe the workflow defined by git
-branches and hg bookmarks is only partially what users want - perhaps
-something that feels more like a traditional VCS branch is right, but
-that it should "dissolve" upon being finished. This extension exists
-to be a sandbox for that experimentation.
-
-# install
-
-Enable topics like any mercurial extension: download the source code to a
-local directory, and add that directory to your `.hgrc`:
-
-    [extensions]
-    topics=path/to/hg-topics/hgext3rd/topic/
-
-# help
-
-See 'hg help -e topic' for a generic help.
-See 'hg help topics' and 'hg help stack' for help on specific commands.
-See the 'tests/test-topic-tutorial.t' file for a quick tutorial.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/nopushpublish.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,36 @@
+# Extension which prevent changeset to be turn public by push operation
+#
+# Copyright 2011 Logilab SA        <contact@logilab.fr>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+
+from mercurial import extensions, util
+from mercurial import discovery
+
+def checkpublish(orig, repo, remote, outgoing, *args):
+
+    # is remote publishing?
+    publish = True
+    if 'phases' in remote.listkeys('namespaces'):
+        remotephases = remote.listkeys('phases')
+        publish = remotephases.get('publishing', False)
+
+    npublish = 0
+    if publish:
+        for rev in outgoing.missing:
+            if repo[rev].phase():
+                npublish += 1
+    if npublish:
+        repo.ui.warn("Push would publish %s changesets" % npublish)
+
+    ret = orig(repo, remote, outgoing, *args)
+    if npublish:
+        raise util.Abort("Publishing push forbidden",
+                         hint="Use `hg phase -p <rev>` to manually publish them")
+
+    return ret
+
+def uisetup(ui):
+    extensions.wrapfunction(discovery, 'checkheads', checkpublish)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/changelog	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,107 @@
+mercurial-evolve (5.6.1-1) UNRELEASED; urgency=medium
+
+  * New Upstream Release
+  * new upstream version
+
+ -- Pierre-Yves David <marmoute@nodosa.octopoid.net>  Tue, 28 Feb 2017 17:21:34 +0100
+
+mercurial-evolve (5.5.0-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org>  Sun, 30 Oct 2016 23:27:14 +0100
+
+mercurial-evolve (5.2.1-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Faheem Mitha <faheem@faheem.info>  Wed, 30 Dec 2015 03:46:06 +0530
+
+mercurial-evolve (5.2.0-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org>  Thu, 25 Jun 2015 17:41:56 -0700
+
+mercurial-evolve (5.1.3-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Julien Cristau <julien.cristau@logilab.fr>  Mon, 20 Apr 2015 14:44:45 +0200
+
+mercurial-evolve (5.0.2-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org>  Sun, 14 Dec 2014 12:43:28 -0800
+
+mercurial-evolve (5.0.1-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Faheem Mitha <faheem@faheem.info>  Wed, 12 Nov 2014 11:24:28 +0530
+
+mercurial-evolve (5.0.0+-1) UNRELEASED; urgency=low
+
+  * new upstream snapshot
+
+ -- Julien Cristau <julien.cristau@logilab.fr>  Mon, 17 Nov 2014 15:44:32 +0100
+
+mercurial-evolve (4.1.0-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Pierre-Yves David <pyd@marginatus.alto.octopoid.net>  Fri, 08 Aug 2014 23:15:11 -0700
+
+mercurial-evolve (4.0.1-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Pierre-Yves David <pyd@marginatus.alto.octopoid.net>  Fri, 08 Aug 2014 15:50:09 -0700
+
+mercurial-evolve (4.0.0-1) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * New upstream release.
+
+  [ Pierre-Yves David ]
+  * new upstream release
+
+ -- Pierre-Yves David <pyd@marginatus.alto.octopoid.net>  Fri, 08 Aug 2014 15:48:16 -0700
+
+mercurial-evolve (3.1.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Pierre-Yves David <pierre-yves.david@logilab.fr>  Mon, 04 Mar 2013 18:02:15 +0100
+
+mercurial-evolve (2.1.0-1) UNRELEASED; urgency=low
+
+  * New upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@logilab.fr>  Mon, 03 Dec 2012 15:19:19 +0100
+
+mercurial-evolve (1.1.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Pierre-Yves David <pierre-yves.david@logilab.fr>  Tue, 20 Nov 2012 16:28:12 +0100
+
+mercurial-evolve (1.0.2-1) UNRELEASED; urgency=low
+
+  * New upstream Release
+
+ -- Pierre-Yves David <pierre-yves.david@logilab.fr>  Wed, 19 Sep 2012 17:38:47 +0200
+
+mercurial-evolve (1.0.1-1) UNRELEASED; urgency=low
+
+  * New bug fix release
+  * remove conflicting __init__.py
+
+ -- Pierre-Yves David <pierre-yves.david@logilab.fr>  Fri, 31 Aug 2012 11:31:03 +0200
+
+mercurial-evolve (1.0.0-1) UNRELEASED; urgency=low
+
+  * Initial release.
+
+ -- Julien Cristau <jcristau@debian.org>  Fri, 24 Aug 2012 16:46:30 +0200
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/compat	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,1 @@
+8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/control	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,40 @@
+Source: mercurial-evolve
+Section: vcs
+Priority: optional
+Maintainer: Logilab <contact@logilab.fr>
+Uploaders:
+ Julien Cristau <julien.cristau@logilab.fr>,
+ Pierre-Yves David <pierre-yves.david@logilab.fr>,
+Standards-Version: 3.9.3
+Build-Depends:
+ mercurial (>= 3.4~),
+ python,
+ debhelper (>= 8),
+ python-sphinx (>= 1.0.8),
+ imagemagick,
+ librsvg2-bin,
+ wget,
+Python-Version: >= 2.6
+Homepage: https://www.mercurial-scm.org/doc/evolution/
+
+Package: mercurial-evolve
+Architecture: all
+Depends:
+ ${python:Depends},
+ ${misc:Depends},
+ mercurial (>= 3.3~),
+Description: evolve extension for Mercurial
+ This package provides the experimental "evolve" extension for the Mercurial
+ DVCS.
+ .
+ This extension provides several commands to mutate history and deal with issues
+ it may raise.
+ .
+ It also:
+  - enables the "Changeset Obsolescence" feature of mercurial,
+  - alters core command and extension that rewrite history to use this feature,
+  - improves some aspects of the early implementation in Mercurial 2.3.
+ .
+ **These extensions are experimental and are not meant for production.**
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/copyright	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,15 @@
+This software was downloaded from
+http://hg.netv6.net/evolve-main/
+
+Copyright 2011 Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
+               Logilab SA        <contact@logilab.fr>
+               Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+	       Patrick Mezard <patrick@mezard.eu>
+
+
+This software may be used and distributed according to the terms of the GNU
+General Public License version 2 or any later version.
+
+On Debian systems, the complete text of the GNU General Public License version
+2 can be found in `/usr/share/common-licenses/GPL-2'.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/docs	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,2 @@
+html
+README
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/rules	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,32 @@
+#!/usr/bin/make -f
+#export DH_VERBOSE=1
+
+%:
+	dh $@ --with python2 --buildsystem=python_distutils
+
+override_dh_auto_build:
+	dh_auto_build
+	$(MAKE) -C docs
+
+hgsrc_defined:
+	# Use "! -z" instead of "-n", because "-n" without arguments is true
+	test ! -z $(HGSRC) && test -d $(HGSRC) || (echo "$(HGSRC) is not a directory"; false)
+
+ifeq (,$(filter nocheck, $(DEB_BUILD_OPTIONS)))
+override_dh_auto_test: hgsrc_defined
+	cd tests && python $(HGSRC)/tests/run-tests.py --with-hg=$(HGSRC)/hg --blacklist=$(CURDIR)/debian/test-blacklist
+endif
+
+override_dh_python2:
+	# avoid conflict with mercurial's own hgext/__init__.py
+	find debian -name __init__.py -delete
+	dh_python2
+
+override_dh_auto_clean: clean-docs
+	dh_auto_clean
+	rm -f tests/*.err
+
+clean-docs:
+	rm -rf html
+	rm -f docs/static/logo-evolve.ico
+	rm -f docs/tutorials/tutorial.rst
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/source/format	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,1 @@
+3.0 (quilt)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/test-blacklist	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,4 @@
+test-drop.t
+test-inhibit.t
+test-simple4server.t
+tests/test-simple4server-bundle2.t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/README	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,3 @@
+doc generated with sphinx. tutorial exported using sphinxedhg
+
+http://hg.piranha.org.ua/sphinxedhg/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/concepts.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,223 @@
+.. Copyright 2014 Greg Ward <greg@gerg.ca>
+
+----------------
+Evolve: Concepts
+----------------
+
+Getting the most out of software requires an accurate understanding of
+the concepts underlying it. For example, you cannot use Mercurial to
+its full potential without understanding the DAG (directed acyclic
+graph) of changesets and the meaning of parent/child relationships
+between nodes in that graph. Mercurial with changeset evolution adds
+some additional concepts to the graph of changesets. Understanding
+those concepts will make you an informed and empowered user of
+``evolve``.
+
+.. note:: This document contains math! If you have a pathological fear
+          of set theory and the associated notation, you might be
+          better off just reading the `user guide`_. But if you
+          appreciate the theoretical rigour underlying core Mercurial,
+          you will be happy to know that it continues right into
+          changeset evolution.
+
+.. note:: This document is incomplete! (The formatting of the math
+          isn't quite right yet, and the diagrams are missing for
+          malformatted.)
+
+This document follows standard set theory notation::
+
+  x ∈ A: x is a member of A
+
+  A ∪ B: union of A and B: { x | x ∈ A or x ∈ B }
+
+  A ∖ B: set difference: { x | x ∈ A and x ∉ B }
+
+  A ⊇ B: superset: if x ∈ B, then x ∈ A
+
+.. _`user guide`: user-guide.html
+
+Phases
+------
+
+First, every changeset in a Mercurial repository (since 2.3) has a
+*phase*. Phases are independent of ``evolve`` and they affect
+Mercurial usage with or without changeset evolution. However, they
+were implemented in order to support evolution, and are a critical
+foundation of ``evolve``.
+
+Phases are strictly ordered:
+
+  secret > draft > public
+
+Changesets generally only move from a higher phase to a lower phase.
+Typically, changesets start life in *draft* phase, and move to
+*public* phase when they are pushed to a public repository. (You can
+set the default phase of new commits in Mercurial configuration.)
+
+The purpose of phases is to prevent modifying published history.
+``evolve`` will therefore only let you rewrite changesets in one of
+the two *mutable* phases (secret or draft).
+
+Run ``hg help phases`` for more information on phases.
+
+Obsolete changesets
+-------------------
+
+*Obsolescence* is they key concept at the heart of changeset
+evolution. Everything else in this document depends on understanding
+obsolescence. So: what does it mean for a changeset to be obsolete?
+
+In implementation terms, there is an *obsolescence marker* associated
+with changesets: every changeset is either obsolete or not.
+
+The simplest way that a changeset becomes obsolete is by *pruning* it.
+The ``hg prune`` command simply marks the specified changesets
+obsolete, as long as they are mutable.
+
+More commonly, a changeset *A* becomes obsolete by *amending* it.
+Amendment creates a new changeset *A'* that replaces *A*, which is now
+obsolete. *A'* is the successor of *A*, and *A* the predecessor of *A'*:
+
+  [diagram: A and A' with pred/succ edge]
+
+The predecessor/successor relationship forms an additional
+*obsolescence graph* overlaid on top of the traditional DAG formed by
+changesets and their parent/child relationships. In fact, the
+obsolescence graph is second-order version control. Where the
+traditional parent/child DAG tracks changes to your source code, the
+obsolescence graph tracks changes to your changesets. It tracks the
+evolution of your changesets.
+
+(If you prefer a calculus metaphor to set theory, it might help to
+think of the traditional parent/child DAG as the first derivative of
+your source code, and the obsolescence DAG as the second derivative.)
+
+Troubled changesets (unstable, bumped, divergent)
+-------------------------------------------------
+
+Evolving history can introduce problems that need to be solved. For
+example, if you prune a changeset *P* but not its descendants, those
+descendants are now on thin ice. To push a changeset to another
+repository *R*, all of its ancestors must be present in *R* or pushed
+at the same time. But Mercurial does not push obsolete changesets like
+*P*, so it cannot push the descendants of *P*. Any non-obsolete
+changeset that is a descendant of an obsolete changeset is said to be
+*unstable*.
+
+  [diagram: obsolete cset with non-obsolete descendant]
+
+Another sort of trouble occurs when two developers, Alice and Bob,
+collaborate via a shared non-publishing repository. (This is how
+developers can safely `share mutable history`_.) Say Alice and Bob
+both start the day with changeset *C* in *draft* phase. If Alice
+pushes *C* to their public repository, then it is now published and
+therefore immutable. But Bob is working from a desert island and
+cannot pull this change in *C*'s phase. For Bob, *C* is still in draft
+phase and therefore mutable. So Bob amends *C*, which marks it
+obsolete and replaces it with *C'*. When he is back online and pulls
+from the public repository, Mercurial learns that *C* is public, which
+means it cannot be obsolete. We say that *C'* is *bumped*, since it is
+the successor of a public changeset.
+
+.. _`share mutable history`: sharing.html
+
+(Incidentally, the terminology here comes from airline overbooking: if
+two people have bought tickets for the same seat on a plane and they
+both show up at the airport, only one of them gets on the plane. The
+passenger who is left behind in the airport terminal has been
+"bumped".)
+
+The third sort of trouble is when Alice and Bob both amend the same
+changeset *C* to have different successors. When this happens, the
+successors are both called *divergent* (unless one of them is in
+public phase; only mutable changesets are divergent).
+
+The collective term for unstable, bumped, and divergent changeset is
+*troubled*::
+
+  troubled = unstable ∪ bumped ∪ divergent
+
+It is possible for a changeset to be in any of the troubled categories
+at the same time: it might be unstable and divergent, or bumped and
+divergent, or whatever.
+
+  [diagram: Venn diagram of troubled changesets, showing overlap]
+
+The presence of troubled changesets indicates the need to run ``hg
+evolve``.
+
+Hidden (and visible) changesets
+-------------------------------
+
+Some obsolete changesets are *hidden*: deliberately suppressed by
+Mercurial and usually not visible through the UI. (As of Mercurial
+2.9, there are still some commands that inadvertently reveal hidden
+changesets; these are bugs and will be fixed in due course.)
+
+All hidden changesets are obsolete, and all obsolete changesets are
+part of your repository. Mathematically speaking::
+
+  repo ⊇ obsolete ⊇ hidden
+
+Or, putting it visually:
+
+  [diagram: Venn diagram showing nested strict subsets]
+
+However, the presence of obsolete but not hidden changesets should be
+temporary. The desired end state for any history mutation operation is
+that all obsolete changesets are hidden, i.e.:
+
+  repo ⊇ obsolete, obsolete = hidden
+
+Visually:
+
+  [diagram: Venn diagram showing obsolete = hidden, subset of repo]
+
+
+Why is this changeset visible?
+------------------------------
+
+Any changeset which is not hidden is *visible*. That is, ::
+
+  visible = repo ∖ hidden
+
+(Recall that ∖ means set difference: *visible* is the set of
+changesets that are in *repo* but not in *hidden*.)
+
+After amending or pruning a changeset, you might expect it to be
+hidden. It doesn't always work out that way. The precise rules are::
+
+  hideable = obsolete
+  blockers = bookmarks ∪ parents(workingcopy) ∪ localtags
+  hidden = hideable ∖ ancestors((repo ∖ hideable) ∪ blockers)
+
+This will probably be clearer with a worked example. First, here's a
+repository with some obsolete changesets, some troubled changesets,
+one bookmark, a working copy, and some hidden changesets::
+
+        x-x
+       /
+  -o-o-o-o
+     \
+      x-x-o
+
+Here's the computation required to determine which changesets are
+hidden::
+
+  repo = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }
+
+  hideable = obsolete = { 2, 4, 5, 8 }
+
+  blockers = { 6 } ∪ { 4 } ∪ {}
+
+  blockers = { 4, 6 }
+
+  hidden = hideable ∖ ancestors((repo ∖ { 2, 4, 5, 8 }) ∪ { 4, 6 })
+
+  hidden = hideable ∖ ancestors({ 0, 1, 3, 6, 7 } ∪ { 4, 6 })
+
+  hidden = hideable ∖ ancestors({ 0, 1, 3, 4, 6, 7 })
+
+  hidden = { 2, 4, 5, 8 } ∖ { 0, 1, 2, 3, 4, 5, 6, 7 }
+
+  hidden = { 8 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/conf.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,124 @@
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+#autoclass_content = 'both'
+# Add any paths that contain templates here, relative to this directory.
+#templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'evolve extension for Mercurial'
+copyright = '2010-2014, Pierre-Yves David, Greg Ward, and contributors'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.0'
+# The full version, including alpha/beta/rc tags.
+release = '0.0'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+unused_docs = []
+
+# List of directories, relative to source directories, that shouldn't be searched
+# for source files.
+#exclude_dirs = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+#html_style = 'sphinx-default.css'
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+html_title = project
+html_theme = 'haiku'
+html_theme_path = ['.']
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (within the static path) to place at the top of
+# the sidebar.
+#html_logo = 'logo-evolve.svg'
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = 'logo-evolve.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_use_modindex = False
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = '.html'
+
+# Output file base name for HTML help builder.
+#htmlhelp_basename = ''
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/evolve-faq.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,215 @@
+.. Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+..                Logilab SA        <contact@logilab.fr>
+
+-------------
+Evolve How To
+-------------
+
+
+
+Add a changeset: ``commit``
+---------------------------
+
+Just use commit as usual. New changesets will be in the `draft` phase.
+
+Rewrite a changeset: ``commit --amend``
+---------------------------------------
+
+It writes a new changeset combining working-directory parent changes and parent.
+It will work on any `draft` or `secret` changeset. It will not work on `public`
+changesets.
+
+To understand what the result of amend will be I use the two following
+aliases   [#]_::
+
+    # diff what amend will look like
+    pdiff=diff --rev .^
+
+    # status what amend will look like
+    pstatus=status --rev .^
+
+This command can even be invoked on changesets with children, provided
+none are public.
+
+.. [#] (defined by the evolve extension for you)
+
+
+
+Move a changeset: ``grab``
+--------------------------
+
+You can use ``hg grab <rev>`` to move a rev at your current location, making the
+old version obsolete.
+
+.. note:: grab is an alias for ``hg rebase --dest . --rev $@; hg up <result>``
+
+
+Delete a changeset: ``prune``
+-----------------------------
+
+A new ``prune`` command allows removing a changeset.
+
+Just use ``hg prune <some-rev>``.
+
+
+Moving within the history: ``gdown`` and ``gup``
+------------------------------------------------
+
+While working on mutable part of the history you often need to move between
+mutable commits.
+
+You just need to use standard update to work with evolve. For convenience, you
+can use ``hg gup`` to move to the child commit or ``hg gdown`` to move to the parent commit.
+
+Those command have ``previous`` and ``next`` alias.
+
+.. note:: Those commands only exist for the convenience of getting qpush and qpop
+          feeling back.
+
+Collapse changesets: ``fold``
+-----------------------------
+
+You can use ``hg fold`` to collapse multiple changesets in a single one.
+
+It takes two forms:
+
+``hg fold <rev>`` folds everything from you current changeset to `<rev>`
+
+``hg fold -r <revset>`` fold everything changeset matching the revset together.
+
+Getting changes out of a commit
+-------------------------------
+
+The ``hg uncommit`` command lets you rewrite the parent commit without
+selected changed files. Target files content is not altered and
+appears again as "modified"::
+
+  $ hg st
+  M babar
+  M celestine
+  $ hg commit babar celestine
+  $ hg st
+  $ hg uncommit celestine
+  $ hg status
+  M celestine
+
+Split a changeset
+-----------------
+
+To split on file boundaries, just use ``uncommit`` command.
+
+If you need a fine-grained split, there is no official command for that yet.
+However, it is easily achieved by manual operation::
+
+  ### you want to split changeset A: 42
+  # update to A parent
+  $ hg up 42^
+  # restore content from A
+  $ hg revert -r 42 --all
+  # partially commit the first part
+  $ hg record
+  # commit the second part
+  $ hg commit
+  # informs mercurial of what happened
+  # current changeset (.) and previous one (.^) replace A (42)
+  $ hg prune --new . --new .^ 42
+
+For more complexe scenario we recommend the use of the histedit_ extension.
+
+.. _histedit: https://www.mercurial-scm.org/wiki/HisteditExtension
+
+
+Update my current work in progress after a pull
+-----------------------------------------------
+
+Whenever you are working on some changesets, it is more likely that a pull
+will, eventually, import new changesets in your tree.
+
+And it is likely that you will want your work in progress changesets to be
+rebased on the top of this newly imported subtree.
+
+Doing so is only a matter of rebasing.
+
+
+
+Move multiple changesets: ``rebase``
+------------------------------------
+
+You can still use rebase to move a whole segment of the changeset graph together.
+
+.. warning:: Beware that rebasing changesets already obsolete will likely result in
+             divergent versions of the changesets.
+
+Resolve history troubles: ``evolve``
+------------------------------------
+
+When you rewrite (amend) a changeset with children without rewriting
+those children you create *unstable* changesets and *suspended
+obsolete* changesets.
+
+When you are finished amending a given changeset, you will want to
+declare it stable, in other words rebase its former descendants on its
+newest version.
+
+You can also use evolve to solve `bumped` and `divergent` changeset/
+
+
+Fix my history afterward: ``prune -n``
+--------------------------------------
+
+Sometimes you need to create an obsolete marker by hand. This may happen when
+upstream has applied some of your patches for example.
+
+you can use ``hg prune <old-changeset> --succ <new-changeset>`` to add obsolete
+marker.
+
+View diff from the last amend
+-----------------------------
+
+An ``odiff`` alias have been added by ``enable.sh``
+
+::
+    [alias]
+    odiff = diff --rev 'limit(precursors(.),1)' --rev .
+
+View obsolete markers
+---------------------
+
+hgview_ is the only viewer that currently supports this feature. You
+need version 1.6.2
+
+.. _hgview: http://www.logilab.org/project/hgview/
+
+.. image:: figures/hgview-example.png
+    :scale: 50%
+
+
+You can also use a debug command
+
+    $ hg debugobsolete
+      5eb72dbe0cb4 e8db4aa611f6
+      c4cbebac3751 4f1c269eab68
+
+
+
+Important Note
+==============
+
+View change to your file
+------------------------
+
+Extinct changesets are hidden using the *hidden* feature of mercurial.
+
+Only ``hg log`` and ``hgview`` support it, other
+graphical viewer do not.
+
+You can use ``hg log --graph --hidden`` from the command line
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/evolve-good-practice.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,47 @@
+.. Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+..                Logilab SA        <contact@logilab.fr>
+
+-----------------------------------------
+Good practice for (early) users of evolve
+-----------------------------------------
+
+Avoid unstability
+-----------------
+
+The less unstability you have the less you need to resolve.
+
+Evolve is not yet able to detect and solve every situation. And your mind is
+not ready neither.
+
+Branch as much as possible
+--------------------------
+
+This is not MQ; you are not constrained to linear history.
+
+Making a branch per independent branch will help you avoid unstability
+and conflict.
+
+Rewrite your changes only
+-------------------------
+
+There is no descent conflict detection and handling right now.
+Rewriting other people's changesets guarantees that you will get
+conflicts. Communicate with your fellow developers before trying to
+touch other people's work (which is a good practice in any case).
+
+Using multiple branches will help you to achieve this goal.
+
+Prefer pushing unstability to touching other people changesets
+--------------------------------------------------------------
+
+
+If you have children changesets from other people that you don't really care
+about, prefer not altering them to risking a conflict by stabilizing them.
+
+
+Do not get too confident
+------------------------
+
+This is an experimental extension and a complex concept. This is beautiful,
+powerful and robust on paper, but the tool and your mind may not be prepared for
+all situations yet.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug01.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="200"
+   height="150"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug01.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path3998"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3976">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3978" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3980" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path5316"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5292"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path5289"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5253">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5255" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop5257" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5245"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5247" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5207"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5209" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5253"
+       id="linearGradient5259"
+       x1="384.79102"
+       y1="262.99402"
+       x2="391.83789"
+       y2="262.99402"
+       gradientUnits="userSpaceOnUse" />
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3976"
+       id="linearGradient3986"
+       x1="21.490866"
+       y1="78.901947"
+       x2="53.729759"
+       y2="78.901947"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(1.9995778e-6,24.148893)" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1"
+     inkscape:cx="73.6273"
+     inkscape:cy="87.13832"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:window-width="976"
+     inkscape:window-height="802"
+     inkscape:window-x="18"
+     inkscape:window-y="350"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:snap-global="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid8451"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0.078084198px"
+       originy="-2924.5747px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0.0780842,2022.2125)" />
+  <g
+     id="g6159"
+     transform="matrix(0.9999958,0,0,1,-382.57893,-238.18697)">
+    <rect
+       y="238.83586"
+       x="383.08054"
+       height="18.05327"
+       width="21.481829"
+       id="rect2987"
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217"
+       y="252.23067"
+       x="390.00699"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="252.23067"
+         x="390.00699"
+         id="tspan5219"
+         sodipodi:role="line">0</tspan></text>
+  </g>
+  <g
+     id="g3802"
+     transform="translate(10.633744,0.14889301)">
+    <rect
+       y="0.50000465"
+       x="49.866257"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8"
+       y="13.894781"
+       x="56.792801"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156"
+         sodipodi:role="line"
+         x="56.792801"
+         y="13.894781">1</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.981735,9.6755275 38.518266,4.2e-6"
+     id="path8263"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-start="#g6159"
+     inkscape:connection-end="#g3802"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+     x="46.543751"
+     y="42.826393"
+     id="text5217-8-0"
+     sodipodi:linespacing="125%"
+     transform="scale(0.9999979,1.0000021)"><tspan
+       sodipodi:role="line"
+       id="tspan8594"
+       x="46.543751"
+       y="42.826393">hg commit --amend</tspan></text>
+  <path
+     style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+     id="path8598"
+     inkscape:connector-curvature="0" />
+  <g
+     id="g3821"
+     transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)">
+    <path
+       inkscape:connector-curvature="0"
+       id="path8466-5"
+       d="M 35.5,23.60911 35.5,59.5"
+       style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path8466-4-7"
+       d="M 33.5,23.60911 33.5,59.5"
+       style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+  </g>
+  <g
+     id="g6159-9"
+     transform="matrix(0.9999958,0,0,1,-382.5698,-144.46361)">
+    <rect
+       y="238.83586"
+       x="383.08054"
+       height="18.05327"
+       width="21.481829"
+       id="rect2987-41"
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217-7"
+       y="252.23067"
+       x="390.00699"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="252.23067"
+         x="390.00699"
+         id="tspan5219-3"
+         sodipodi:role="line">0</tspan></text>
+  </g>
+  <g
+     id="g3916"
+     transform="translate(9.5649648e-7,23.723361)">
+    <rect
+       y="107.72337"
+       x="60.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-7"
+       y="121.11791"
+       x="65.68634"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         y="121.11791"
+         x="65.68634"
+         id="tspan3914"
+         sodipodi:role="line">1'</tspan></text>
+  </g>
+  <g
+     id="g3969"
+     transform="translate(4.0851082,20.999957)">
+    <path
+       transform="matrix(2.0019166,-0.33373336,0.24981576,1.1431983,-230.26746,31.077255)"
+       inkscape:transform-center-y="-0.9468898"
+       inkscape:transform-center-x="-0.82266973"
+       d="m 157.12291,94.440838 c -1.18183,1.454597 -8.91272,-1.300343 -10.79635,-1.00274 -1.88363,0.297602 -2.27986,5.900632 -3.98505,5.130533 -1.7052,-0.7701 -3.74374,-5.759198 -4.73141,-7.362338 -0.98766,-1.603141 -6.98979,-4.377117 -7.06039,-6.057672 -0.0706,-1.680555 6.93719,-0.349919 7.75648,-1.903786 0.81928,-1.553866 0.0513,-8.775377 1.58159,-9.477758 1.53031,-0.70238 3.98957,4.754872 5.63472,5.323605 1.64516,0.568733 10.20851,-0.835155 11.23768,0.484831 1.02916,1.319987 -4.3673,5.790377 -4.35486,7.530709 0.0124,1.740332 5.89943,5.880018 4.71759,7.334616 z"
+       inkscape:randomized="0.15"
+       inkscape:rounded="0.2"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.268675"
+       sodipodi:arg1="0.64035647"
+       sodipodi:r2="6.7602978"
+       sodipodi:r1="13.520596"
+       sodipodi:cy="85.499779"
+       sodipodi:cx="144.7717"
+       sodipodi:sides="5"
+       id="path3943"
+       style="fill:none;stroke:#686868;stroke-width:0.68990517;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       sodipodi:type="star" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text3957"
+       y="84.170212"
+       x="69.021271"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       xml:space="preserve"><tspan
+         y="84.170212"
+         x="69.021271"
+         id="tspan3959"
+         sodipodi:role="line">poof!</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:url(#linearGradient3986);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2, 1;stroke-dashoffset:0;marker-mid:none;marker-end:none"
+     d="m 21.990865,103.39791 57.925771,-0.005"
+     id="path3974"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end-point="d4"
+     inkscape:connection-end="#g3969"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-start="#g6159-9" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-6)"
+     d="m 21.990865,110.03677 38.509136,23.79872"
+     id="path5012"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g6159-9"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g3916"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="46.760448"
+     y="58.872295"
+     id="text5223"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan5227"
+       x="46.760448"
+       y="58.872295">(destructive, not using evolve)</tspan></text>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug02.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,590 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="250"
+   height="250"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug02.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotS"
+       style="overflow:visible">
+      <path
+         id="path4196"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.2,0,0,0.2,1.48,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path3998"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path5316"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5292"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path5289"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5253">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5255" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop5257" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5245"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5247" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5207"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5209" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5253"
+       id="linearGradient5259"
+       x1="384.79102"
+       y1="262.99402"
+       x2="391.83789"
+       y2="262.99402"
+       gradientUnits="userSpaceOnUse" />
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-9"
+       style="overflow:visible">
+      <path
+         id="path5316-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-1"
+       style="overflow:visible">
+      <path
+         id="path5316-9"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.7318511"
+     inkscape:cx="113.8845"
+     inkscape:cy="138.3052"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:window-width="974"
+     inkscape:window-height="1048"
+     inkscape:window-x="104"
+     inkscape:window-y="103"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:snap-global="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid8451"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0.078088198px"
+       originy="-2937.8154px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0.0780882,2135.4532)" />
+  <g
+     id="g6159"
+     transform="matrix(0.9999958,0,0,1,-382.57893,-236.94626)">
+    <rect
+       y="238.83586"
+       x="383.08054"
+       height="18.05327"
+       width="21.481829"
+       id="rect2987"
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217"
+       y="252.23067"
+       x="390.00699"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="252.23067"
+         x="390.00699"
+         id="tspan5219"
+         sodipodi:role="line">0</tspan></text>
+  </g>
+  <g
+     id="g3802"
+     transform="translate(10.633748,1.389597)">
+    <rect
+       y="0.50000465"
+       x="49.866257"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8"
+       y="13.894781"
+       x="56.792801"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156"
+         sodipodi:role="line"
+         x="56.792801"
+         y="13.894781">1</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.981735,10.916236 38.51827,1e-6"
+     id="path8263"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-start="#g6159"
+     inkscape:connection-end="#g3802"
+     inkscape:connection-end-point="d4" />
+  <g
+     id="g6159-9"
+     transform="matrix(1.0000075,0,0,1,-382.57429,-102.14843)">
+    <rect
+       y="238.83586"
+       x="383.08054"
+       height="18.05327"
+       width="21.481829"
+       id="rect2987-41"
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217-7"
+       y="252.23067"
+       x="390.00699"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="252.23067"
+         x="390.00699"
+         id="tspan5219-3"
+         sodipodi:role="line">0</tspan></text>
+  </g>
+  <g
+     id="g4101"
+     transform="translate(3.9991556e-6,76)">
+    <rect
+       y="131.44673"
+       x="60.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-7"
+       y="144.84122"
+       x="67.447083"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         y="144.84122"
+         x="67.447083"
+         id="tspan3914"
+         sodipodi:role="line">3</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-6);display:inline"
+     d="m 18.903026,154.7407 44.684935,52.70603"
+     id="path5012"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g6159-9"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4101"
+     inkscape:connection-end-point="d4" />
+  <g
+     id="g6499"
+     transform="translate(1.9995778e-6,23.240701)">
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-0"
+       y="42.826412"
+       x="46.543755"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         y="42.826412"
+         x="46.543755"
+         id="tspan8594"
+         sodipodi:role="line">hg commit --amend</tspan></text>
+    <text
+       sodipodi:linespacing="125%"
+       id="text5223"
+       y="54.872299"
+       x="46.760452"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       xml:space="preserve"><tspan
+         y="54.872299"
+         x="46.760452"
+         id="tspan5227"
+         sodipodi:role="line">(safe, using evolve)</tspan></text>
+  </g>
+  <g
+     id="g4022"
+     transform="translate(3.9991556e-6,42.31518)">
+    <rect
+       y="94.372253"
+       x="60.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-0"
+       style="fill:none;stroke:#404040;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-9"
+       y="107.76683"
+       x="67.426567"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-7"
+         sodipodi:role="line"
+         x="67.426567"
+         y="107.76683">1</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#404040;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.94117647;stroke-dasharray:none;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.991109,145.71407 38.508895,0"
+     id="path8263-2"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g6159-9"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4022"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="122.10091"
+     y="140.49216"
+     id="text4115"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4117"
+       x="122.10091"
+       y="140.49216" /></text>
+  <g
+     id="g5472"
+     transform="translate(1.9995778e-6,1.240699)">
+    <rect
+       y="135.44673"
+       x="120.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-0-0"
+       style="fill:none;stroke:#404040;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0" />
+    <text
+       inkscape:transform-center-x="2.6044813"
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-9-2"
+       y="148.84123"
+       x="127.4267"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-7-4"
+         sodipodi:role="line"
+         x="127.4267"
+         y="148.84123">2</tspan></text>
+  </g>
+  <text
+     xml:space="preserve"
+     style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="140.76923"
+     y="136.65099"
+     id="text4119"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4121"
+       x="140.76923"
+       y="136.65099"
+       style="font-size:8px;font-weight:bold;-inkscape-font-specification:Sans Bold">T</tspan></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM)"
+     d="m 71.240874,154.7407 0,52.70603"
+     id="path4123"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4022"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4101"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="175.07857"
+     y="112.16577"
+     id="text4787"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       x="175.07857"
+       y="112.16577"
+       id="tspan4791">temporary</tspan><tspan
+       sodipodi:role="line"
+       x="175.07857"
+       y="122.16577"
+       id="tspan4795">amend</tspan><tspan
+       sodipodi:role="line"
+       x="175.07857"
+       y="132.16577"
+       id="tspan4797">commit</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="51.716301"
+     y="112.74194"
+     id="text4799"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4801"
+       x="51.716301"
+       y="112.74194">obsolete (and hidden)</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="94.602974"
+     y="171.26965"
+     id="text4803"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4805"
+       x="94.602974"
+       y="171.26965">precursor</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="94.461372"
+     y="189.68568"
+     id="text4807"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4809"
+       x="94.461372"
+       y="189.68568">successor</tspan></text>
+  <path
+     style="fill:none;stroke:#7d7d7d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="M 92.837054,168.99918 C 80.990247,168.9329 79.499863,165.60079 77.196029,156.38545"
+     id="path5061"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;stroke:#7d7d7d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="M 93.341603,186.6584 C 79.50523,184.42591 75.177832,194.04021 75.177832,205.32672"
+     id="path5263"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="m 173.06037,115.51697 c -10.90807,9.681 -3.90454,20.30854 -25.22746,18.66832"
+     id="path5689"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 97.377997,116.02152 c 1.765752,12.09244 -25.911587,2.23195 -29.768403,17.65922"
+     id="path5893"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 99.093394,115.78744 c -1.76575,12.09244 25.911586,2.23195 29.768406,17.65922"
+     id="path5893-7"
+     inkscape:connector-curvature="0" />
+  <g
+     id="g6493"
+     transform="translate(1.9995778e-6,1.240701)">
+    <path
+       inkscape:connector-curvature="0"
+       id="path8598"
+       d="m 36.655934,114.93533 3.649333,6.32067 3.711171,-6.42777"
+       style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <g
+       transform="translate(0.73014858,0)"
+       id="g6489">
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1.21219063;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 40.606,21.314861 0,98.078949"
+         id="path8466-5"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1.10104096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 38.5505,21.370511 0,98.078949"
+         id="path8466-5-3"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Mend-2)"
+     d="m 81.981743,145.71407 38.518257,0"
+     id="path3069"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4022"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g5472"
+     inkscape:connection-end-point="d4" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug03.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="200"
+   height="150"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug03.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path3998"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path5316"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5292"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path5289"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5253">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5255" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop5257" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5245"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5247" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5207"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5209" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5253"
+       id="linearGradient5259"
+       x1="384.79102"
+       y1="262.99402"
+       x2="391.83789"
+       y2="262.99402"
+       gradientUnits="userSpaceOnUse" />
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-7"
+       style="overflow:visible">
+      <path
+         id="path5316-3"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.4712371"
+     inkscape:cx="72.857038"
+     inkscape:cy="79.643357"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:window-width="976"
+     inkscape:window-height="802"
+     inkscape:window-x="179"
+     inkscape:window-y="330"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:snap-global="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid8451"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0.078084198px"
+       originy="-2924.5747px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0.0780842,2022.2125)" />
+  <g
+     id="g6622"
+     transform="translate(0,18)">
+    <g
+       id="g6602">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987"
+         width="21.481739"
+         height="18.05327"
+         x="0.49999696"
+         y="0.64889121" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="7.4264359"
+         y="14.043668"
+         id="text5217"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           sodipodi:role="line"
+           id="tspan5219"
+           x="7.4264359"
+           y="14.043668"
+           style="stroke:none">3</tspan></text>
+    </g>
+    <g
+       id="g6612">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4"
+         width="21.481739"
+         height="18.05327"
+         x="60.5"
+         y="0.64889765" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="67.426567"
+         y="14.043674"
+         id="text5217-8"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="14.043674"
+           x="67.426567"
+           sodipodi:role="line"
+           id="tspan3900">4</tspan></text>
+    </g>
+    <path
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path8263"
+       d="m 21.981735,9.6755275 38.518266,4.2e-6"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline" />
+  </g>
+  <g
+     id="g6397"
+     transform="translate(1.2139669,17.353636)">
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-0"
+       y="53.910118"
+       x="46.543751"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         y="53.910118"
+         x="46.543751"
+         id="tspan8594"
+         sodipodi:role="line">hg prune .</tspan></text>
+    <g
+       id="g6372">
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         id="path8598"
+         inkscape:connector-curvature="0" />
+      <g
+         id="g3821"
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)">
+        <path
+           inkscape:connector-curvature="0"
+           id="path8466-5"
+           d="M 35.5,23.60911 35.5,59.5"
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+        <path
+           inkscape:connector-curvature="0"
+           id="path8466-4-7"
+           d="M 33.5,23.60911 33.5,59.5"
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      </g>
+    </g>
+  </g>
+  <g
+     id="g6607">
+    <rect
+       y="101.77834"
+       x="0.49999696"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-7"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-9"
+       y="115.1729"
+       x="7.4264359"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan3904"
+         style="stroke:none"
+         y="115.1729"
+         x="7.4264359"
+         sodipodi:role="line">3</tspan></text>
+  </g>
+  <g
+     id="g6617">
+    <rect
+       y="101.77834"
+       x="60.500004"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-2"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999791,1.99999583;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-2"
+       y="115.1729"
+       x="67.426567"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan3908"
+         sodipodi:role="line"
+         x="67.426567"
+         y="115.1729">4</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.981736,110.80498 38.518268,0"
+     id="path8263-2"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g6607"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g6617"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="120.84515"
+     y="108.62753"
+     id="text4799"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan4801"
+       x="120.84515"
+       y="108.62753"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans Italic">obsolete,</tspan><tspan
+       sodipodi:role="line"
+       x="120.84515"
+       y="118.62753"
+       id="tspan4155"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans Italic">hidden,</tspan><tspan
+       sodipodi:role="line"
+       x="120.84515"
+       y="128.62753"
+       id="tspan4157"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans Italic">no successors</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="87.810272"
+     y="8.7751856"
+     id="text4353"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4355"
+       x="87.810272"
+       y="8.7751856">working dir</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="20.528839"
+     y="144.07831"
+     id="text4353-8"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4355-6"
+       x="20.528839"
+       y="144.07831">working dir</tspan></text>
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-7)"
+     d="m 20.030453,140.89525 c -8.427525,-2.11036 -7.688456,-10.62543 -7.688456,-18.00718"
+     id="path5792"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-mid:none;marker-end:url(#Arrow2Mend-7)"
+     d="M 118.5641,115.19962 C 102.21283,112.97531 103.7629,98.729709 86.191648,105.48788"
+     id="path5986"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-7)"
+     d="M 85.382337,4.3239755 C 75.008244,4.2518573 73.079961,8.1306941 70.814734,16.058989"
+     id="path6831"
+     inkscape:connector-curvature="0" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug04.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,547 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="240"
+   height="205"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug04.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotS"
+       style="overflow:visible">
+      <path
+         id="path4196"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.2,0,0,0.2,1.48,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path3998"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path5316"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5292"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path5289"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5253">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5255" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop5257" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5245"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5247" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5207"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5209" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5253"
+       id="linearGradient5259"
+       x1="384.79102"
+       y1="262.99402"
+       x2="391.83789"
+       y2="262.99402"
+       gradientUnits="userSpaceOnUse" />
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-9"
+       style="overflow:visible">
+      <path
+         id="path5316-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-1"
+       style="overflow:visible">
+      <path
+         id="path5316-9"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.6388172"
+     inkscape:cx="115.17834"
+     inkscape:cy="50.304612"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:window-width="974"
+     inkscape:window-height="1048"
+     inkscape:window-x="104"
+     inkscape:window-y="103"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:snap-global="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid8451"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0.078090195px"
+       originy="-3032.6372px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0.0780902,2185.275)" />
+  <g
+     id="g4373"
+     transform="translate(1.9967556e-6,-0.17817035)">
+    <rect
+       y="1.3195724"
+       x="0.4999969"
+       height="18.05327"
+       width="21.481733"
+       id="rect2987"
+       style="fill:none;stroke:#000000;stroke-width:0.99999779;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999978,1.0000022)"
+       sodipodi:linespacing="125%"
+       id="text5217"
+       y="14.714343"
+       x="7.426435"
+       style="font-size:11.9999733px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="14.714343"
+         x="7.426435"
+         id="tspan5219"
+         sodipodi:role="line">3</tspan></text>
+  </g>
+  <g
+     id="g4378"
+     transform="translate(1.9967556e-6,-0.17817035)">
+    <rect
+       y="1.3195724"
+       x="60.499989"
+       height="18.05327"
+       width="21.481733"
+       id="rect2987-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999779;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999978,1.0000022)"
+       sodipodi:linespacing="125%"
+       id="text5217-8"
+       y="14.714343"
+       x="67.426567"
+       style="font-size:11.9999733px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156"
+         sodipodi:role="line"
+         x="67.426567"
+         y="14.714343">5</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999779px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.981731,10.168036 38.518259,10e-7"
+     id="path8263"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0" />
+  <g
+     id="g4383"
+     transform="translate(1.9967556e-6,-36.178171)">
+    <g
+       transform="matrix(1.0000072,0,0,1,-382.57418,-102.71846)"
+       id="g6159-9">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-41"
+         width="21.481829"
+         height="18.05327"
+         x="383.08054"
+         y="238.83586" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="390.00699"
+         y="252.23067"
+         id="text5217-7"
+         sodipodi:linespacing="125%"><tspan
+           sodipodi:role="line"
+           id="tspan5219-3"
+           x="390.00699"
+           y="252.23067"
+           style="stroke:none">3</tspan></text>
+    </g>
+  </g>
+  <g
+     id="g4395"
+     transform="translate(1.9967556e-6,-36.178171)">
+    <g
+       transform="translate(4.0689943e-6,75.42997)"
+       id="g4101">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4-4"
+         width="21.481739"
+         height="18.05327"
+         x="60.5"
+         y="131.44673" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="67.447083"
+         y="144.84122"
+         id="text5217-8-7"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           sodipodi:role="line"
+           id="tspan3914"
+           x="67.447083"
+           y="144.84122">6</tspan></text>
+    </g>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-6);display:inline"
+     d="m 18.903021,117.9925 44.684942,52.70603"
+     id="path5012"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end="#g4395"
+     inkscape:connection-end-point="d4"
+     inkscape:connection-start="#g4383"
+     inkscape:connection-start-point="d4" />
+  <g
+     id="g4389"
+     transform="translate(1.9967556e-6,-36.178171)">
+    <g
+       transform="translate(4.0689943e-6,41.74515)"
+       id="g4022">
+      <rect
+         style="fill:none;stroke:#404040;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0"
+         id="rect2987-4-0"
+         width="21.481739"
+         height="18.05327"
+         x="60.5"
+         y="94.372253" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="67.426567"
+         y="107.76683"
+         id="text5217-8-9"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="107.76683"
+           x="67.426567"
+           sodipodi:role="line"
+           id="tspan6156-7">5</tspan></text>
+    </g>
+  </g>
+  <path
+     style="fill:none;stroke:#404040;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.94117647;stroke-dasharray:none;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.991099,108.96587 38.508907,0"
+     id="path8263-2"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="122.10089"
+     y="139.74393"
+     id="text4115"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4117"
+       x="122.10089"
+       y="139.74393" /></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM)"
+     d="m 71.240876,117.9925 0,52.70603"
+     id="path4123"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="131.67636"
+     y="97.973274"
+     id="text4799"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4801"
+       x="131.67636"
+       y="97.973274">obsolete, hidden</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="94.602959"
+     y="134.52141"
+     id="text4803"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4805"
+       x="94.602959"
+       y="134.52141">precursor</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="94.461357"
+     y="152.93744"
+     id="text4807"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4809"
+       x="94.461357"
+       y="152.93744">successor</tspan></text>
+  <path
+     style="fill:none;stroke:#7d7d7d;stroke-width:0.99999988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="M 92.83703,132.25098 C 80.990226,132.18468 79.499843,128.85259 77.19601,119.63725"
+     id="path5061"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;stroke:#7d7d7d;stroke-width:0.99999988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="M 93.341579,149.9102 C 79.50521,147.67771 75.177813,157.29201 75.177813,168.57852"
+     id="path5263"
+     inkscape:connector-curvature="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="131.8273"
+     y="14.09236"
+     id="text4799-8"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4801-4"
+       x="131.8273"
+       y="14.09236">working dir (clean)</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="133.3548"
+     y="177.91992"
+     id="text4799-8-1"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       x="133.3548"
+       y="177.91992"
+       id="tspan3129">working dir</tspan><tspan
+       sodipodi:role="line"
+       x="133.3548"
+       y="190.41992"
+       id="tspan3137">(with uncommitted</tspan><tspan
+       sodipodi:role="line"
+       x="133.3548"
+       y="202.91992"
+       id="tspan3135">changes to f1 f2 ...)</tspan></text>
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="M 127.70873,11.814007 C 109.60365,21.89832 105.56713,4.2966494 86.402349,8.4033887"
+     id="path4609"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="M 127.70873,95.185669 C 112.22803,107.58577 114.03479,115.58851 86.023391,109.58606"
+     id="path5019"
+     inkscape:connector-curvature="0" />
+  <g
+     id="g5433"
+     transform="translate(1.9967556e-6,-0.17817035)">
+    <text
+       transform="scale(0.9999978,1.0000022)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-0"
+       y="58.841717"
+       x="46.92271"
+       style="font-size:11.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         y="58.841717"
+         x="46.92271"
+         id="tspan8594"
+         sodipodi:role="line">hg uncommit <tspan
+   id="tspan3131"
+   style="font-style:italic">f1 f2 ...</tspan></tspan></text>
+    <g
+       transform="translate(-0.59241834,4.9316169)"
+       id="g6372">
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         id="path8598-5"
+         inkscape:connector-curvature="0" />
+      <g
+         id="g3821"
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)">
+        <path
+           inkscape:connector-curvature="0"
+           id="path8466-5-0"
+           d="M 35.5,23.60911 35.5,59.5"
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+        <path
+           inkscape:connector-curvature="0"
+           id="path8466-4-7"
+           d="M 33.5,23.60911 33.5,59.5"
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      </g>
+    </g>
+  </g>
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="M 129.98248,191.8189 C 105.83194,202.48442 106.0295,178.82045 86.402349,177.41851"
+     id="path5443"
+     inkscape:connector-curvature="0" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug05.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,723 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="300"
+   height="250"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug05.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotS"
+       style="overflow:visible">
+      <path
+         id="path4196"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.2,0,0,0.2,1.48,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path3998"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path5316"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5292"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path5289"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5253">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5255" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop5257" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5245"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5247" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5207"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5209" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5253"
+       id="linearGradient5259"
+       x1="384.79102"
+       y1="262.99402"
+       x2="391.83789"
+       y2="262.99402"
+       gradientUnits="userSpaceOnUse" />
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-9"
+       style="overflow:visible">
+      <path
+         id="path5316-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-1"
+       style="overflow:visible">
+      <path
+         id="path5316-9"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-3"
+       style="overflow:visible">
+      <path
+         id="path5316-7-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker4448"
+       style="overflow:visible">
+      <path
+         id="path4450"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-0"
+       style="overflow:visible">
+      <path
+         id="path4193-1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-4"
+       style="overflow:visible">
+      <path
+         id="path4193-5"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.5123284"
+     inkscape:cx="139.72657"
+     inkscape:cy="132.43442"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:window-width="974"
+     inkscape:window-height="1048"
+     inkscape:window-x="73"
+     inkscape:window-y="50"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:snap-global="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid8451"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0.078088198px"
+       originy="-2937.8154px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0.0780882,2135.4532)" />
+  <g
+     id="g3155">
+    <rect
+       y="1.4467304"
+       x="0.49999774"
+       height="18.053268"
+       width="21.481806"
+       id="rect2987"
+       style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217"
+       y="14.841532"
+       x="7.4264469"
+       style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="14.841532"
+         x="7.4264469"
+         id="tspan5219"
+         sodipodi:role="line">6</tspan></text>
+  </g>
+  <g
+     id="g3160">
+    <g
+       transform="matrix(1.0000031,0,0,0.99999992,-8.1553343e-7,-0.44287016)"
+       id="g3102">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4"
+         width="21.481739"
+         height="18.05327"
+         x="60.500004"
+         y="1.8896017" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="67.426575"
+         y="15.284375"
+         id="text5217-8"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="15.284375"
+           x="67.426575"
+           sodipodi:role="line"
+           id="tspan6156">7</tspan></text>
+    </g>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.981805,10.473365 38.518392,1e-6"
+     id="path8263"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0" />
+  <g
+     id="g4516"
+     transform="translate(-0.00911713,4.7593041)">
+    <rect
+       y="136.68742"
+       x="0.50911897"
+       height="18.05327"
+       width="21.481989"
+       id="rect2987-41"
+       style="fill:none;stroke:#000000;stroke-width:1.0000037;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(1.0000037,0.99999628)"
+       sodipodi:linespacing="125%"
+       id="text5217-7"
+       y="150.08279"
+       x="7.3916588"
+       style="font-size:12.00004482px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="150.08279"
+         x="7.3916588"
+         id="tspan5219-3"
+         sodipodi:role="line">6</tspan></text>
+  </g>
+  <g
+     id="g4533"
+     transform="translate(-48.885537,0)">
+    <rect
+       y="218.81546"
+       x="109.38554"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-7"
+       y="232.20978"
+       x="112.22823"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         y="232.20978"
+         x="112.22823"
+         id="tspan3914"
+         sodipodi:role="line">10</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-6);display:inline"
+     d="m 18.241201,159.5 45.999463,59.31546"
+     id="path5012"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4516"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4533"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="122.10091"
+     y="140.49216"
+     id="text4115"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4117"
+       x="122.10091"
+       y="140.49216" /></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+     d="m 71.240899,159.5 -2.6e-5,59.31546"
+     id="path4123"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end="#g4533"
+     inkscape:connection-end-point="d4"
+     inkscape:connection-start="#g4837"
+     inkscape:connection-start-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="145.71631"
+     y="120.74194"
+     id="text4799"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       x="145.71631"
+       y="120.74194"
+       id="tspan4866">obsolete, hidden precursors</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="140.08366"
+     y="221.99774"
+     id="text4807"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4809"
+       x="140.08366"
+       y="221.99774">successor, working dir</tspan></text>
+  <g
+     id="g4748"
+     transform="translate(66,4)">
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-0"
+       y="75.774689"
+       x="46.543758"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         y="75.774689"
+         x="46.543758"
+         id="tspan8594"
+         sodipodi:role="line">hg fold 7</tspan></text>
+    <g
+       transform="translate(1.9995778e-6,1.240701)"
+       id="g6493">
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 36.655934,114.93533 3.649333,6.32067 3.711171,-6.42777"
+         id="path8598"
+         inkscape:connector-curvature="0" />
+      <g
+         id="g6489"
+         transform="translate(0.73014858,0)">
+        <path
+           inkscape:connector-curvature="0"
+           id="path8466-5"
+           d="m 40.606,21.314861 0,98.078949"
+           style="fill:none;stroke:#808080;stroke-width:1.21219063;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+        <path
+           inkscape:connector-curvature="0"
+           id="path8466-5-3"
+           d="m 38.5505,21.370511 0,98.078949"
+           style="fill:none;stroke:#808080;stroke-width:1.10104096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      </g>
+    </g>
+  </g>
+  <g
+     id="g3166">
+    <g
+       id="g3102-9"
+       transform="translate(59.999995,-0.442871)">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4-02"
+         width="21.481739"
+         height="18.05327"
+         x="60.500004"
+         y="1.8896017" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="67.426575"
+         y="15.284375"
+         id="text5217-8-72"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="15.284375"
+           x="67.426575"
+           sodipodi:role="line"
+           id="tspan6156-9">8</tspan></text>
+    </g>
+  </g>
+  <g
+     id="g3172">
+    <g
+       id="g3102-8"
+       transform="translate(120,-0.442871)">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4-026"
+         width="21.481739"
+         height="18.05327"
+         x="60.500004"
+         y="1.8896017" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="67.426575"
+         y="15.284375"
+         id="text5217-8-3"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="15.284375"
+           x="67.426575"
+           sodipodi:role="line"
+           id="tspan6156-0">9</tspan></text>
+    </g>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="m 81.981996,10.473366 38.518004,0"
+     id="path3178"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g3160"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g3166"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2)"
+     d="m 141.98174,10.473366 38.51826,0"
+     id="path3180"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g3166"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g3172"
+     inkscape:connection-end-point="d4" />
+  <g
+     id="g4837">
+    <rect
+       y="141.44673"
+       x="60.5"
+       height="18.053268"
+       width="21.481806"
+       id="rect2987-4-7"
+       style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.9999994, 2.99999821;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217-8-1"
+       y="154.84146"
+       x="67.426483"
+       style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-7"
+         sodipodi:role="line"
+         x="67.426483"
+         y="154.84146">7</tspan></text>
+  </g>
+  <g
+     id="g4842">
+    <rect
+       y="141.44673"
+       x="120.49981"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-02-9"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999791, 2.99999374;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-72-7"
+       y="154.84122"
+       x="127.42651"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-9-5"
+         sodipodi:role="line"
+         x="127.42651"
+         y="154.84122">8</tspan></text>
+  </g>
+  <g
+     id="g4847">
+    <rect
+       y="141.44673"
+       x="180.49982"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-026-9"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999791, 2.99999374;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-3-2"
+       y="154.84122"
+       x="187.42664"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-0-8"
+         sodipodi:role="line"
+         x="187.42664"
+         y="154.84122">9</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+     d="m 81.981806,150.47337 38.518004,0"
+     id="path3178-7"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4837"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4842"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+     d="m 141.98155,150.47337 38.51827,0"
+     id="path3180-3"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4842"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4847"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4448);display:inline"
+     d="M 21.981991,150.47336 60.5,150.47337"
+     id="path4542"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4516"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4837"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+     d="M 124.24048,159.5 78.241066,218.81546"
+     id="path4123-2"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4842"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4533"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+     d="M 180.49982,157.39844 81.981738,220.91702"
+     id="path4123-2-7"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g4847"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g4533"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker4448)"
+     d="m 160.40897,123.42419 c 2.57952,11.70065 19.72743,7.53006 26.27045,14.72737"
+     id="path5710"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker4448)"
+     d="m 152.05019,123.02615 c -18.20742,12.2407 -49.96313,3.854 -68.064354,15.92149"
+     id="path5714"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker4448)"
+     d="m 155.63252,123.42419 c -3.55115,8.6397 -12.38945,8.51306 -17.91167,13.53326"
+     id="path5716"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker4448)"
+     d="m 152.44822,224.92366 c -12.26234,20.49653 -41.95881,1.63236 -63.685938,3.1843"
+     id="path5926"
+     inkscape:connector-curvature="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="219.76105"
+     y="45.381439"
+     id="text4799-8"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4801-4"
+       x="219.76105"
+       y="45.381439">working dir</tspan></text>
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker4448)"
+     d="m 216.5322,43.418725 c -17.12038,-3.247846 -32.15429,-0.004 -25.47437,-18.707746"
+     id="path6377"
+     inkscape:connector-curvature="0" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug06.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="275"
+   height="310"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug06.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotS"
+       style="overflow:visible">
+      <path
+         id="path4196"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.2,0,0,0.2,1.48,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path3998"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path5316"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5292"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path5289"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5253">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5255" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop5257" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5245"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5247" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5207"
+       osb:paint="solid">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5209" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5253"
+       id="linearGradient5259"
+       x1="384.79102"
+       y1="262.99402"
+       x2="391.83789"
+       y2="262.99402"
+       gradientUnits="userSpaceOnUse" />
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-9"
+       style="overflow:visible">
+      <path
+         id="path5316-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-1"
+       style="overflow:visible">
+      <path
+         id="path5316-9"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-3"
+       style="overflow:visible">
+      <path
+         id="path5316-7-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker4448"
+       style="overflow:visible">
+      <path
+         id="path4450"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-0"
+       style="overflow:visible">
+      <path
+         id="path4193-1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-4"
+       style="overflow:visible">
+      <path
+         id="path4193-5"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-37"
+       style="overflow:visible">
+      <path
+         id="path5316-7-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3150"
+       style="overflow:visible">
+      <path
+         id="path3152"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-7"
+       style="overflow:visible">
+      <path
+         id="path5316-7-50"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3230"
+       style="overflow:visible">
+      <path
+         id="path3232"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-8"
+       style="overflow:visible">
+      <path
+         id="path4193-53"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="124.00649"
+     inkscape:cy="153.46969"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:window-width="974"
+     inkscape:window-height="1048"
+     inkscape:window-x="48"
+     inkscape:window-y="61"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:snap-global="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid8451"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0.078088198px"
+       originy="-2937.8154px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <text
+     xml:space="preserve"
+     style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+     x="112.5439"
+     y="113.7746"
+     id="text5217-8-0"
+     sodipodi:linespacing="125%"
+     transform="scale(0.9999979,1.0000021)"><tspan
+       sodipodi:role="line"
+       id="tspan8594"
+       x="112.5439"
+       y="113.7746">hg amend</tspan></text>
+  <g
+     id="g6493"
+     transform="translate(63.844066,39.240701)">
+    <path
+       inkscape:connector-curvature="0"
+       id="path8598"
+       d="m 36.655934,114.93533 3.649333,6.32067 3.711171,-6.42777"
+       style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <g
+       transform="translate(0.73014858,0)"
+       id="g6489">
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1.21219063;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 40.606,21.314861 0,98.078949"
+         id="path8466-5"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:none;stroke:#808080;stroke-width:1.10104096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 38.5505,21.370511 0,98.078949"
+         id="path8466-5-3"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0.0780882,2195.4532)" />
+  <rect
+     style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+     id="rect2987"
+     width="21.481806"
+     height="18.053268"
+     x="0.49999774"
+     y="35.446732" />
+  <text
+     xml:space="preserve"
+     style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="3.3424675"
+     y="48.84153"
+     id="text5217"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan5219"
+       x="3.3424675"
+       y="48.84153"
+       style="stroke:none">10</tspan></text>
+  <rect
+     style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+     id="rect2987-4"
+     width="21.481806"
+     height="18.053268"
+     x="60.500191"
+     y="35.446732" />
+  <text
+     xml:space="preserve"
+     style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="63.497932"
+     y="48.84153"
+     id="text5217-8"
+     sodipodi:linespacing="125%"><tspan
+       y="48.84153"
+       x="63.497932"
+       sodipodi:role="line"
+       id="tspan6156">11</tspan></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:0.99999946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);display:inline"
+     d="m 21.981805,44.473365 38.518386,10e-7"
+     id="path8263"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end="#rect2987-4"
+     inkscape:connection-end-point="d4" />
+  <g
+     id="g3291"
+     transform="translate(0,34)">
+    <rect
+       y="141.44673"
+       x="0.50000185"
+       height="18.05327"
+       width="21.481989"
+       id="rect2987-41"
+       style="fill:none;stroke:#000000;stroke-width:1.0000037;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(1.0000037,0.9999963)"
+       sodipodi:linespacing="125%"
+       id="text5217-7"
+       y="154.84212"
+       x="3.3424876"
+       style="font-size:12.00004482px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         style="stroke:none"
+         y="154.84212"
+         x="3.3424876"
+         id="tspan5219-3"
+         sodipodi:role="line">10</tspan></text>
+  </g>
+  <rect
+     style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+     id="rect2987-4-4"
+     width="21.481739"
+     height="18.05327"
+     x="60.5"
+     y="252.81546" />
+  <text
+     xml:space="preserve"
+     style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="63.342594"
+     y="266.20969"
+     id="text5217-8-7"
+     sodipodi:linespacing="125%"
+     transform="scale(0.9999979,1.0000021)"><tspan
+       sodipodi:role="line"
+       id="tspan3914"
+       x="63.342594"
+       y="266.20969">15</tspan></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-6);display:inline"
+     d="m 18.241201,193.5 45.999463,59.31546"
+     id="path5012"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end="#rect2987-4-4"
+     inkscape:connection-end-point="d4"
+     inkscape:connection-start="#g3291"
+     inkscape:connection-start-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="122.10091"
+     y="174.49216"
+     id="text4115"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4117"
+       x="122.10091"
+       y="174.49216" /></text>
+  <g
+     id="g3118"
+     transform="translate(0,34)">
+    <rect
+       y="1.4467307"
+       x="120.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-02"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-72"
+       y="14.841505"
+       x="123.54487"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-9"
+         sodipodi:role="line"
+         x="123.54487"
+         y="14.841505">12</tspan></text>
+  </g>
+  <g
+     id="g3126"
+     transform="translate(0,34)">
+    <rect
+       y="1.4467307"
+       x="180.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-026"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-3"
+       y="14.841505"
+       x="183.42488"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-0"
+         sodipodi:role="line"
+         x="183.42488"
+         y="14.841505">13</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+     d="m 81.981997,44.473366 38.518003,0"
+     id="path3178"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#rect2987-4"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g3118"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+     d="m 141.98174,44.473366 38.51826,0"
+     id="path3180"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g3118"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g3126"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4448);display:inline"
+     d="M 21.981991,184.65238 60.5,185.29435"
+     id="path4542"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g3291"
+     inkscape:connection-start-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="86.768402"
+     y="12.367264"
+     id="text4799-8"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4801-4"
+       x="86.768402"
+       y="12.367264">working dir</tspan></text>
+  <flowRoot
+     xml:space="preserve"
+     id="flowRoot3104"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     transform="translate(0,34)"><flowRegion
+       id="flowRegion3106"><rect
+         id="rect3108"
+         width="60.309383"
+         height="49.300529"
+         x="-25.368233"
+         y="-22.34952" /></flowRegion><flowPara
+       id="flowPara3110"></flowPara></flowRoot>  <g
+     id="g5560"
+     transform="translate(0,34)">
+    <rect
+       y="141.44673"
+       x="60.5"
+       height="18.053268"
+       width="21.481806"
+       id="rect2987-4-8"
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217-8-4"
+       y="154.84152"
+       x="63.497734"
+       style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-4"
+         sodipodi:role="line"
+         x="63.497734"
+         y="154.84152">11</tspan></text>
+  </g>
+  <g
+     transform="translate(-2.0371355e-4,174)"
+     id="g3118-0">
+    <rect
+       y="1.4467307"
+       x="120.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-02-4"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-72-7"
+       y="14.841505"
+       x="123.54487"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-9-7"
+         sodipodi:role="line"
+         x="123.54487"
+         y="14.841505">12</tspan></text>
+  </g>
+  <g
+     transform="translate(-2.0371355e-4,174)"
+     id="g3126-3">
+    <rect
+       y="1.4467307"
+       x="180.5"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-026-8"
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-3-9"
+       y="14.841505"
+       x="183.42488"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-0-0"
+         sodipodi:role="line"
+         x="183.42488"
+         y="14.841505">13</tspan></text>
+  </g>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+     d="m 81.981806,184.47337 38.517994,0"
+     id="path3178-0"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end="#g3118-0"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+     d="m 141.98154,184.47337 38.51826,0"
+     id="path3180-2"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g3118-0"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g3126-3"
+     inkscape:connection-end-point="d4" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+     d="m 71.240899,193.5 -2.6e-5,59.31546"
+     id="path4123"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-end="#rect2987-4-4"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="18.790892"
+     y="142.23888"
+     id="text4799-8-6"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan4801-4-0"
+       x="18.790892"
+       y="142.23888">obsolete</tspan><tspan
+       sodipodi:role="line"
+       x="18.790892"
+       y="152.23888"
+       id="tspan4452">but visible</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="150.66776"
+     y="148.39902"
+     id="text4454"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4456"
+       x="150.66776"
+       y="148.39902">unstable</tspan></text>
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker3230);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 41.433633,155.93241 c 4.445697,11.92656 24.017716,1.13391 25.948336,14.64825"
+     id="path4880"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker3230);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 171.59383,151.74719 c -5.21207,17.59198 -29.77875,-3.6088 -34.31876,17.57791"
+     id="path5100"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker3230);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 174.94201,152.58423 c 1.6786,11.87585 15.90381,0.83843 15.90381,15.90382"
+     id="path5104"
+     inkscape:connector-curvature="0" />
+  <g
+     id="g5631"
+     transform="translate(-27.905601,-5.4032307)">
+    <rect
+       y="211.84996"
+       x="118.4056"
+       height="18.05327"
+       width="21.481739"
+       id="rect2987-4-0-0"
+       style="fill:none;stroke:#404040;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0" />
+    <text
+       inkscape:transform-center-x="2.6044813"
+       transform="scale(0.9999979,1.0000021)"
+       sodipodi:linespacing="125%"
+       id="text5217-8-9-2"
+       y="225.24431"
+       x="121.1868"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-7-4"
+         sodipodi:role="line"
+         x="121.1868"
+         y="225.24431">14</tspan></text>
+  </g>
+  <text
+     xml:space="preserve"
+     style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+     x="108.67482"
+     y="206.41029"
+     id="text4119"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4121"
+       x="108.67482"
+       y="206.41029"
+       style="font-size:8px;font-weight:bold;-inkscape-font-specification:Sans Bold">T</tspan></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker3230)"
+     d="m 79.976346,193.5 12.52908,12.94673"
+     id="path5636"
+     inkscape:connector-type="polyline"
+     inkscape:connector-curvature="0"
+     inkscape:connection-start="#g5560"
+     inkscape:connection-start-point="d4"
+     inkscape:connection-end="#g5631"
+     inkscape:connection-end-point="d4" />
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="143.52129"
+     y="224.8358"
+     id="text4787"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       x="143.52129"
+       y="224.8358"
+       id="tspan4791">temporary</tspan><tspan
+       sodipodi:role="line"
+       x="143.52129"
+       y="234.8358"
+       id="tspan4795">amend</tspan><tspan
+       sodipodi:role="line"
+       x="143.52129"
+       y="244.8358"
+       id="tspan4797">commit;</tspan><tspan
+       sodipodi:role="line"
+       x="143.52129"
+       y="254.8358"
+       id="tspan6283">obsolete and</tspan><tspan
+       sodipodi:role="line"
+       x="143.52129"
+       y="264.83582"
+       id="tspan6285">hidden</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+     x="95.495201"
+     y="291.81802"
+     id="text4799-8-7"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan4801-4-8"
+       x="95.495201"
+       y="291.81802">working dir</tspan></text>
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker3230);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="M 114.6749,14.053603 C 108.77815,29.370318 80.769041,12.646358 73.241271,33.724116"
+     id="path6974"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker3230)"
+     d="m 92.984542,288.7868 c -17.463809,1.31107 -20.109707,1.30681 -21.213204,-14.14214"
+     id="path7860"
+     inkscape:connector-curvature="0" />
+  <path
+     style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#marker3230)"
+     d="m 139.5,223.5 c -16.33548,3.61997 -8.82833,-10 -24.5,-10"
+     id="path8482"
+     inkscape:connector-curvature="0" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug07.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,608 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="310"
+   height="220"
+   id="svg8082"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug07.svg">
+  <defs
+     id="defs8084">
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mend"
+       style="overflow:visible">
+      <path
+         id="path4117"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(-0.4,0,0,-0.4,-4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3230"
+       style="overflow:visible">
+      <path
+         id="path3232"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8231"
+       style="overflow:visible">
+      <path
+         id="path8233"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8239"
+       style="overflow:visible">
+      <path
+         id="path8241"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker4448"
+       style="overflow:visible">
+      <path
+         id="path4450"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-6"
+       style="overflow:visible">
+      <path
+         id="path5316-5"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker4448-9"
+       style="overflow:visible">
+      <path
+         id="path4450-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker4448-8"
+       style="overflow:visible">
+      <path
+         id="path4450-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-6"
+       style="overflow:visible">
+      <path
+         id="path4193-5"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-7"
+       style="overflow:visible">
+      <path
+         id="path4193-7"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="126.91408"
+     inkscape:cy="102.44906"
+     inkscape:current-layer="layer1"
+     inkscape:document-units="px"
+     showgrid="false"
+     inkscape:window-width="887"
+     inkscape:window-height="875"
+     inkscape:window-x="342"
+     inkscape:window-y="160"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata8087">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     transform="translate(0,18.65699)">
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="113.19138"
+       y="21.624107"
+       id="text5217-8-0"
+       sodipodi:linespacing="125%"
+       transform="scale(0.9999979,1.0000021)"><tspan
+         sodipodi:role="line"
+         id="tspan8594"
+         x="113.19138"
+         y="21.624107">hg evolve --all</tspan></text>
+    <g
+       id="g6372"
+       transform="translate(63.844068,-32.28608)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path8598"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      <g
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)"
+         id="g3821">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 35.5,23.60911 35.5,59.5"
+           id="path8466-5"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 33.5,23.60911 33.5,59.5"
+           id="path8466-4-7"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+    <g
+       id="g3291"
+       transform="translate(0,-82.02573)">
+      <rect
+         y="141.44673"
+         x="0.50000185"
+         height="18.05327"
+         width="21.481989"
+         id="rect2987-41"
+         style="fill:none;stroke:#000000;stroke-width:1.0000037;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(1.0000037,0.9999963)"
+         sodipodi:linespacing="125%"
+         id="text5217-7"
+         y="154.84212"
+         x="3.3424876"
+         style="font-size:12.00004482px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           style="stroke:none"
+           y="154.84212"
+           x="3.3424876"
+           id="tspan5219-3"
+           sodipodi:role="line">10</tspan></text>
+    </g>
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect2987-4-4"
+       width="21.481739"
+       height="18.05327"
+       x="60.5"
+       y="136.78973" />
+    <text
+       xml:space="preserve"
+       style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="63.342571"
+       y="150.18422"
+       id="text5217-8-7"
+       sodipodi:linespacing="125%"
+       transform="scale(0.9999979,1.0000021)"><tspan
+         sodipodi:role="line"
+         id="tspan3914"
+         x="63.342571"
+         y="150.18422">15</tspan></text>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-6);display:inline"
+       d="M 18.241201,77.474272 64.240665,136.78973"
+       id="path5012"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#rect2987-4-4"
+       inkscape:connection-end-point="d4"
+       inkscape:connection-start="#g3291"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4448);display:inline"
+       d="M 21.981991,68.626653 60.499999,69.26862"
+       id="path4542"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3291"
+       inkscape:connection-start-point="d4" />
+    <g
+       id="g5560"
+       transform="translate(0,-82.02573)">
+      <rect
+         y="141.44673"
+         x="60.5"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-8"
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-4"
+         y="154.84152"
+         x="63.497734"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-4"
+           sodipodi:role="line"
+           x="63.497734"
+           y="154.84152">11</tspan></text>
+    </g>
+    <g
+       id="g8702"
+       transform="translate(0,-16)">
+      <rect
+         y="75.421013"
+         x="120.49979"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02-4"
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-7"
+         y="88.815628"
+         x="123.54466"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-7"
+           sodipodi:role="line"
+           x="123.54466"
+           y="88.815628">12</tspan></text>
+    </g>
+    <g
+       id="g8707"
+       transform="translate(0,-16)">
+      <rect
+         y="75.421013"
+         x="180.4998"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026-8"
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-9"
+         y="88.815628"
+         x="183.42468"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-0"
+           sodipodi:role="line"
+           x="183.42468"
+           y="88.815628">13</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981809,68.44765 38.517981,-2e-6"
+       id="path3178-0"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g8702"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 141.98153,68.447648 38.51827,0"
+       id="path3180-2"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8702"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g8707"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 71.240899,77.47427 -2.6e-5,59.31546"
+       id="path4123"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#rect2987-4-4"
+       inkscape:connection-end-point="d4" />
+    <g
+       id="g5631"
+       transform="translate(-27.905602,-122.06022)">
+      <rect
+         y="211.84996"
+         x="118.4056"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-0-0"
+         style="fill:none;stroke:#404040;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0" />
+      <text
+         inkscape:transform-center-x="2.6044813"
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-9-2"
+         y="225.24431"
+         x="121.1868"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-7-4"
+           sodipodi:role="line"
+           x="121.1868"
+           y="225.24431">14</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="108.67482"
+       y="89.753288"
+       id="text4119"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4121"
+         x="108.67482"
+         y="89.753288"
+         style="font-size:8px;font-weight:bold;-inkscape-font-specification:Sans Bold">T</tspan></text>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker3230)"
+       d="M 80.157925,77.47427 92.323846,89.78974"
+       id="path5636"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g5560"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g5631"
+       inkscape:connection-end-point="d4" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot8394"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       transform="translate(0,-36)"><flowRegion
+         id="flowRegion8396"><rect
+           id="rect8398"
+           width="311.2373"
+           height="172.50397"
+           x="13.690791"
+           y="268.24911" /></flowRegion><flowPara
+         id="flowPara8400" /></flowRoot>    <g
+       id="g8798"
+       transform="translate(28.427001,-38.337945)">
+      <rect
+         y="175.12769"
+         x="92.072998"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-4-9"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-7-4"
+         y="188.52202"
+         x="94.915642"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           y="188.52202"
+           x="94.915642"
+           id="tspan3914-6"
+           sodipodi:role="line">16</tspan></text>
+    </g>
+    <g
+       id="g8803"
+       transform="translate(8.4270009,-38.337945)">
+      <rect
+         y="175.12769"
+         x="172.073"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-4-4"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-7-46"
+         y="188.52202"
+         x="174.91582"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           y="188.52202"
+           x="174.91582"
+           id="tspan3914-1"
+           sodipodi:role="line">17</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4448);display:inline"
+       d="m 81.981739,145.81637 38.518261,0"
+       id="path4542-5"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#rect2987-4-4"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g8798"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4448);display:inline"
+       d="M 141.98174,145.77795 180.5,145.64016"
+       id="path4542-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8798"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 131.24068,77.474283 1.6e-4,59.315457"
+       id="path4123-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8702"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g8798"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 191.24069,77.474283 1.6e-4,59.315457"
+       id="path4123-14"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8707"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g8803"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="226.23938"
+       y="81.810745"
+       id="text3058"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3060"
+         x="226.23938"
+         y="81.810745">obsolete, hidden</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="243.1927"
+       y="151.52931"
+       id="text6402"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan6404"
+         x="243.1927"
+         y="151.52931">working dir</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="102"
+       y="184.34302"
+       id="text7020"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan7022"
+         x="102"
+         y="184.34302">successors</tspan></text>
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 214.5,51.843009 c 2.26039,0.588947 4.4416,0.9416 5.5,2 2.95364,2.953636 2.98797,53.512031 0.5,56.000001 -3.15839,3.15839 -5.49327,6.33109 -9,7.5"
+       id="path7862"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker4448-8);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 240,149.34301 c -2.15495,-0.66255 -7.61688,0.38312 -9,-1 -11.39271,-11.39271 -10.31018,-6 -25.5,-6"
+       id="path7864"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 51.5,159.34301 c -0.275757,4.62088 1.079227,8.02641 5.5,9.5 11.41327,3.80442 21.457711,-0.70846 32.500001,1.5 27.298709,5.45974 71.848979,-2 99.499999,-2 8.52242,0 22,4.51185 22,-8.5"
+       id="path8084"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug08.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,415 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="250"
+   height="190"
+   id="svg8392"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug08.svg">
+  <defs
+     id="defs8394">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3230"
+       style="overflow:visible">
+      <path
+         id="path3232"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8414"
+       style="overflow:visible">
+      <path
+         id="path8416"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-7"
+       style="overflow:visible">
+      <path
+         id="path5316-7-1"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8695"
+       style="overflow:visible">
+      <path
+         id="path8697"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8695-6"
+       style="overflow:visible">
+      <path
+         id="path8697-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="95.232262"
+     inkscape:cy="117.91553"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="824"
+     inkscape:window-height="830"
+     inkscape:window-x="647"
+     inkscape:window-y="278"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata8397">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-769.99805)">
+    <g
+       id="g8678"
+       transform="translate(0,-6)">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">18</tspan></text>
+    </g>
+    <g
+       id="g3118"
+       transform="translate(-60.000001,786.36218)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">19</tspan></text>
+    </g>
+    <g
+       id="g3126"
+       transform="translate(-60.000192,786.36218)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">20</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981806,796.83549 38.518193,4e-5"
+       id="path3178"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g3118"
+       inkscape:connection-end-point="d4"
+       inkscape:connection-start="#g8678"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981738,796.83555 38.518072,0"
+       id="path3180"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3118"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3126"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="192.95625"
+       y="783.27075"
+       id="text4799-8"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4801-4"
+         x="192.95625"
+         y="783.27075">working dir</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="80.662636"
+       y="851.4538"
+       id="text5217-8-0"
+       sodipodi:linespacing="125%"
+       transform="scale(0.9999979,1.0000021)"><tspan
+         sodipodi:role="line"
+         id="tspan8594"
+         x="80.662636"
+         y="851.4538">hg prune 19</tspan></text>
+    <g
+       id="g6372"
+       transform="translate(31.315375,797.54535)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path8598"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      <g
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)"
+         id="g3821">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 35.5,23.60911 35.5,59.5"
+           id="path8466-5"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 33.5,23.60911 33.5,59.5"
+           id="path8466-4-7"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+    <g
+       transform="matrix(1.0000032,0,0,0.99999991,-8.2080488e-7,99.00007)"
+       id="g8678-6">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-9"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-32"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-8"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">18</tspan></text>
+    </g>
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999946, 3.99999785;stroke-dashoffset:0"
+       id="rect2987-4-02-6"
+       width="21.481808"
+       height="18.053268"
+       x="60.5"
+       y="892.8089" />
+    <text
+       xml:space="preserve"
+       style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="63.544647"
+       y="906.20331"
+       id="text5217-8-72-1"
+       sodipodi:linespacing="125%"><tspan
+         y="906.20331"
+         x="63.544647"
+         sodipodi:role="line"
+         id="tspan6156-9-8">19</tspan></text>
+    <g
+       id="g3126-8"
+       transform="matrix(1.0000032,0,0,0.99999991,-60.000385,891.36218)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026-7"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-8"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-9"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">20</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,901.83548 38.518126,5e-5"
+       id="path3178-9"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981808,901.83554 38.518382,0"
+       id="path3180-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g3126-8"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="33.872818"
+       y="941.35645"
+       id="text9295"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan9297"
+         x="33.872818"
+         y="941.35645">obsolete</tspan><tspan
+         sodipodi:role="line"
+         x="33.872818"
+         y="953.85645"
+         id="tspan9299">but visible</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="125.75282"
+       y="939.66284"
+       id="text9301"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan9303"
+         x="125.75282"
+         y="939.66284">unstable</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="192.95625"
+       y="920.7381"
+       id="text4799-8-4"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4801-4-2"
+         x="192.95625"
+         y="920.7381">working dir</tspan></text>
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker8695);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 188.0904,779.78292 c -26.25288,3.51598 -8.22083,22.5684 -39.59798,18.38478"
+       id="path9349"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker8695);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 189.55807,918.25683 c -26.25288,-3.51598 -8.22083,-22.5684 -39.59798,-18.38478"
+       id="path9349-7"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker8695-6);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 57.275649,931.10377 c 1.651424,-10.44392 15.963695,-1.81375 16.970563,-15.9099"
+       id="path9569"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker8695-6);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 147.43176,929.68956 c -3.24422,-11.34319 -17.24529,-1.56955 -19.09188,-14.49569"
+       id="path9957"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug09.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="250"
+   height="150"
+   id="svg10360"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug09.svg">
+  <defs
+     id="defs10362">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker10584"
+       style="overflow:visible">
+      <path
+         id="path10586"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.180467"
+     inkscape:cx="119.78971"
+     inkscape:cy="57.203827"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="866"
+     inkscape:window-height="800"
+     inkscape:window-x="548"
+     inkscape:window-y="176"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata10365">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-52.986766,123.22995)">
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="132.17838"
+       y="-88.939552"
+       id="text5217-8-0"
+       sodipodi:linespacing="125%"
+       transform="scale(0.9999979,1.0000021)"><tspan
+         sodipodi:role="line"
+         id="tspan8594"
+         x="132.17838"
+         y="-88.939552">hg evolve --all</tspan></text>
+    <g
+       id="g6372"
+       transform="translate(82.830913,-142.84994)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path8598"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      <g
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)"
+         id="g3821">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 35.5,23.60911 35.5,59.5"
+           id="path8466-5"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 33.5,23.60911 33.5,59.5"
+           id="path8466-4-7"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+    <g
+       transform="matrix(1.0000032,0,0,0.99999991,52.986844,-844.35614)"
+       id="g8678-6">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-9"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-32"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-8"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">18</tspan></text>
+    </g>
+    <g
+       id="g11168"
+       transform="translate(0,112)">
+      <rect
+         y="-162.54732"
+         x="113.48685"
+         height="18.053268"
+         width="21.481808"
+         id="rect2987-4-02-6"
+         style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999946, 3.99999783;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-1"
+         y="-149.15291"
+         x="116.53148"
+         style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-8"
+           sodipodi:role="line"
+           x="116.53148"
+           y="-149.15291">19</tspan></text>
+    </g>
+    <g
+       id="g11163"
+       transform="translate(0,112)">
+      <rect
+         y="-162.5473"
+         x="173.48705"
+         height="18.053268"
+         width="21.481808"
+         id="rect2987-4-026-7"
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-8"
+         y="-149.15244"
+         x="176.41162"
+         style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-9"
+           sodipodi:role="line"
+           x="176.41162"
+           y="-149.15244">20</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 74.96872,-41.52073 38.51813,3.7e-5"
+       id="path3178-9"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g11168"
+       inkscape:connection-end-point="d4"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 134.96865,-41.520681 38.5184,1e-5"
+       id="path3180-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g11168"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g11163"
+       inkscape:connection-end-point="d4" />
+    <g
+       transform="matrix(1.0000032,0,0,0.99999991,172.98684,-795.29459)"
+       id="g8678-6-4">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-9-5"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-32-6"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-8-9"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">21</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10584)"
+       d="M 74.96872,-37.129348 173.48684,3.1494178"
+       id="path11202"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g8678-6-4"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 184.22792,-32.494034 -1.1e-4,31.0082104"
+       id="path4123-2"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g11163"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g8678-6-4"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="188.27898"
+       y="-68.730186"
+       id="text11674"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan11676"
+         x="188.27898"
+         y="-68.730186">obsolete, hidden</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="229.09592"
+       y="4.1899796"
+       id="text11678"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan11680"
+         x="229.09592"
+         y="4.1899796">successor,</tspan><tspan
+         sodipodi:role="line"
+         x="229.09592"
+         y="16.68998"
+         id="tspan11682">working dir</tspan></text>
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker10584);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 224.96835,6.48307 c -14.81489,-0.42162 -8.84647,9.26545 -25.22395,4.58617"
+       id="path11688"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker10584);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 230.01314,-64.60262 c -9.90102,12.73442 -31.46298,0.0328 -40.81693,11.46543"
+       id="path12074"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker10584);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 225.88558,-65.97848 c -32.80764,7.84904 -73.26593,-8.64954 -95.3924,11.46544"
+       id="path12076"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug10.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,872 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="300"
+   height="400"
+   id="svg8392"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug10.svg">
+  <defs
+     id="defs8394">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3230"
+       style="overflow:visible">
+      <path
+         id="path3232"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8414"
+       style="overflow:visible">
+      <path
+         id="path8416"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-7"
+       style="overflow:visible">
+      <path
+         id="path5316-7-1"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8695"
+       style="overflow:visible">
+      <path
+         id="path8697"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8695-6"
+       style="overflow:visible">
+      <path
+         id="path8697-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-5"
+       style="overflow:visible">
+      <path
+         id="path5316-7-0"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-2"
+       style="overflow:visible">
+      <path
+         id="path4193-0"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-1"
+       style="overflow:visible">
+      <path
+         id="path5316-7-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3338"
+       style="overflow:visible">
+      <path
+         id="path3340"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3342"
+       style="overflow:visible">
+      <path
+         id="path3344"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-3"
+       style="overflow:visible">
+      <path
+         id="path4193-8"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-0"
+       style="overflow:visible">
+      <path
+         id="path5316-7-14"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.2724663"
+     inkscape:cx="124.3132"
+     inkscape:cy="243.92715"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="923"
+     inkscape:window-height="1064"
+     inkscape:window-x="106"
+     inkscape:window-y="54"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata8397">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-559.99805)">
+    <g
+       id="g8678"
+       transform="translate(0,-214)">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">21</tspan></text>
+    </g>
+    <g
+       id="g3118"
+       transform="translate(-60.000001,578.36218)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">22</tspan></text>
+    </g>
+    <g
+       id="g3126"
+       transform="translate(-60.000192,578.36218)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">23</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981806,588.83549 38.518193,4e-5"
+       id="path3178"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g3118"
+       inkscape:connection-end-point="d4"
+       inkscape:connection-start="#g8678"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981738,588.83555 38.518072,0"
+       id="path3180"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3118"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3126"
+       inkscape:connection-end-point="d4" />
+    <g
+       transform="matrix(1.0000032,0,0,0.99999991,-8.2080488e-7,-108.99993)"
+       id="g8678-6">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-9"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-32"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-8"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">21</tspan></text>
+    </g>
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999946, 3.99999785;stroke-dashoffset:0"
+       id="rect2987-4-02-6"
+       width="21.481808"
+       height="18.053268"
+       x="60.5"
+       y="684.8089" />
+    <text
+       xml:space="preserve"
+       style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="63.544647"
+       y="698.20331"
+       id="text5217-8-72-1"
+       sodipodi:linespacing="125%"><tspan
+         y="698.20331"
+         x="63.544647"
+         sodipodi:role="line"
+         id="tspan6156-9-8">22</tspan></text>
+    <g
+       id="g3126-8"
+       transform="matrix(1.0000032,0,0,0.99999991,-60.000385,683.36218)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026-7"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-8"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-9"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">23</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,693.83548 38.518126,5e-5"
+       id="path3178-9"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981808,693.83554 38.518382,0"
+       id="path3180-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g3126-8"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="7.5114212"
+       y="652.66315"
+       id="text9295"
+       sodipodi:linespacing="100%"><tspan
+         sodipodi:role="line"
+         id="tspan9297"
+         x="7.5114212"
+         y="652.66315">obsolete</tspan><tspan
+         sodipodi:role="line"
+         x="7.5114212"
+         y="662.66315"
+         id="tspan9299">but visible</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="155.24913"
+       y="668.43335"
+       id="text9301"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan9303"
+         x="155.24913"
+         y="668.43335">unstable</tspan></text>
+    <g
+       id="g5433"
+       transform="translate(32.476727,584.47248)">
+      <text
+         transform="scale(0.9999978,1.0000022)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-0"
+         y="58.841717"
+         x="46.92271"
+         style="font-size:11.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+         xml:space="preserve"><tspan
+           y="58.841717"
+           x="46.92271"
+           id="tspan8594"
+           sodipodi:role="line">hg uncommit <tspan
+   id="tspan3131"
+   style="font-style:italic">f1 f2 ...</tspan></tspan></text>
+      <g
+         transform="translate(-0.59241834,4.9316169)"
+         id="g6372-4">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+           id="path8598-5"
+           inkscape:connector-curvature="0" />
+        <g
+           id="g3821-3"
+           transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)">
+          <path
+             inkscape:connector-curvature="0"
+             id="path8466-5-0"
+             d="M 35.5,23.60911 35.5,59.5"
+             style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+          <path
+             inkscape:connector-curvature="0"
+             id="path8466-4-7-7"
+             d="M 33.5,23.60911 33.5,59.5"
+             style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+        </g>
+      </g>
+    </g>
+    <g
+       id="g3118-2"
+       transform="translate(-60.000001,733.29305)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02-8"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-3"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-3"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">24</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="187.68906"
+       y="740.26349"
+       id="text3218"
+       sodipodi:linespacing="100%"><tspan
+         sodipodi:role="line"
+         id="tspan3220"
+         x="187.68906"
+         y="740.26349">working dir</tspan><tspan
+         sodipodi:role="line"
+         x="187.68906"
+         y="750.26349"
+         id="tspan4379">(with uncommitted</tspan><tspan
+         sodipodi:role="line"
+         x="187.68906"
+         y="760.26349"
+         id="tspan4381">changes to f1 f2 ...)</tspan></text>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,702.7739 38.518124,32.05414"
+       id="path3178-9-5"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 71.240897,702.86217 -2.2e-5,31.87761"
+       id="path4123"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#rect2987-4-02-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:11.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="79.694885"
+       y="791.03015"
+       id="text5217-8-0-7"
+       sodipodi:linespacing="125%"
+       transform="scale(0.9999978,1.0000022)"><tspan
+         id="tspan3316"
+         sodipodi:role="line"
+         x="79.694885"
+         y="791.03015">hg revert <tspan
+   id="tspan3314"
+   style="font-style:italic">f1 f2 ...</tspan></tspan><tspan
+         id="tspan3322"
+         sodipodi:role="line"
+         x="79.694885"
+         y="806.03015">hg evolve --all</tspan></text>
+    <g
+       id="g6372-4-2"
+       transform="translate(32.179684,745.12164)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path8598-5-0"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      <g
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)"
+         id="g3821-3-9">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 35.5,23.60911 35.5,59.5"
+           id="path8466-5-0-9"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 33.5,23.60911 33.5,59.5"
+           id="path8466-4-7-7-4"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+    <g
+       id="g8678-6-1"
+       transform="matrix(1.0000032,0,0,0.99999991,-1e-6,45.40223)">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4-9-7"
+         width="21.481806"
+         height="18.053268"
+         x="0.4999997"
+         y="793.80884" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="3.4977415"
+         y="807.20361"
+         id="text5217-8-32-6"
+         sodipodi:linespacing="125%"><tspan
+           y="807.20361"
+           x="3.4977415"
+           sodipodi:role="line"
+           id="tspan6156-8-5">21</tspan></text>
+    </g>
+    <rect
+       y="839.21106"
+       x="60.5"
+       height="18.053268"
+       width="21.481808"
+       id="rect2987-4-02-6-9"
+       style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999946, 3.99999785;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text5217-8-72-1-2"
+       y="852.60547"
+       x="63.544647"
+       style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       xml:space="preserve"><tspan
+         id="tspan6156-9-8-1"
+         sodipodi:role="line"
+         x="63.544647"
+         y="852.60547">22</tspan></text>
+    <g
+       id="g4295">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0"
+         id="rect2987-4-026-7-9"
+         width="21.481808"
+         height="18.053268"
+         x="120.50019"
+         y="839.21106" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="123.42475"
+         y="852.60547"
+         id="text5217-8-3-8-6"
+         sodipodi:linespacing="125%"><tspan
+           y="852.60547"
+           x="123.42475"
+           sodipodi:role="line"
+           id="tspan6156-0-9-3">23</tspan></text>
+    </g>
+    <path
+       inkscape:connection-start-point="d4"
+       inkscape:connection-start="#g8678-6-1"
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path3178-9-1"
+       d="m 21.981875,848.23763 38.518124,2e-5"
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline" />
+    <path
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path3180-1-7"
+       d="m 81.981809,848.23766 38.518381,3e-5"
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       inkscape:connection-end="#g4295"
+       inkscape:connection-end-point="d4" />
+    <g
+       transform="translate(-60.000001,887.69517)"
+       id="g3118-2-6">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4-02-8-4"
+         width="21.481739"
+         height="18.05327"
+         x="120.5"
+         y="1.4467307" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="123.54487"
+         y="14.841505"
+         id="text5217-8-72-3-4"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="14.841505"
+           x="123.54487"
+           sodipodi:role="line"
+           id="tspan6156-9-3-9">24</tspan></text>
+    </g>
+    <path
+       inkscape:connection-end-point="d4"
+       inkscape:connection-end="#g3118-2-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-start="#g8678-6-1"
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path3178-9-5-1"
+       d="m 21.981875,857.17605 38.518124,32.05412"
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline" />
+    <path
+       inkscape:connection-end-point="d4"
+       inkscape:connection-end="#g3118-2-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-start="#rect2987-4-02-6-9"
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path4123-8"
+       d="m 71.240897,857.26433 -2.2e-5,31.87757"
+       style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM);display:inline" />
+    <g
+       transform="translate(-1.0430814e-6,887.87361)"
+       id="g3118-2-6-6">
+      <rect
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+         id="rect2987-4-02-8-4-3"
+         width="21.481739"
+         height="18.05327"
+         x="120.5"
+         y="1.4467307" />
+      <text
+         xml:space="preserve"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         x="123.54487"
+         y="14.841505"
+         id="text5217-8-72-3-4-9"
+         sodipodi:linespacing="125%"
+         transform="scale(0.9999979,1.0000021)"><tspan
+           y="14.841505"
+           x="123.54487"
+           sodipodi:role="line"
+           id="tspan6156-9-3-9-1">25</tspan></text>
+    </g>
+    <path
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path4123-8-2"
+       d="m 131.24105,857.26433 -1.4e-4,32.05601"
+       style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       inkscape:connection-start="#g4295"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2-6-6"
+       inkscape:connection-end-point="d4" />
+    <path
+       inkscape:connector-curvature="0"
+       inkscape:connector-type="polyline"
+       id="path3178-9-1-1"
+       d="M 81.981738,898.20048 120.5,898.31503"
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       inkscape:connection-start="#g3118-2-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2-6-6"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="187.37656"
+       y="909.57391"
+       id="text4799-8-0"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="909.57391"
+         id="tspan4416">working dir</tspan><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="922.07391"
+         id="tspan4420">(clean)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="175.91385"
+       y="840.83063"
+       id="text4404"
+       sodipodi:linespacing="100%"><tspan
+         sodipodi:role="line"
+         id="tspan4406"
+         x="175.91385"
+         y="840.83063">obsolete,</tspan><tspan
+         sodipodi:role="line"
+         x="175.91385"
+         y="850.83063"
+         id="tspan4408">hidden,</tspan><tspan
+         sodipodi:role="line"
+         x="175.91385"
+         y="860.83063"
+         id="tspan4410">precursors</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="53.690826"
+       y="380.35703"
+       id="text4412"
+       sodipodi:linespacing="100%"
+       transform="translate(0,559.99805)"><tspan
+         sodipodi:role="line"
+         id="tspan4414"
+         x="53.690826"
+         y="380.35703">successors</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="187.37656"
+       y="571.41107"
+       id="text4799-8-0-8"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="571.41107"
+         id="tspan4416-9">working dir</tspan><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="583.91107"
+         id="tspan4420-1">(clean)</tspan></text>
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="M 182.62097,9.6751729 C 149.31312,5.6732792 109.12827,-5.7223311 84.489703,18.916234"
+       id="path4446"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 182.62097,177.33443 c -11.66919,2.11797 -39.69025,-8.27526 -48.84561,0.8801 -4.08681,4.08681 5.91098,7.3857 -1.32015,11.00126 -8.45778,4.22889 -37.224994,-3.5204 -45.765254,-3.5204"
+       id="path4452"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 173.37991,274.14555 c -26.50591,-25.47484 -62.13868,-7.60786 -86.249903,3.5204"
+       id="path4458"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 172.05976,275.4657 c -15.34118,-5.10156 -27.83143,-16.04735 -35.64409,0.8801"
+       id="path4466"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 184.38118,349.39419 c -17.09613,-2.47468 -18.70357,-14.67863 -38.2844,-11.88137"
+       id="path4468"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 90.21036,370.95666 c 5.346579,-17.09267 25.584,-5.21534 35.20404,-18.04207"
+       id="path4690"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="M 87.570057,370.95666 C 90.583364,353.5751 71.256395,368.31133 69.968036,350.27429"
+       id="path4694"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 29.043336,106.04624 c 9.697316,11.54911 30.278008,-0.41536 36.084144,15.84182"
+       id="path4908"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0)"
+       d="m 152.25749,104.72609 c -14.85295,-1.56817 -17.66404,5.2687 -18.48213,16.72192"
+       id="path5120"
+       inkscape:connector-curvature="0"
+       transform="translate(0,559.99805)" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug11.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="250"
+   height="260"
+   id="svg8392"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug11.svg">
+  <defs
+     id="defs8394">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3230"
+       style="overflow:visible">
+      <path
+         id="path3232"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8414"
+       style="overflow:visible">
+      <path
+         id="path8416"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-7"
+       style="overflow:visible">
+      <path
+         id="path5316-7-1"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8695"
+       style="overflow:visible">
+      <path
+         id="path8697"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8695-6"
+       style="overflow:visible">
+      <path
+         id="path8697-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-5"
+       style="overflow:visible">
+      <path
+         id="path5316-7-0"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-2"
+       style="overflow:visible">
+      <path
+         id="path4193-0"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-1"
+       style="overflow:visible">
+      <path
+         id="path5316-7-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3338"
+       style="overflow:visible">
+      <path
+         id="path3340"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3342"
+       style="overflow:visible">
+      <path
+         id="path3344"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-3"
+       style="overflow:visible">
+      <path
+         id="path4193-8"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-0"
+       style="overflow:visible">
+      <path
+         id="path5316-7-14"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-8"
+       style="overflow:visible">
+      <path
+         id="path5316-7-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-0-3"
+       style="overflow:visible">
+      <path
+         id="path5316-7-14-4"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-0-5"
+       style="overflow:visible">
+      <path
+         id="path5316-7-14-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="131.9535"
+     inkscape:cy="63.06899"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="923"
+     inkscape:window-height="1064"
+     inkscape:window-x="75"
+     inkscape:window-y="87"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata8397">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-551.69805)">
+    <g
+       id="g8678"
+       transform="translate(0,-222)">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">25</tspan></text>
+    </g>
+    <g
+       id="g3118"
+       transform="translate(-60.000001,570.36218)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">26</tspan></text>
+    </g>
+    <g
+       id="g3126"
+       transform="translate(-60.000192,570.36218)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">27</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981806,580.83549 38.518193,4e-5"
+       id="path3178"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g3118"
+       inkscape:connection-end-point="d4"
+       inkscape:connection-start="#g8678"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981738,580.83555 38.518072,0"
+       id="path3180"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3118"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3126"
+       inkscape:connection-end-point="d4" />
+    <g
+       transform="matrix(1.0000032,0,0,0.99999991,-8.2080488e-7,-108.66406)"
+       id="g8678-6">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-9"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-32"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-8"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">25</tspan></text>
+    </g>
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999946, 3.99999785;stroke-dashoffset:0"
+       id="rect2987-4-02-6"
+       width="21.481808"
+       height="18.053268"
+       x="60.5"
+       y="685.14484" />
+    <text
+       xml:space="preserve"
+       style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="63.544647"
+       y="698.53925"
+       id="text5217-8-72-1"
+       sodipodi:linespacing="125%"><tspan
+         y="698.53925"
+         x="63.544647"
+         sodipodi:role="line"
+         id="tspan6156-9-8">26</tspan></text>
+    <g
+       id="g3126-8"
+       transform="matrix(1.0000032,0,0,0.99999991,-60.000385,683.69805)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026-7"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-8"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-9"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">27</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,694.17135 38.518126,5e-5"
+       id="path3178-9"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981808,694.17141 38.518382,0"
+       id="path3180-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g3126-8"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="6.5114212"
+       y="652.66315"
+       id="text9295"
+       sodipodi:linespacing="100%"><tspan
+         sodipodi:role="line"
+         id="tspan9297"
+         x="6.5114212"
+         y="652.66315">obsolete</tspan><tspan
+         sodipodi:role="line"
+         x="6.5114212"
+         y="662.66315"
+         id="tspan9299">but visible</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="159.24913"
+       y="668.43335"
+       id="text9301"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan9303"
+         x="159.24913"
+         y="668.43335">unstable</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:11.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="79.399506"
+       y="627.31293"
+       id="text5217-8-0"
+       sodipodi:linespacing="125%"
+       transform="scale(0.9999978,1.0000022)"><tspan
+         sodipodi:role="line"
+         id="tspan8594"
+         x="79.399506"
+         y="627.31293">hg uncommit <tspan
+   style="font-style:italic"
+   id="tspan3131">f1 f2 ...</tspan></tspan><tspan
+         sodipodi:role="line"
+         x="79.399506"
+         y="642.31293"
+         id="tspan3124">hg commit</tspan></text>
+    <g
+       id="g6372-4"
+       transform="translate(31.884309,581.4041)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path8598-5"
+         d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+         style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      <g
+         transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)"
+         id="g3821-3">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 35.5,23.60911 35.5,59.5"
+           id="path8466-5-0"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 33.5,23.60911 33.5,59.5"
+           id="path8466-4-7-7"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+    <g
+       id="g3118-2"
+       transform="translate(-60.000001,733.69805)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02-8"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-3"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-3"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">28</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="187.37656"
+       y="781.10907"
+       id="text3218"
+       sodipodi:linespacing="100%"><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="781.10907"
+         id="tspan4381">working dir</tspan><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="791.10907"
+         id="tspan3635">(clean)</tspan></text>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,703.12214 38.518124,32.09853"
+       id="path3178-9-5"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 71.240897,703.1981 -2.2e-5,31.94668"
+       id="path4123"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#rect2987-4-02-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2"
+       inkscape:connection-end-point="d4" />
+    <text
+       xml:space="preserve"
+       style="font-size:9.99999905px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="187.37656"
+       y="563.41107"
+       id="text4799-8-0-8"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="563.41107"
+         id="tspan4416-9">working dir</tspan><tspan
+         sodipodi:role="line"
+         x="187.37656"
+         y="575.91107"
+         id="tspan4420-1">(clean)</tspan></text>
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2-0);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 182.62097,561.67322 c -33.30785,-4.00189 -73.4927,-15.3975 -98.131267,9.24106"
+       id="path4446"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g3118-2-4"
+       transform="translate(-1.0430813e-6,783.69805)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02-8-7"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-3-7"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-3-0"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">29</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="M 81.981738,753.12214 120.5,785.22069"
+       id="path3180-1-6"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3118-2"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2-4"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2-0);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 30.44802,666.70515 c 9.697316,11.54911 30.278008,-0.41536 36.084144,15.84182"
+       id="path4908"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2-0);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 155.00217,664.33755 c -14.85295,-1.56817 -17.66404,5.2687 -18.48213,16.72192"
+       id="path5120"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;marker-end:url(#Arrow2Mend-2-0-5)"
+       d="m 184.5,777.49805 c -23.81983,-9.8642 -42.3145,-20.8823 -51.5,3"
+       id="path3662"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/figures/figure-ug12.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,606 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="270"
+   height="200"
+   id="svg3183"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="figure-ug12.svg">
+  <defs
+     id="defs3185">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-0"
+       style="overflow:visible">
+      <path
+         id="path5316-7-14"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3206"
+       style="overflow:visible">
+      <path
+         id="path3208"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3210"
+       style="overflow:visible">
+      <path
+         id="path3212"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3214"
+       style="overflow:visible">
+      <path
+         id="path3216"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3218"
+       style="overflow:visible">
+      <path
+         id="path3220"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path5316-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible">
+      <path
+         id="path4193"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3226"
+       style="overflow:visible">
+      <path
+         id="path3228"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3230"
+       style="overflow:visible">
+      <path
+         id="path3232"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3234"
+       style="overflow:visible">
+      <path
+         id="path3236"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker3238"
+       style="overflow:visible">
+      <path
+         id="path3240"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-1"
+       style="overflow:visible">
+      <path
+         id="path5316-7-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-8"
+       style="overflow:visible">
+      <path
+         id="path4193-8"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6080"
+       style="overflow:visible">
+      <path
+         id="path6082"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6084"
+       style="overflow:visible">
+      <path
+         id="path6086"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6088"
+       style="overflow:visible">
+      <path
+         id="path6090"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-3"
+       style="overflow:visible">
+      <path
+         id="path5316-7-2"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-5"
+       style="overflow:visible">
+      <path
+         id="path4193-3"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2-0-5"
+       style="overflow:visible">
+      <path
+         id="path5316-7-14-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="121.99883"
+     inkscape:cy="102.73738"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="825"
+     inkscape:window-height="678"
+     inkscape:window-x="413"
+     inkscape:window-y="279"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata3188">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-852.36218)">
+    <g
+       id="g4234"
+       transform="translate(2,-8)">
+      <text
+         transform="scale(0.9999978,1.0000022)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-0-7"
+         y="900.3703"
+         x="76.696045"
+         style="font-size:11.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+         xml:space="preserve"><tspan
+           y="900.3703"
+           x="76.696045"
+           sodipodi:role="line"
+           id="tspan3322">hg evolve --all</tspan></text>
+      <g
+         transform="translate(29.180861,844.4619)"
+         id="g6372-4-2">
+        <path
+           style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="m 36.655932,74.035228 3.649333,6.320665 3.711171,-6.427764"
+           id="path8598-5-0"
+           inkscape:connector-curvature="0" />
+        <g
+           id="g3821-3-9"
+           transform="matrix(1,0,0,1.5998137,5.836184,-16.712267)">
+          <path
+             inkscape:connector-curvature="0"
+             id="path8466-5-0-9"
+             d="M 35.5,23.60911 35.5,59.5"
+             style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+          <path
+             inkscape:connector-curvature="0"
+             id="path8466-4-7-7-4"
+             d="M 33.5,23.60911 33.5,59.5"
+             style="fill:none;stroke:#808080;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+        </g>
+      </g>
+    </g>
+    <g
+       transform="matrix(1.0000032,0,0,0.99999991,-8.2250019e-7,130.00002)"
+       id="g8678-6">
+      <rect
+         y="793.80884"
+         x="0.4999997"
+         height="18.053268"
+         width="21.481806"
+         id="rect2987-4-9"
+         style="fill:none;stroke:#000000;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-32"
+         y="807.20361"
+         x="3.4977415"
+         style="font-size:11.99999332px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-8"
+           sodipodi:role="line"
+           x="3.4977415"
+           y="807.20361">25</tspan></text>
+    </g>
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999946, 3.99999785;stroke-dashoffset:0"
+       id="rect2987-4-02-6"
+       width="21.481808"
+       height="18.053268"
+       x="60.5"
+       y="923.8089" />
+    <text
+       xml:space="preserve"
+       style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="63.544647"
+       y="937.20331"
+       id="text5217-8-72-1"
+       sodipodi:linespacing="125%"><tspan
+         y="937.20331"
+         x="63.544647"
+         sodipodi:role="line"
+         id="tspan6156-9-8">26</tspan></text>
+    <g
+       id="g4904">
+      <rect
+         y="923.80884"
+         x="120.50019"
+         height="18.053268"
+         width="21.481808"
+         id="rect2987-4-026-7"
+         style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 4;stroke-dashoffset:0" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-8"
+         y="937.20325"
+         x="123.42475"
+         style="font-size:11.99999428px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-9"
+           sodipodi:role="line"
+           x="123.42475"
+           y="937.20325">27</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,932.83543 38.518126,5e-5"
+       id="path3178-9"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981805,932.83549 38.518385,-1e-5"
+       id="path3180-1"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-end="#g4904"
+       inkscape:connection-end-point="d4" />
+    <g
+       id="g3118-2"
+       transform="translate(-60.000001,972.36213)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02-8"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-3"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-3"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">28</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="188.87656"
+       y="965.77319"
+       id="text3218"
+       sodipodi:linespacing="100%"><tspan
+         sodipodi:role="line"
+         x="188.87656"
+         y="965.77319"
+         id="tspan4381">working dir</tspan><tspan
+         sodipodi:role="line"
+         x="188.87656"
+         y="975.77319"
+         id="tspan3635">(clean)</tspan></text>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 21.981875,941.78622 38.518124,32.09853"
+       id="path3178-9-5"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g8678-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 71.240897,941.86217 -2.2e-5,31.94669"
+       id="path4123"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#rect2987-4-02-6"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2"
+       inkscape:connection-end-point="d4" />
+    <g
+       id="g3118-2-4"
+       transform="translate(-8.2250019e-7,1022.3622)">
+      <rect
+         y="1.4467307"
+         x="120.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-02-8-7"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-72-3-7"
+         y="14.841505"
+         x="123.54487"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-9-3-0"
+           sodipodi:role="line"
+           x="123.54487"
+           y="14.841505">29</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="M 81.981738,991.78623 120.5,1023.8848"
+       id="path3180-1-6"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3118-2"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3118-2-4"
+       inkscape:connection-end-point="d4" />
+    <g
+       id="g3126-8-4"
+       transform="matrix(1.000012,0,0,0.99999991,-60.002151,972.36218)">
+      <rect
+         y="1.4467307"
+         x="180.5"
+         height="18.05327"
+         width="21.481739"
+         id="rect2987-4-026-7-1"
+         style="fill:none;stroke:#000000;stroke-width:0.99999791;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+      <text
+         transform="scale(0.9999979,1.0000021)"
+         sodipodi:linespacing="125%"
+         id="text5217-8-3-8-6"
+         y="14.841505"
+         x="183.42488"
+         style="font-size:11.9999752px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan6156-0-9-7"
+           sodipodi:role="line"
+           x="183.42488"
+           y="14.841505">30</tspan></text>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.00000155px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-2);display:inline"
+       d="m 81.981738,982.8355 38.518272,4e-5"
+       id="path3180-1-4"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g3118-2"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3126-8-4"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.99999986, 2.99999958;stroke-dashoffset:0;marker-start:url(#DotM);display:inline"
+       d="m 131.24108,941.86211 -5e-5,31.9468"
+       id="path4123-8"
+       inkscape:connector-type="polyline"
+       inkscape:connector-curvature="0"
+       inkscape:connection-start="#g4904"
+       inkscape:connection-start-point="d4"
+       inkscape:connection-end="#g3126-8-4"
+       inkscape:connection-end-point="d4" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2-0-5);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 187.75,968.15572 c -23.81983,-9.8642 -42.3145,-20.8823 -51.5,3"
+       id="path3662"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-size:10px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
+       x="175"
+       y="154.5"
+       id="text5013"
+       sodipodi:linespacing="100%"
+       transform="translate(0,852.36218)"><tspan
+         sodipodi:role="line"
+         id="tspan5015"
+         x="175"
+         y="154.5">two heads!</tspan><tspan
+         sodipodi:role="line"
+         x="175"
+         y="164.5"
+         id="tspan5019">(merge or rebase)</tspan></text>
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2-0-5);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 170,152.5 c -16.09308,-9.35441 4.39162,-25.49226 -23.5,-23.5"
+       id="path5021"
+       inkscape:connector-curvature="0"
+       transform="translate(0,852.36218)" />
+    <path
+       style="color:#000000;fill:none;stroke:#707070;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Mend-2-0-5);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 169,153 c -11.30259,8.89405 -8.87795,25.5 -24,25.5"
+       id="path5025"
+       inkscape:connector-curvature="0"
+       transform="translate(0,852.36218)" />
+  </g>
+</svg>
Binary file docs/figures/hgview-example.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/from-mq.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,172 @@
+.. Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+..                Logilab SA        <contact@logilab.fr>
+
+-----------------------------------
+From MQ To Evolve, The Refugee Book
+-----------------------------------
+
+Cheat sheet
+-----------
+
+==============================  ============================================
+mq command                       new equivalent
+==============================  ============================================
+qseries                         ``log``
+qnew                            ``commit``
+qrefresh                        ``amend``
+qrefresh --exclude              ``uncommit``
+qpop                            ``update`` or ``gdown``
+qpush                           ``update`` or ``gup`` sometimes ``evolve``
+qrm                             ``prune``
+qfold                           ``fold``
+qdiff                           ``odiff``
+qrecord                         ``record``
+
+qfinish                         --
+qimport                         --
+==============================  ============================================
+
+
+Replacement details
+-------------------
+
+hg qseries
+``````````
+
+All your work in progress is now in real changesets all the time.
+
+You can use the standard log command to display them. You can use the
+phase revset to display unfinished work only, and use templates to have
+the same kind of compact that the output of qseries has.
+
+This will result in something like::
+
+  [alias]
+  wip = log -r 'not public()' --template='{rev}:{node|short} {desc|firstline}\n'
+
+hg qnew
+```````
+
+With evolve you handle standard changesets without an additional overlay.
+
+Standard changeset are created using hg commit as usual::
+
+  $ hg commit
+
+If you want to keep the "WIP is not pushed" behavior, you want to
+set your changeset in the secret phase using the phase command.
+
+Note that you only need it for the first commit you want to be secret. Later
+commits will inherit their parent's phase.
+
+If you always want your new commit to be in the secret phase, your should
+consider updating your configuration:
+
+  [phases]
+  new-commit=secret
+
+hg qref
+```````
+
+A new command from evolution will allow you to rewrite the changeset you are
+currently on. Just call:
+
+  $ hg amend
+
+This command takes the same options as commit, plus the switch '-e' (--edit)
+to edit the commit message in an editor.
+
+
+.. -c is very confusig
+..
+.. The amend command also has a -c switch which allows you to make an
+.. explicit amending commit before rewriting a changeset.::
+..
+..   $ hg record -m 'feature A'
+..   # oups, I forgot some stuff
+..   $ hg record babar.py
+..   $ hg amend -c .^ # .^ refer to "working directory parent, here 'feature A'
+
+.. note: refresh is an alias for amend
+
+hg qref --exclude
+`````````````````
+
+To remove changes from your current commit use::
+
+  $ hg uncommit not-ready.txt
+
+
+hg qpop
+```````
+
+The following command emulates the behavior of hg qpop:
+
+  $ hg gdown
+
+If you need to go back to an arbitrary commit you can use:
+
+  $ hg update
+
+.. note:: gdown and update allow movement with working directory
+          changes applied, and gracefully merge them.
+
+hg qpush
+````````
+
+When you rewrite changesets, descendants of rewritten changesets are marked as
+"unstable". You need to rewrite them on top of the new version of their
+ancestor.
+
+The evolution extension adds a command to rewrite "unstable"
+changesets:::
+
+  $ hg evolve
+
+You can also decide to do it manually using::
+
+  $ hg graft -O <old-version>
+
+or::
+
+  $ hg rebase -r <revset for old version> -d .
+
+note: using graft allows you to pick the changeset you want next as the --move
+option of qpush do.
+
+
+hg qrm
+``````
+
+evolution introduce a new command to mark a changeset as "not wanted anymore".::
+
+  $ hg prune <revset>
+
+hg qfold
+````````
+
+
+::
+
+  $ hg fold first::last
+
+hg qdiff
+````````
+
+``pdiff`` is an alias for `hg diff -r .^` It works like qdiff, but outside MQ.
+
+
+
+hg qfinish and hg qimport
+`````````````````````````
+
+These are not necessary anymore. If you want to control the
+mutability of changesets, see the phase feature.
+
+
+
+hg qcommit
+``````````
+
+If you really need to send patches through versioned mq patches, you should
+look at the qsync extension.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/index.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,147 @@
+.. Copyright © 2014 Greg Ward <greg@gerg.ca>
+
+==================================
+Changeset Evolution with Mercurial
+==================================
+
+.. toctree::
+   :maxdepth: 2
+
+   user-guide
+   sharing
+   concepts
+   from-mq
+
+`evolve`_ is an experimental Mercurial extension for safe mutable history.
+
+.. _`evolve`: https://www.mercurial-scm.org/wiki/EvolveExtension
+
+With core Mercurial, changesets are permanent and immutable. You can
+commit new changesets to modify your source code, but you cannot
+modify or remove old changesets—they are carved in stone for all
+eternity.
+
+For years, Mercurial has included various extensions that allow
+history modification: ``rebase``, ``mq``, ``histedit``, and so forth.
+These are useful and popular extensions, and in fact history
+modification is one of the big reasons DVCSes (distributed version
+control systems) like Mercurial took off.
+
+But there's a catch: until now, Mercurial's various mechanisms for
+modifying history have been *unsafe*, in that changesets were
+destroyed (“stripped”) rather than simply made invisible.
+
+``evolve`` makes things better in a couple of ways:
+
+  * It changes the behaviour of most existing history modification
+    extensions (``rebase``, ``histedit``, etc.) so they use a safer
+    mechanism (*changeset obsolescence*, covered below) rather than
+    the older, less safe *strip* operation.
+
+  * It provides a new way of modifying history that is roughly
+    equivalent to ``mq`` (but much nicer and safer).
+
+It helps to understand that ``evolve`` builds on infrastructure
+already in core Mercurial:
+
+  * *Phases* (starting in Mercurial 2.1) allow you to distinguish
+    mutable and immutable changesets. We'll cover phases early in the
+    user guide, since understanding phases is essential to
+    understanding ``evolve``.
+
+  * *Changeset obsolescence* (starting in Mercurial 2.3) is how
+    Mercurial knows how history has been modified, specifically when
+    one changeset replaces another. In the obsolescence model, a
+    changeset is neither removed nor modified, but is instead marked
+    *obsolete* and typically replaced by a *successor*. Obsolete
+    changesets usually become *hidden* as well. Obsolescence is an
+    invisible feature until you start using ``evolve``, so we'll cover
+    it in the user guide too.
+
+Some of the things you can do with ``evolve`` are:
+
+  * Fix a mistake immediately: “Oops! I just committed a changeset
+    with a syntax error—I'll fix that and amend the changeset so no
+    one sees my mistake.” (While this is possible using existing
+    features of core Mercurial, ``evolve`` makes it safer.)
+
+  * Fix a mistake a little bit later: “Oops! I broke the tests three
+    commits back, but only noticed it now—I'll just update back to the
+    bad changeset, fix my mistake, amend the changeset, and evolve
+    history to update the affected changesets.”
+
+  * Remove unwanted changes: “I hacked in some debug output two
+    commits back; everything is working now, so I'll just prune that
+    unwanted changeset and evolve history before pushing.”
+
+  * Share mutable history with yourself: say you do most of your
+    programming work locally, but need to test on a big remote server
+    somewhere before you know everything is good. You can use
+    ``evolve`` to share mutable history between two computers, pushing
+    finely polished changesets to a public repository only after
+    testing on the test server.
+
+  * Share mutable history for code review: you don't want to publish
+    unreviewed changesets, but you can't block every commit waiting
+    for code review. The solution is to share mutable history with
+    your reviewer, amending each changeset until it passes review.
+
+``evolve`` is experimental!
+---------------------------
+
+The long-term plan for ``evolve`` is to add it to core Mercurial.
+However, it is not yet stable enough for that. In particular:
+
+  * The UI is unstable: ``evolve``'s command names and command options
+    are not completely nailed down yet. They are subject to occasional
+    backwards-incompatible changes. If you write scripts that use
+    evolve commands, a future release could break your scripts.
+
+  * There are still some corner cases that aren't handled yet. If you
+    think you have found such a case, please check if it's already
+    described in the Mercurial bug tracker (https://bz.mercurial-scm.org/).
+    Bugs in ``evolve`` are files under component "evolution": use
+    `this query`_ to view open bugs in ``evolve``.
+
+.. _`this query`: https://bz.mercurial-scm.org/buglist.cgi?component=evolution&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=NEED_EXAMPLE
+
+Installation and setup
+----------------------
+
+To use ``evolve``, you must:
+
+  #. Clone the ``evolve`` repository::
+
+       cd ~/src
+       hg clone http://hg.netv6.net/evolve-main
+
+  #. Configure the extension, either locally ::
+
+       hg config --local
+
+     or for all your repositories ::
+
+       hg config --edit
+
+     Then add ::
+
+       evolve=~/src/evolve-main/hgext/evolve.py
+
+     in the ``[extensions]`` section (adding the section if necessary). Use
+     the directory that you actually cloned to, of course.
+
+
+Next steps:
+-----------
+
+  * For a practical guide to using ``evolve`` in a single repository,
+    see the `user guide`_.
+  * For more advanced tricks, see `sharing mutable history`_.
+  * To learn about the concepts underlying ``evolve``, see `concepts`_
+    (incomplete).
+  * If you're coming from MQ, see the `MQ migration guide`_ (incomplete).
+
+.. _`user guide`: user-guide.html
+.. _`sharing mutable history`: sharing.html
+.. _`concepts`: concepts.html
+.. _`MQ migration guide`: from-mq.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/makefile	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,11 @@
+
+all: tutorials/tutorial.rst static/logo-evolve.ico
+	sphinx-build . ../html/
+
+tutorials/tutorial.rst: tutorials/tutorial.t
+	python test2rst.py tutorials/
+
+static/logo-evolve.ico: static/logo-evolve.svg
+	convert -resize 36x36 static/logo-evolve.svg static/logo-evolve.ico
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/obs-terms.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,237 @@
+.. Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+..                Logilab SA        <contact@logilab.fr>
+
+-----------------------------------
+Terminology of the obsolete concept
+-----------------------------------
+
+Obsolete markers
+----------------
+
+The mutable concept is based on **obsolete markers**. Creating an obsolete
+marker registers a relation between an old obsoleted changeset and its newer
+version.
+
+Old changesets are called **precursors** while their new versions are called
+**successors**. A marker always registers a single *precursor* and:
+
+- no *successor*: the *precursor* is just discarded.
+- one *successor*: the *precursor* has been rewritten
+- multiple *successors*: the *precursor* were splits in multiple
+  changesets.
+
+.. The *precursors* and *successors* terms can be used on changeset directly:
+
+.. :precursors: of a changeset `A` are changesets used as *precursors* by
+..              obsolete marker using changeset `A` as *successors*
+
+.. :successors: of a changeset `B` are changesets used as *successors* by
+..              obsolete marker using changeset `B` as *precursors*
+
+Chaining obsolete markers is allowed to rewrite a changeset that is already a
+*successor*. This is a kind of *second order version control*.
+To clarify ambiguous situations one can use **direct precursors** or
+**direct successors** to name changesets that are directly related.
+
+The set of all *obsolete markers* forms a direct acyclic graph the same way
+standard *parents*/*children* relation does. In this graph we have:
+
+:any precursors: are transitive precursors of a changeset: *direct precursors*
+                 and *precursors* of *precursors*.
+
+:any successors: are transitive successors of a changeset: *direct successors*
+                 and *successors*  of *successors*)
+
+Obsolete markers may refer changesets that are not known locally.
+So, *direct precursors* of a changeset may be unknown locally.
+This is why we usually focus on the **first known precursors**  of the rewritten
+changeset. The same apply for *successors*.
+
+Changeset in *any successors* which are not **obsolete** are called
+**newest successors**..
+
+.. note:: I'm not very happy with this naming scheme and I'm looking for a
+          better distinction between *direct successors* and **any successors**.
+
+Possible changesets "type"
+--------------------------
+
+The following table describes names and behaviors of changesets affected by
+obsolete markers. The left column describes generic categories and the right
+columns are about sub-categories.
+
+
++---------------------+--------------------------+-----------------------------+
+| **mutable**         | **obsolete**             | **extinct**                 |
+|                     |                          |                             |
+| Changeset in either | Obsolete changeset is    | *extinct* changeset is      |
+| *draft* or *secret* | *mutable* used as a      | *obsolete* which has only   |
+| phase.              | *precursor*.             | *obsolete* descendants.     |
+|                     |                          |                             |
+|                     | A changeset is used as   | They can safely be:         |
+|                     | a *precursor* when at    |                             |
+|                     | least one obsolete       | - hidden in the UI,         |
+|                     | marker refers to it      | - silently excluded from    |
+|                     | as precursors.           |   pull and push operations  |
+|                     |                          | - mostly ignored            |
+|                     |                          | - garbage collected         |
+|                     |                          |                             |
+|                     |                          +-----------------------------+
+|                     |                          |                             |
+|                     |                          | **suspended**               |
+|                     |                          |                             |
+|                     |                          | *suspended* changeset is    |
+|                     |                          | *obsolete* with at least    |
+|                     |                          | one non-obsolete descendant |
+|                     |                          |                             |
+|                     |                          | Those descendants prevent   |
+|                     |                          | properties of extinct       |
+|                     |                          | changesets to apply. But    |
+|                     |                          | they will refuse to be      |
+|                     |                          | pushed without --force.     |
+|                     |                          |                             |
+|                     +--------------------------+-----------------------------+
+|                     |                          |                             |
+|                     | **troubled**             | **unstable**                |
+|                     |                          |                             |
+|                     | *troubled*    has        | *unstable* is a changeset   |
+|                     | unresolved issue caused  | with obsolete ancestors.    |
+|                     | by *obsolete* relations. |                             |
+|                     |                          |                             |
+|                     | Possible issues are      | It must be rebased on a     |
+|                     | listed in the next       | non *troubled*    base to   |
+|                     | column. It is possible   | solve the problem.          |
+|                     | for *troubled*           |                             |
+|                     | changeset to combine     | (possible alternative name: |
+|                     | multiple issue at once.  | precarious)                 |
+|                     | (a.k.a. divergent   and  |                             |
+|                     | unstable)                +-----------------------------+
+|                     |                          |                             |
+|                     | (possible alternative    | **bumped**                  |
+|                     | names: unsettled,        |                             |
+|                     | troublesome              | *bumped* is a changeset     |
+|                     |                          | that tries to be successor  |
+|                     |                          | of  public changesets.      |
+|                     |                          |                             |
+|                     |                          | Public changeset can't      |
+|                     |                          | be deleted and replace      |
+|                     |                          | *bumped*                    |
+|                     |                          | need to be converted into   |
+|                     |                          | an overlay to this public   |
+|                     |                          | changeset.                  |
+|                     |                          |                             |
+|                     |                          | (possible alternative names:|
+|                     |                          | mislead, naive, unaware,    |
+|                     |                          | mindless, disenchanting)    |
+|                     |                          |                             |
+|                     |                          +-----------------------------+
+|                     |                          | **divergent**               |
+|                     |                          |                             |
+|                     |                          | *divergent*   is changeset  |
+|                     |                          | that appears when multiple  |
+|                     |                          | changesets are successors   |
+|                     |                          | of the same precursor.      |
+|                     |                          |                             |
+|                     |                          | *divergent*   are solved    |
+|                     |                          | through a three ways merge  |
+|                     |                          | between the two             |
+|                     |                          | *divergent*   ,             |
+|                     |                          | using the last "obsolete-   |
+|                     |                          | -common-ancestor" as the    |
+|                     |                          | base.                       |
+|                     |                          |                             |
+|                     |                          | (*splitting* is             |
+|                     |                          | properly not detected as a  |
+|                     |                          | conflict)                   |
+|                     |                          |                             |
+|                     |                          | (possible alternative names:|
+|                     |                          | clashing, rival, concurent, |
+|                     |                          | conflicting)                |
+|                     |                          |                             |
+|                     +--------------------------+-----------------------------+
+|                     |                                                        |
+|                     | Mutable changesets which are neither *obsolete* or     |
+|                     | *troubled*    are *"ok"*.                              |
+|                     |                                                        |
+|                     | Do we really need a name for it ? *"ok"* is a pretty   |
+|                     | crappy name :-/ other possibilities are:               |
+|                     |                                                        |
+|                     | - stable (confusing with stable branch)                |
+|                     | - sane                                                 |
+|                     | - healthy                                              |
+|                     |                                                        |
++---------------------+--------------------------------------------------------+
+|                                                                              |
+|     **immutable**                                                            |
+|                                                                              |
+| Changesets in the *public* phases.                                           |
+|                                                                              |
+| Rewriting operation refuse to work on immutable changeset.                   |
+|                                                                              |
+| Obsolete markers that refer an immutable changeset as precursors have        |
+| no effect on the precursors but may have effect on the successors.           |
+|                                                                              |
+| When a *mutable* changeset becomes *immutable* (changing its phase from draft|
+| to public) it is just *immutable* and loose any property of it's former      |
+| state.                                                                       |
+|                                                                              |
+| The phase properties says that public changesets stay as *immutable* forever.|
+|                                                                              |
++------------------------------------------------------------------------------+
+
+
+
+Command and operation name
+--------------------------
+
+
+Existing terms
+``````````````
+
+Mercurial core already uses the following terms:
+
+:amend: to rewrite a changeset
+:graft: to copy a changeset
+:rebase: to move a changeset
+
+
+Uncommit
+````````
+
+Remove files from a commit (and leave them as dirty in the working directory)
+
+The *evolve* extension have an `uncommit` command that aims to replace most
+`rollback` usage.
+
+Fold
+````
+
+Collapse multiple changesets into a unique one.
+
+The *evolve* extension will have a `fold` command.
+
+Prune
+`````
+
+Make a changeset obsolete without successors.
+
+This an important operation as it should mostly replace *strip*.
+
+Alternative names:
+
+- kill: shall has funny effects when you forget "hg" in front of ``hg kill``.
+- obsolete: too vague, too long and too generic.
+
+evolve
+``````
+
+Automatically resolve *troublesome* changesets
+(*unstable*, *bumped* and *divergent*)
+
+This is an important name as hg pull/push will suggest it the same way it
+suggest merging when you add heads.
+
+alternative names:
+
+- solve (too generic ?)
+- stabilize
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/sharing.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,735 @@
+.. Copyright © 2014 Greg Ward <greg@gerg.ca>
+
+------------------------------
+Evolve: Shared Mutable History
+------------------------------
+
+.. contents::
+
+Once you have mastered the art of mutable history in a single
+repository (see the `user guide`_), you can move up to the next level:
+*shared* mutable history. ``evolve`` lets you push and pull draft
+changesets between repositories along with their obsolescence markers.
+This opens up a number of interesting possibilities.
+
+.. _`user guide`: user-guide.html
+
+The simplest scenario is a single developer working across two
+computers. Say you're working on code that must be tested on a remote
+test server, probably in a rack somewhere, only accessible by SSH, and
+running an “enterprise-grade” (out-of-date) OS. But you probably
+prefer to write code locally: everything is setup the way you like it,
+and you can use your preferred editor, IDE, merge/diff tools, etc.
+
+Traditionally, your options are limited: either
+
+  * (ab)use your source control system by committing half-working code
+    in order to get it onto the remote test server, or
+  * go behind source control's back by using ``rsync`` (or similar) to
+    transfer your code back-and-forth until it is ready to commit
+
+The former is less bad with distributed version control systems like
+Mercurial, but it's still far from ideal. (One important version
+control “best practice” is that every commit should make things just a
+little bit better, i.e. you should never commit code that is worse
+than what came before.) The latter, avoiding version control entirely,
+means that you're walking a tightrope without a safety net. One
+accidental ``rsync`` in the wrong direction could destroy hours of
+work.
+
+Using Mercurial with ``evolve`` to share mutable history solves these
+problems. As with single-repository ``evolve``, you can commit
+whenever the code is demonstrably better, even if all the tests aren't
+passing yet—just ``hg amend`` when they are. And you can transfer
+those half-baked changesets between repositories to try things out on
+your test server before anything is carved in stone.
+
+A less common scenario is multiple developers sharing mutable history,
+typically for code review. We'll cover this scenario later. But first,
+single-user sharing.
+
+Sharing with a single developer
+-------------------------------
+
+Publishing and non-publishing repositories
+==========================================
+
+The key to shared mutable history is to keep your changesets in
+*draft* phase as you pass them around. Recall that by default, ``hg
+push`` promotes changesets from *draft* to *public*, and public
+changesets are immutable. You can change this behaviour by
+reconfiguring the *target* repository so that it is non-publishing.
+(Short version: set ``phases.publish`` to ``false``. Long version
+follows.)
+
+Setting up
+==========
+
+We'll work through an example with three local repositories, although
+in the real world they'd most likely be on three different computers.
+First, the ``public`` repository is where tested, polished changesets
+live, and it is where you synchronize with the rest of your team. ::
+
+  $ hg init public
+
+We'll need two clones where work gets done, ``test-repo`` and
+``dev-repo``::
+
+  $ hg clone public test-repo
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone test-repo dev-repo
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+``dev-repo`` is your local machine, with GUI merge tools and IDEs and
+everything configured just the way you like it. ``test-repo`` is the
+test server in a rack somewhere behind SSH. So for the most part,
+we'll develop in ``dev-repo``, push to ``test-repo``, test and polish
+there, and push to ``public``.
+
+The key to shared mutable history is to make the target repository, in
+this case ``test-repo``, non-publishing. And, of course, we have to
+enable ``evolve`` in both ``test-repo`` and ``dev-repo``.
+
+First, edit the configuration for ``test-repo``::
+
+  $ hg -R test-repo config --edit --local
+
+and add ::
+
+  [phases]
+  publish = false
+
+  [extensions]
+  evolve = /path/to/evolve-main/hgext/evolve.py
+
+Then edit the configuration for ``dev-repo``::
+
+  $ hg -R dev-repo config --edit --local
+
+and add ::
+
+  [extensions]
+  evolve = /path/to/evolve-main/hgext/evolve.py
+
+Keep in mind that in real life, these repositories would probably be
+on separate computers, so you'd have to login to each one to configure
+each repository.
+
+To start things off, let's make one public, immutable changeset::
+
+  $ cd test-repo
+  $ echo 'my new project' > file1
+  $ hg add file1
+  $ hg commit -m 'create new project'
+  $ hg push
+  [...]
+  added 1 changesets with 1 changes to 1 files
+
+and pull that into the development repository::
+
+  $ cd ../dev-repo
+  $ hg pull -u
+  [...]
+  added 1 changesets with 1 changes to 1 files
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Example 1: Amend a shared changeset
+===================================
+
+Everything you learned in the `user guide`_ applies to work done in
+``dev-repo``. You can commit, amend, uncommit, evolve, and so forth
+just as before.
+
+.. _`user guide`: user-guide.html
+
+Things get different when you push changesets to ``test-repo``. Or
+rather, things stay the same, which *is* different: because we
+configured ``test-repo`` to be non-publishing, draft changesets stay
+draft when we push them to ``test-repo``. Importantly, they're also
+draft (mutable) in ``test-repo``.
+
+Let's commit a preliminary change and push it to ``test-repo`` for
+testing. ::
+
+  $ echo 'fix fix fix' > file1
+  $ hg commit -m 'prelim change'
+  $ hg push ../test-repo
+
+At this point, ``dev-repo`` and ``test-repo`` have the same changesets
+in the same phases:
+
+  [figure SG01: rev 0:0dc9 public, rev 1:f649 draft, same on both repos]
+
+(You may notice a change in notation from the user guide: now
+changesets are labelled with their revision number and the first four
+digits of the 40-digit hexadecimal changeset ID. Mercurial revision
+numbers are never stable when working across repositories, especially
+when obsolescence is involved. We'll see why shortly.)
+
+Now let's switch to ``test-repo`` to test our change::
+
+  $ cd ../test-repo
+  $ hg update
+
+Don't forget to ``hg update``! Pushing only adds changesets to a
+remote repository; it does not update the working directory (unless
+you have a hook that updates for you).
+
+Now let's imagine the tests failed because we didn't use proper
+punctuation and capitalization (oops). Let's amend our preliminary fix
+(and fix the lame commit message while we're at it)::
+
+  $ echo 'Fix fix fix.' > file1
+  $ hg amend -m 'fix bug 37'
+
+Now we're in a funny intermediate state (figure 2): revision 1:f649 is
+obsolete in ``test-repo``, having been replaced by revision 3:60ff
+(revision 2:2a03 is another one of those temporary amend commits that
+we saw in the user guide)—but ``dev-repo`` knows nothing of these
+recent developments.
+
+  [figure SG02: test-repo has rev 0:0dc9 public, rev 1:f649, 2:2a03 obsolete, rev 3:60ff draft; dev-repo same as in SG01]
+
+Let's resynchronize::
+
+  $ cd ../dev-repo
+  $ hg pull -u
+  [...]
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+As seen in figure 3, this transfers the new changeset *and* the
+obsolescence marker for revision 1. However, it does *not* transfer
+the temporary amend commit, because it is hidden. Push and pull
+transfer obsolesence markers between repositories, but they do not
+transfer hidden changesets.
+
+  [figure SG03: dev-repo grows new rev 2:60ff, marks 1:f649 obsolete]
+
+Because of this deliberately incomplete synchronization, revision
+numbers in ``test-repo`` and ``dev-repo`` are no longer consistent. We
+*must* use changeset IDs.
+
+Example 2: Amend again, locally
+===============================
+
+This process can repeat. Perhaps you figure out a more elegant fix to
+the bug, and want to mutate history so nobody ever knows you had a
+less-than-perfect idea. We'll implement it locally in ``dev-repo`` and
+push to ``test-repo``::
+
+  $ echo 'Fix, fix, and fix.' > file1
+  $ hg amend
+  $ hg push
+
+This time around, the temporary amend commit is in ``dev-repo``, and
+it is not transferred to ``test-repo``—the same as before, just in the
+opposite direction. Figure 4 shows the two repositories after amending
+in ``dev-repo`` and pushing to ``test-repo``.
+
+  [figure SG04: each repo has one temporary amend commit, but they're different in each one]
+
+Let's hop over to ``test-repo`` to test the more elegant fix::
+
+  $ cd ../test-repo
+  $ hg update
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+This time, all the tests pass, so no further amending is required.
+This bug fix is finished, so we push it to the public repository::
+
+  $ hg push
+  [...]
+  added 1 changesets with 1 changes to 1 files
+
+Note that only one changeset—the final version, after two
+amendments—was actually pushed. Again, Mercurial doesn't transfer
+hidden changesets on push and pull.
+
+.. _`concept guide`: concepts.html
+
+So the picture in ``public`` is much simpler than in either
+``dev-repo`` or ``test-repo``. Neither our missteps nor our amendments
+are publicly visible, just the final, beautifully polished changeset:
+
+  [figure SG05: public repo with rev 0:0dc9, 1:de61, both public]
+
+There is one important step left to do. Because we pushed from
+``test-repo`` to ``public``, the pushed changeset is in *public* phase
+in those two repositories. But ``dev-repo`` has been out-of-the-loop;
+changeset de61 is still *draft* there. If we're not careful, we might
+mutate history in ``dev-repo``, obsoleting a changeset that is already
+public. Let's avoid that situation for now by pushing up to
+``dev-repo``::
+
+  $ hg push ../dev-repo
+  pushing to ../dev-repo
+  searching for changes
+  no changes found
+
+Even though no *changesets* were pushed, Mercurial still pushed
+obsolescence markers and phase changes to ``dev-repo``.
+
+A final note: since this fix is now *public*, it is immutable. It's no
+longer possible to amend it::
+
+  $ hg amend -m 'fix bug 37'
+  abort: cannot amend public changesets
+
+This is, after all, the whole point of Mercurial's phases: to prevent
+rewriting history that has already been published.
+
+Sharing with multiple developers: code review
+---------------------------------------------
+
+Now that you know how to share your own mutable history across
+multiple computers, you might be wondering if it makes sense to share
+mutable history with others. It does, but you have to be careful, stay
+alert, and *communicate* with your peers.
+
+Code review is a good use case for sharing mutable history across
+multiple developers: Alice commits a draft changeset, submits it for
+review, and amends her changeset until her reviewer is satisfied.
+Meanwhile, Bob is also committing draft changesets for review,
+amending until his reviewer is satisfied. Once a particular changeset
+passes review, the respective author (Alice or Bob) pushes it to the
+public (publishing) repository.
+
+Incidentally, the reviewers here can be anyone: maybe Bob and Alice
+review each other's work; maybe the same third party reviews both; or
+maybe they pick different experts to review their work on different
+parts of a large codebase. Similarly, it doesn't matter if reviews are
+conducted in person, by email, or by carrier pigeon. Code review is
+outside of the scope of Mercurial, so all we're looking at here
+is the mechanics of committing, amending, pushing, and pulling.
+
+Setting up
+==========
+
+To demonstrate, let's start with the ``public`` repository as we left
+it in the last example, with two immutable changesets (figure 5
+above). We'll clone a ``review`` repository from it, and then Alice
+and Bob will both clone from ``review``. ::
+
+  $ hg clone public review
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone review alice
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone review bob
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+We need to configure Alice's and Bob's working repositories to enable
+``evolve``. First, edit Alice's configuration with ::
+
+  $ hg -R alice config --edit --local
+
+and add ::
+
+  [extensions]
+  evolve = /path/to/evolve-main/hgext/evolve.py
+
+Then edit Bob's repository configuration::
+
+  $ hg -R bob config --edit --local
+
+and add the same text.
+
+Example 3: Alice commits and amends a draft fix
+===============================================
+
+We'll follow Alice working on a bug fix. We're going to use bookmarks to
+make it easier to understand multiple branch heads in the ``review``
+repository, so Alice starts off by creating a bookmark and committing
+her first attempt at a fix::
+
+  $ hg bookmark bug15
+  $ echo 'fix' > file2
+  $ hg commit -A -u alice -m 'fix bug 15 (v1)'
+  adding file2
+
+Note the unorthodox "(v1)" in the commit message. We're just using
+that to make this tutorial easier to follow; it's not something we'd
+recommend in real life.
+
+Of course Alice wouldn't commit unless her fix worked to her
+satisfaction, so it must be time to solicit a code review. She does
+this by pushing to the ``review`` repository::
+
+  $ hg push -B bug15
+  [...]
+  added 1 changesets with 1 changes to 1 files
+  exporting bookmark bug15
+
+(The use of ``-B`` is important to ensure that we only push the
+bookmarked head, and that the bookmark itself is pushed. See this
+`guide to bookmarks`_, especially the `Sharing Bookmarks`_ section, if
+you're not familiar with bookmarks.)
+
+.. _`guide to bookmarks`: http://mercurial.aragost.com/kick-start/en/bookmarks/
+.. _`Sharing Bookmarks`: http://mercurial.aragost.com/kick-start/en/bookmarks/#sharing-bookmarks
+
+Some time passes, and Alice receives her code review. As a result,
+Alice revises her fix and submits it for a second review::
+
+  $ echo 'Fix.' > file2
+  $ hg amend -m 'fix bug 15 (v2)'
+  $ hg push
+  [...]
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  updating bookmark bug15
+
+Figure 6 shows the state of the ``review`` repository at this point.
+
+  [figure SG06: rev 2:fn1e is Alice's obsolete v1, rev 3:cbdf is her v2; both children of rev 1:de61]
+
+After a busy morning of bug fixing, Alice stops for lunch. Let's see
+what Bob has been up to.
+
+Example 4: Bob implements and publishes a new feature
+=====================================================
+
+Meanwhile, Bob has been working on a new feature. Like Alice, he'll
+use a bookmark to track his work, and he'll push that bookmark to the
+``review`` repository, so that reviewers know which changesets to
+review. ::
+
+  $ cd ../bob
+  $ echo 'stuff' > file1
+  $ hg bookmark featureX
+  $ hg commit -u bob -m 'implement feature X (v1)'          # rev 4:1636
+  $ hg push -B featureX
+  [...]
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark featureX
+
+When Bob receives his code review, he improves his implementation a
+bit, amends, and submits the resulting changeset for review::
+
+  $ echo 'do stuff' > file1
+  $ hg amend -m 'implement feature X (v2)'                  # rev 5:0eb7
+  $ hg push
+  [...]
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  updating bookmark featureX
+
+Unfortunately, that still doesn't pass muster. Bob's reviewer insists
+on proper capitalization and punctuation. ::
+
+  $ echo 'Do stuff.' > file1
+  $ hg amend -m 'implement feature X (v3)'                  # rev 6:540b
+
+On the bright side, the second review said, "Go ahead and publish once
+you fix that." So Bob immediately publishes his third attempt::
+
+  $ hg push ../public
+  [...]
+  added 1 changesets with 1 changes to 1 files
+
+It's not enough just to update ``public``, though! Other people also
+use the ``review`` repository, and right now it doesn't have Bob's
+latest amendment ("v3", revision 6:540b), nor does it know that the
+precursor of that changeset ("v2", revision 5:0eb7) is obsolete. Thus,
+Bob pushes to ``review`` as well::
+
+  $ hg push ../review
+  [...]
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  updating bookmark featureX
+
+Figure 7 shows the result of Bob's work in both ``review`` and
+``public``.
+
+  [figure SG07: review includes Alice's draft work on bug 15, as well as Bob's v1, v2, and v3 changes for feature X: v1 and v2 obsolete, v3 public. public contains only the final, public implementation of feature X]
+
+Incidentally, it's important that Bob push to ``public`` *before*
+``review``. If he pushed to ``review`` first, then revision 6:540b
+would still be in *draft* phase in ``review``, but it would be
+*public* in both Bob's local repository and the ``public`` repository.
+That could lead to confusion at some point, which is easily avoided by
+pushing first to ``public``.
+
+Example 5: Alice integrates and publishes
+=========================================
+
+Finally, Alice gets back from lunch and sees that the carrier pigeon
+with her second review has arrived (or maybe it's in her email inbox).
+Alice's reviewer approved her amended changeset, so she pushes it to
+``public``::
+
+  $ hg push ../public
+  [...]
+  remote has heads on branch 'default' that are not known locally: 540ba8f317e6
+  abort: push creates new remote head cbdfbd5a5db2!
+  (pull and merge or see "hg help push" for details about pushing new heads)
+
+Oops! Bob has won the race to push first to ``public``. So Alice needs
+to integrate with Bob: let's pull his changeset(s) and see what the
+branch heads are. ::
+
+  $ hg pull ../public
+  [...]
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg log -G -q -r 'head()' --template '{rev}:{node|short}  ({author})\n'
+  o  5:540ba8f317e6  (bob)
+  |
+  | @  4:cbdfbd5a5db2  (alice)
+  |/
+
+We'll assume Alice and Bob are perfectly comfortable with rebasing
+changesets. (After all, they're already using mutable history in the
+form of ``amend``.) So Alice rebases her changeset on top of Bob's and
+publishes the result::
+
+  $ hg rebase -d 5
+  $ hg push ../public
+  [...]
+  added 1 changesets with 1 changes to 1 files
+  $ hg push ../review
+  [...]
+  added 1 changesets with 0 changes to 0 files
+  updating bookmark bug15
+
+The result, in both ``review`` and ``public`` repositories, is shown
+in figure 8.
+
+  [figure SG08: review shows v1 and v2 of Alice's fix, then v1, v2, v3 of Bob's feature, finally Alice's fix rebased onto Bob's. public just shows the final public version of each changeset]
+
+Getting into trouble with shared mutable history
+------------------------------------------------
+
+Mercurial with ``evolve`` is a powerful tool, and using powerful tools
+can have consequences. (You can cut yourself badly with a sharp knife,
+but every competent chef keeps several around. Ever try to chop onions
+with a spoon?)
+
+In the user guide, we saw examples of *unstable* changesets, which are
+the most common type of troubled changeset. (Recall that a
+non-obsolete changeset with obsolete ancestors is unstable.)
+
+Two other types of trouble can happen: *divergent* and *bumped*
+changesets. Both are more likely with shared mutable history,
+especially mutable history shared by multiple developers.
+
+Setting up
+==========
+
+For these examples, we're going to use a slightly different workflow:
+as before, Alice and Bob share a ``public`` repository. But this time
+there is no ``review`` repository. Instead, Alice and Bob put on their
+cowboy hats, throw good practice to the wind, and pull directly from
+each other's working repositories.
+
+So we throw away everything except ``public`` and reclone::
+
+  $ rm -rf review alice bob
+  $ hg clone public alice
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone public bob
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Once again we have to configure their repositories: enable ``evolve``
+and (since Alice and Bob will be pulling directly from each other)
+make their repositories non-publishing. Edit Alice's configuration::
+
+  $ hg -R alice config --edit --local
+
+and add ::
+
+  [extensions]
+  rebase =
+  evolve = /path/to/evolve-main/hgext/evolve.py
+
+  [phases]
+  publish = false
+
+Then edit Bob's repository configuration::
+
+  $ hg -R bob config --edit --local
+
+and add the same text.
+
+Example 6: Divergent changesets
+===============================
+
+When an obsolete changeset has two successors, those successors are
+*divergent*. One way to get into such a situation is by failing to
+communicate with your teammates. Let's see how that might happen.
+
+First, we'll have Bob commit a bug fix that could still be improved::
+
+  $ cd bob
+  $ echo 'pretty good fix' >> file1
+  $ hg commit -u bob -m 'fix bug 24 (v1)'                   # rev 4:2fe6
+
+Since Alice and Bob are now in cowboy mode, Alice pulls Bob's draft
+changeset and amends it herself. ::
+
+  $ cd ../alice
+  $ hg pull -u ../bob
+  [...]
+  added 1 changesets with 1 changes to 1 files
+  $ echo 'better fix (alice)' >> file1
+  $ hg amend -u alice -m 'fix bug 24 (v2 by alice)'
+
+But Bob has no idea that Alice just did this. (See how important good
+communication is?) So he implements a better fix of his own::
+
+  $ cd ../bob
+  $ echo 'better fix (bob)' >> file1
+  $ hg amend -u bob -m 'fix bug 24 (v2 by bob)'             # rev 6:a360
+
+At this point, the divergence exists, but only in theory: Bob's
+original changeset, 4:2fe6, is obsolete and has two successors. But
+those successors are in different repositories, so the trouble is not
+visible to anyone yet. It will be as soon as Bob pulls from Alice's
+repository (or vice-versa). ::
+
+  $ hg pull ../alice
+  [...]
+  added 1 changesets with 1 changes to 2 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  2 new divergent changesets
+
+Figure 9 shows the situation in Bob's repository.
+
+  [figure SG09: Bob's repo with 2 heads for the 2 divergent changesets, 6:a360 and 7:e3f9; wc is at 6:a360; both are successors of obsolete 4:2fe6, hence divergence]
+
+Now we need to get out of trouble. As usual, the answer is to evolve
+history. ::
+
+  $ HGMERGE=internal:other hg evolve
+  merge:[6] fix bug 24 (v2 by bob)
+  with: [7] fix bug 24 (v2 by alice)
+  base: [4] fix bug 24 (v1)
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+
+Figure 10 shows how Bob's repository looks now.
+
+  [figure SG10: only one visible head, 9:5ad6, successor to hidden 6:a360 and 7:e3f9]
+
+We carefully dodged a merge conflict by specifying a merge tool
+(``internal:other``) that will take Alice's changes over Bob's. (You
+might wonder why Bob wouldn't prefer his own changes by using
+``internal:local``. He's avoiding a `bug`_ in ``evolve`` that occurs
+when evolving divergent changesets using ``internal:local``.)
+
+.. _`bug`: https://bitbucket.org/marmoute/mutable-history/issue/48/
+
+** STOP HERE: WORK IN PROGRESS **
+
+Bumped changesets: only one gets on the plane
+=============================================
+
+If two people show up at the airport with tickets for the same seat on
+the same plane, only one of them gets on the plane. The would-be
+traveller left behind in the airport terminal is said to have been
+*bumped*.
+
+Similarly, if Alice and Bob are collaborating on some mutable
+changesets, it's possible to get into a situation where an otherwise
+worthwhile changeset cannot be pushed to the public repository; it is
+bumped by an alternative changeset that happened to get there first.
+Let's demonstrate one way this could happen.
+
+It starts with Alice committing a bug fix. Right now, we don't yet
+know if this bug fix is good enough to push to the public repository,
+but it's good enough for Alice to commit. ::
+
+  $ cd alice
+  $ echo 'fix' > file2
+  $ hg commit -A -m 'fix bug 15'
+  adding file2
+
+Now Bob has a bad idea: he decides to pull whatever Alice is working
+on and tweak her bug fix to his taste::
+
+  $ cd ../bob
+  $ hg pull -u ../alice
+  [...]
+  added 1 changesets with 1 changes to 1 files
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 'Fix.' > file2
+  $ hg amend -A -m 'fix bug 15 (amended)'
+
+(Note the lack of communication between Alice and Bob. Failing to
+communicate with your colleagues is a good way to get into trouble.
+Nevertheless, ``evolve`` can usually sort things out, as we will see.)
+
+  [figure SG06: Bob's repo with one amendment]
+
+After some testing, Alice realizes her bug fix is just fine as it is:
+no need for further polishing and amending, this changeset is ready to
+publish. ::
+
+  $ cd ../alice
+  $ hg push
+  [...]
+  added 1 changesets with 1 changes to 1 files
+
+This introduces a contradiction: in Bob's repository, changeset 2:e011
+(his copy of Alice's fix) is obsolete, since Bob amended it. But in
+Alice's repository (and ``public``), that changeset is public: it is
+immutable, carved in stone for all eternity. No changeset can be both
+obsolete and public, so Bob is in for a surprise the next time he
+pulls from ``public``::
+
+  $ cd ../bob
+  $ hg pull -q -u
+  1 new bumped changesets
+
+Figure 7 shows what just happened to Bob's repository: changeset
+2:e011 is now public, so it can't be obsolete. When that changeset was
+obsolete, it made perfect sense for it to have a successor, namely
+Bob's amendment of Alice's fix (changeset 4:fe88). But it's illogical
+for a public changeset to have a successor, so 4:fe88 is in trouble:
+it has been *bumped*.
+
+  [figure SG07: 2:e011 now public not obsolete, 4:fe88 now bumped]
+
+As usual when there's trouble in your repository, the solution is to
+evolve it::
+
+  $ hg evolve --all
+
+Figure 8 illustrate's Bob's repository after evolving away the bumped
+changeset. Ignoring the obsolete changesets, Bob now has a nice,
+clean, simple history. His amendment of Alice's bug fix lives on, as
+changeset 5:227d—albeit with a software-generated commit message. (Bob
+should probably amend that changeset to improve the commit message.)
+But the important thing is that his repository no longer has any
+troubled changesets, thanks to ``evolve``.
+
+  [figure SG08: 5:227d is new, formerly bumped changeset 4:fe88 now hidden]
+
+Conclusion
+----------
+
+Mutable history is a powerful tool. Like a sharp knife, an experienced
+user can do wonderful things with it, much more wonderful than with a
+dull knife (never mind a rusty spoon). At the same time, an
+inattentive or careless user can do harm to himself or others.
+Mercurial with ``evolve`` goes to great lengths to limit the harm you
+can do by trying to handle all possible types of “troubled”
+changesets. But having a first-aid kit nearby does not excuse you from
+being careful with sharp knives.
+
+Mutable history shared across multiple repositories by a single
+developer is a natural extension of this model. Once you are used to
+using a single sharp knife on its own, it's pretty straightforward to
+chop onions and mushrooms using the same knife, or to alternate
+between two chopping boards with different knives.
+
+Mutable history shared by multiple developers is a scary place to go.
+Imagine a professional kitchen full of expert chefs tossing their
+favourite knives back and forth, with the occasional axe or chainsaw
+thrown in to spice things up. If you're confident that you *and your
+colleagues* can do it without losing a limb, go for it. But be sure to
+practice a lot first before you rely on it!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/static/logo-evolve.svg	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,622 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="100"
+   height="100"
+   viewBox="0 0 124.766 126.74917"
+   id="Layer_1"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="logo-evolve.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   style="display:inline"><metadata
+   id="metadata6845"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title><dc:creator><cc:Agent><dc:title>Cali Mastny and Matt Mackall</dc:title></cc:Agent></dc:creator><cc:license
+         rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /><dc:date>Feb 12 2008</dc:date></cc:Work><cc:License
+       rdf:about="http://creativecommons.org/licenses/GPL/2.0/"><cc:permits
+         rdf:resource="http://web.resource.org/cc/Reproduction" /><cc:permits
+         rdf:resource="http://web.resource.org/cc/Distribution" /><cc:requires
+         rdf:resource="http://web.resource.org/cc/Notice" /><cc:permits
+         rdf:resource="http://web.resource.org/cc/DerivativeWorks" /><cc:requires
+         rdf:resource="http://web.resource.org/cc/ShareAlike" /><cc:requires
+         rdf:resource="http://web.resource.org/cc/SourceCode" /></cc:License></rdf:RDF></metadata><sodipodi:namedview
+   inkscape:window-height="1165"
+   inkscape:window-width="1918"
+   inkscape:pageshadow="2"
+   inkscape:pageopacity="0.0"
+   guidetolerance="10.0"
+   gridtolerance="10.0"
+   objecttolerance="10.0"
+   borderopacity="1.0"
+   bordercolor="#666666"
+   pagecolor="#ffffff"
+   id="base"
+   inkscape:zoom="5.4093668"
+   inkscape:cx="86.89449"
+   inkscape:cy="46.517129"
+   inkscape:window-x="0"
+   inkscape:window-y="0"
+   inkscape:current-layer="Layer_1"
+   width="100px"
+   height="120px"
+   units="px"
+   showgrid="false"
+   inkscape:window-maximized="0"><sodipodi:guide
+     position="0,0"
+     orientation="0,100"
+     id="guide3006" /><sodipodi:guide
+     position="100,0"
+     orientation="-120,0"
+     id="guide3008" /><sodipodi:guide
+     position="-14.419433,100.19657"
+     orientation="0,-100"
+     id="guide3010" /><sodipodi:guide
+     position="0,142.90028"
+     orientation="120,0"
+     id="guide3012" /></sodipodi:namedview><defs
+   id="defs261"><inkscape:perspective
+     sodipodi:type="inkscape:persp3d"
+     inkscape:vp_x="0 : 60 : 1"
+     inkscape:vp_y="0 : 1000 : 0"
+     inkscape:vp_z="100 : 60 : 1"
+     inkscape:persp3d-origin="50 : 40 : 1"
+     id="perspective146" /></defs>
+<pattern
+   overflow="visible"
+   viewBox="2.125 -70.896 69 69"
+   id="Polka_Dot_Pattern"
+   patternUnits="userSpaceOnUse"
+   height="69"
+   width="69"
+   y="736.415"
+   x="-316">
+	<g
+   id="g4">
+		<polygon
+   id="polygon6"
+   points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896   "
+   fill="none" />
+		<polygon
+   id="polygon8"
+   points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896   "
+   fill="#F7BC60" />
+		<g
+   id="g10">
+			<path
+   id="path12"
+   d="M61.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path14"
+   d="M54.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path16"
+   d="M46.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path18"
+   d="M38.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path20"
+   d="M31.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path22"
+   d="M23.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path24"
+   d="M15.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path26"
+   d="M8.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path28"
+   d="M0.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19C0.361-71.362,0.3-71.4,0.248-71.335     c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+		</g>
+		<g
+   id="g30">
+			<path
+   id="path32"
+   d="M69.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.062-0.165,0.128     c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+		</g>
+		<path
+   id="path34"
+   d="M0.495-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.062-0.165,0.128    c-0.051,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161    c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631    c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45    c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221    c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337    c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207    c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224C0.5-71.68,0.503-71.744,0.51-71.626    c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+		<g
+   id="g36">
+			<g
+   id="g38">
+				<path
+   id="path40"
+   d="M69.439-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path42"
+   d="M61.778-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path44"
+   d="M54.118-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path46"
+   d="M46.458-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path48"
+   d="M38.797-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path50"
+   d="M31.137-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path52"
+   d="M23.477-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path54"
+   d="M15.816-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path56"
+   d="M8.156-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path58"
+   d="M0.495-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143C2-61.45,2.217-61.397,2.391-61.46c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g60">
+				<path
+   id="path62"
+   d="M69.439-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path64"
+   d="M61.778-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path66"
+   d="M54.118-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path68"
+   d="M46.458-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path70"
+   d="M38.797-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path72"
+   d="M31.137-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path74"
+   d="M23.477-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path76"
+   d="M15.816-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path78"
+   d="M8.156-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path80"
+   d="M0.495-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-56.374,0.503-56.438,0.51-56.32      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g82">
+				<path
+   id="path84"
+   d="M69.439-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path86"
+   d="M61.778-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path88"
+   d="M54.118-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path90"
+   d="M46.458-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path92"
+   d="M38.797-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path94"
+   d="M31.137-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path96"
+   d="M23.477-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path98"
+   d="M15.816-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path100"
+   d="M8.156-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path102"
+   d="M0.495-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g104">
+				<path
+   id="path106"
+   d="M69.439-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path108"
+   d="M61.778-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path110"
+   d="M54.118-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path112"
+   d="M46.458-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path114"
+   d="M38.797-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path116"
+   d="M31.137-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path118"
+   d="M23.477-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path120"
+   d="M15.816-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path122"
+   d="M8.156-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      C8.15-41.004,8.149-41.02,8.14-41.04"
+   fill="#FFFFFF" />
+				<path
+   id="path124"
+   d="M0.495-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g126">
+				<path
+   id="path128"
+   d="M69.439-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path130"
+   d="M61.778-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path132"
+   d="M54.118-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path134"
+   d="M46.458-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path136"
+   d="M38.797-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path138"
+   d="M31.137-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path140"
+   d="M23.477-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path142"
+   d="M15.816-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path144"
+   d="M8.156-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path146"
+   d="M0.495-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-33.416,0.503-33.48,0.51-33.362      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g148">
+				<path
+   id="path150"
+   d="M69.439-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path152"
+   d="M61.778-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path154"
+   d="M54.118-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path156"
+   d="M46.458-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path158"
+   d="M38.797-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path160"
+   d="M31.137-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path162"
+   d="M23.477-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path164"
+   d="M15.816-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path166"
+   d="M8.156-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path168"
+   d="M0.495-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g170">
+				<path
+   id="path172"
+   d="M69.439-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path174"
+   d="M61.778-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path176"
+   d="M54.118-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path178"
+   d="M46.458-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path180"
+   d="M38.797-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path182"
+   d="M31.137-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path184"
+   d="M23.477-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path186"
+   d="M15.816-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path188"
+   d="M8.156-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path190"
+   d="M0.495-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-18.11,0.503-18.175,0.51-18.057      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+			<g
+   id="g192">
+				<path
+   id="path194"
+   d="M69.439-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362C69-9.692,69.159-9.523,69.154-9.4c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path196"
+   d="M61.778-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path198"
+   d="M54.118-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path200"
+   d="M46.458-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path202"
+   d="M38.797-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path204"
+   d="M31.137-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path206"
+   d="M23.477-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path208"
+   d="M15.816-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053C17.933-7.969,17.839-8.227,18-8.34      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path210"
+   d="M8.156-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      C7.915-10.05,7.866-9.836,7.886-9.75C7.717-9.692,7.876-9.523,7.871-9.4C7.868-9.351,7.83-9.295,7.826-9.239      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      C9.114-7.652,9.321-7.799,9.48-7.837c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+				<path
+   id="path212"
+   d="M0.495-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128      C0.254-10.05,0.205-9.836,0.225-9.75C0.056-9.692,0.215-9.523,0.21-9.4c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-8.671,0.501-8.456,0.668-8.325c0.19,0.148,0.365,0.572,0.608,0.631      C1.454-7.652,1.66-7.799,1.819-7.837C2-7.88,2.217-7.827,2.391-7.89c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46C3.477-8.933,3.471-8.995,3.5-9.071      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			</g>
+		</g>
+		<g
+   id="g214">
+			<path
+   id="path216"
+   d="M69.439-2.778c0.018,0.072,0.008,0.127-0.026,0.19C69.361-2.487,69.3-2.525,69.248-2.46     c-0.051,0.062-0.099,0.276-0.079,0.362C69-2.04,69.159-1.871,69.154-1.748c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C70.397,0,70.604-0.146,70.763-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path218"
+   d="M61.778-2.778c0.018,0.072,0.007,0.127-0.026,0.19C61.7-2.487,61.64-2.525,61.587-2.46     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C62.737,0,62.943-0.146,63.103-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C61.915-3.117,61.78-3.02,61.781-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path220"
+   d="M54.118-2.778c0.018,0.072,0.007,0.127-0.026,0.19C54.04-2.487,53.98-2.525,53.927-2.46     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C55.077,0,55.283-0.146,55.442-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C54.255-3.117,54.12-3.02,54.121-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path222"
+   d="M46.458-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C47.416,0,47.623-0.146,47.782-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C46.594-3.117,46.459-3.02,46.46-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path224"
+   d="M38.797-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C39.756,0,39.962-0.146,40.122-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C38.934-3.117,38.799-3.02,38.8-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path226"
+   d="M31.137-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C32.095,0,32.302-0.146,32.461-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C31.273-3.117,31.139-3.02,31.14-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path228"
+   d="M23.477-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C24.435,0,24.642-0.146,24.801-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+   fill="#FFFFFF" />
+			<path
+   id="path230"
+   d="M15.816-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.062-0.165,0.128     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C16.774,0,16.981-0.146,17.14-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     C15.81-2.74,15.809-2.756,15.8-2.776"
+   fill="#FFFFFF" />
+			<path
+   id="path232"
+   d="M8.156-2.778c0.018,0.072,0.007,0.127-0.026,0.19C8.077-2.487,8.018-2.525,7.965-2.46     c-0.05,0.062-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35C7.868-1.698,7.83-1.643,7.826-1.587     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C9.114,0,9.321-0.146,9.48-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C8.954-3.54,8.847-3.448,8.692-3.367     c-0.17,0.088-0.139,0.166-0.318,0.224C8.292-3.117,8.158-3.02,8.159-2.92C8.16-2.805,8.164-2.869,8.17-2.751     C8.15-2.74,8.149-2.756,8.14-2.776"
+   fill="#FFFFFF" />
+			<path
+   id="path234"
+   d="M0.495-2.778c0.018,0.072,0.008,0.127-0.026,0.19C0.417-2.487,0.356-2.525,0.304-2.46     C0.253-2.397,0.205-2.184,0.225-2.098C0.056-2.04,0.215-1.871,0.21-1.748c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-1.019,0.501-0.804,0.668-0.673c0.19,0.148,0.365,0.572,0.608,0.631     C1.454,0,1.66-0.146,1.819-0.185C2-0.228,2.217-0.175,2.391-0.237c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46C3.477-1.28,3.471-1.343,3.5-1.419     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C1.293-3.54,1.187-3.448,1.031-3.367     c-0.17,0.088-0.139,0.166-0.318,0.224C0.632-3.117,0.498-3.02,0.498-2.92C0.5-2.805,0.503-2.869,0.51-2.751     C0.489-2.74,0.488-2.756,0.479-2.776"
+   fill="#FFFFFF" />
+		</g>
+	</g>
+</pattern>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<rect
+   style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.83134139;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+   id="rect6847"
+   width="126.74917"
+   height="126.99831"
+   x="-0.99158502"
+   y="-0.24915084" /><g
+   id="g2996"
+   transform="matrix(0.46679402,-0.88436607,0.88436607,0.46679402,-20.509268,97.149298)"><path
+     d="M 107.61309,85.427163 C 126.35316,54.267748 103.65523,3.7316784 62.152514,8.8657974 24.653999,13.501508 24.049791,52.97069 57.097677,62.347028 c 28.598853,8.121324 5.908299,26.261404 6.571301,38.341302 0.665797,12.07808 24.862369,16.46007 43.944112,-15.261167 z"
+     style="fill:#1b1a1b"
+     id="path2339" /><path
+     d="M 108.32072,84.162974 C 127.06181,53.003291 104.36388,2.4672218 62.861165,7.6013402 25.362652,12.23705 24.757687,51.707522 57.805574,61.083859 c 28.598853,8.121324 5.908299,26.261404 6.571569,38.342322 0.666551,12.076789 24.861834,16.458029 43.943577,-15.263207 z"
+     style="fill:#bfbfbf"
+     id="path2561" /><path
+     d="m 69.186033,104.19365 c -1.135692,-1.84204 0.601038,-3.88837 2.386188,-3.73277 2.841598,0.24886 9.028642,-0.0333 13.910588,-2.800482 C 97.6794,90.746293 116.44888,57.478025 107.00882,36.495137 102.78257,27.102283 100.72467,24.412915 96.372318,19.81831 c -0.887874,-0.937057 -0.378162,-0.886124 0.223066,-0.568957 2.353599,1.235189 6.489446,6.019569 10.731716,13.806724 7.16765,13.156791 6.79595,28.797842 4.13015,38.609442 -1.85691,6.825577 -8.25281,22.266533 -17.619587,28.942751 -9.387853,6.69156 -20.372606,10.52943 -24.65163,3.58538 z"
+     style="fill:#000000"
+     id="path2563" /><path
+     d="M 60.687485,61.019981 C 54.297665,59.123186 46.06011,56.4817 41.295423,50.249529 c -3.51248,-4.595193 -5.295582,-9.610385 -5.750944,-12.454176 -0.162003,-1.014713 -0.299617,-1.861261 -0.0075,-2.094878 0.135238,-0.108497 2.622869,5.514283 6.341685,10.226737 3.718069,4.713742 8.914807,7.470526 13.24405,8.472162 3.850608,0.890203 11.826899,2.846243 14.525556,5.145317 2.77437,2.363257 3.005946,7.469336 2.072352,8.045384 C 70.779125,68.169283 68.87,63.447817 60.687289,61.019981 z"
+     style="fill:#000000"
+     id="path2565" /><path
+     d="m 73.863069,105.09442 c -0.123332,1.46251 1.556525,1.74932 3.817708,1.41046 2.898288,-0.43471 5.349293,-0.76107 8.685191,-2.43293 4.521182,-2.2658 9.09685,-5.506989 12.447924,-9.879632 9.998228,-13.044622 13.538728,-28.478823 12.993498,-30.69907 -0.1822,1.833569 -2.59588,11.458073 -8.11589,20.134991 -7.089521,11.145311 -12.230531,17.081841 -24.087282,19.959951 -3.299704,0.80164 -5.579675,-0.41901 -5.741149,1.50623 z"
+     style="fill:#ffffff"
+     id="path2567" /><path
+     d="m 47.56572,54.369317 c 1.350435,1.145429 4.117343,2.671707 9.561614,4.457113 6.575462,2.155844 9.776981,4.025449 11.117744,4.921402 1.420732,0.951385 2.321212,3.074269 2.41017,1.188742 0.09277,-1.887616 -1.070702,-3.510729 -3.66667,-4.37155 -1.756347,-0.583153 -4.7109,-1.97194 -7.543128,-2.530905 -1.819913,-0.359233 -4.780811,-1.072155 -7.320051,-1.849642 -1.391646,-0.427711 -2.809634,-1.1769 -4.559679,-1.81516 z"
+     style="fill:#ffffff"
+     id="path2569" /><path
+     d="M 105.72614,63.921199 C 113.7054,40.922252 97.007933,6.1896881 63.228641,10.367773 32.706856,14.141463 32.214677,46.266552 59.113519,53.899069 89.582156,58.51118 71.235202,81.495802 68.632602,93.086552 66.299323,103.47658 93.255777,105.18656 105.72614,63.921199 z"
+     style="fill:#999999"
+     id="path2561_1_" /><path
+     d="m 84.848561,81.885586 c -8.254188,-1.021445 -20.13245,17.614405 -8.932534,15.431899 11.198141,-2.180945 -11.199916,2.182506 0,0 5.383182,-0.798314 9.842872,-2.698914 13.835192,-7.255788 5.205477,-5.940314 12.981581,-18.771954 15.230561,-27.062759 1.89451,-6.990334 0.94225,-17.820653 -1.01071,-7.64474 -2.00298,10.4432 -10.868321,27.552835 -19.122509,26.531388 z"
+     style="fill:#f3f3f3"
+     id="path2571" /></g>
+<text
+   xml:space="preserve"
+   style="font-size:35.48976898px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Balker;-inkscape-font-specification:Balker"
+   x="16.816299"
+   y="109.87854"
+   id="text3014"
+   sodipodi:linespacing="125%"><tspan
+     sodipodi:role="line"
+     id="tspan3018"
+     x="16.816299"
+     y="109.87854">evolve</tspan></text>
+<g
+   id="g2988"
+   transform="matrix(0.74328759,-0.66897202,0.66897202,0.74328759,8.9028358,75.473986)"><path
+     d="M 19.418398,44.509742 C 13.566506,45.076202 9.2828039,50.274467 9.8492604,56.126357 10.416792,61.982332 15.614839,66.269362 21.46775,65.702634 27.31879,65.12876 31.606084,59.931735 31.037317,54.079359 30.468598,48.231333 25.271308,43.943014 19.418398,44.509742 z"
+     style="fill:#1b1a1b"
+     id="path2343" /><path
+     d="M 20.127041,43.245285 C 14.275159,43.811746 9.9914567,49.01001 10.557913,54.8619 c 0.567261,5.854953 5.765579,10.143005 11.61747,9.576545 5.85206,-0.574142 10.139092,-5.772187 9.569297,-11.624297 -0.567701,-5.848293 -5.764728,-10.13559 -11.617639,-9.568863 z"
+     style="fill:#bfbfbf"
+     id="path2589" /><path
+     d="m 15.297614,61.936273 c 0.0649,0.752128 1.095012,1.718382 2.713381,2.162016 1.390355,0.381136 4.974531,1.355379 9.578993,-1.550784 4.604462,-2.906163 5.135393,-10.679565 3.042277,-12.965884 -0.647907,-1.158064 -1.490462,-2.001165 -0.820074,-0.152965 1.692982,4.666774 -1.596739,9.032083 -4.434212,11.053479 -2.836454,2.021128 -6.433853,1.064641 -7.902778,0.616794 -1.468915,-0.447847 -2.243523,0.0604 -2.177587,0.837344 z"
+     style="fill:#000000"
+     id="path2591" /><path
+     d="m 21.239503,62.980483 c 0.422006,-0.379939 2.558364,-0.22464 4.487234,-1.261971 1.92785,-1.037065 4.219346,-3.310451 4.628251,-6.540865 0.240881,-1.896934 0.313223,-1.420583 0.409121,-0.387475 -0.299215,5.370492 -5.238089,8.336927 -8.06262,8.72834 -0.76217,0.105705 -2.103468,0.04118 -1.461986,-0.538029 z"
+     style="fill:#ffffff"
+     id="path2597" /><path
+     d="m 12.336171,56.430605 c 0.380898,1.199486 1.354175,2.949646 3.409446,3.241412 2.744512,0.389611 3.30561,1.629622 6.546396,0.986326 3.240786,-0.643297 5.697258,-3.299154 6.680242,-6.23693 1.125385,-4.064906 -0.559668,-6.163496 -3.095682,-8.037135 -2.536005,-1.873639 -8.114707,-1.672161 -11.443975,1.362735 -2.366007,2.155435 -3.02378,5.763265 -2.096427,8.683592 z"
+     style="fill:#999999"
+     id="path2593_2_" /><path
+     d="m 23.114098,59.11873 c 2.490146,-0.651887 5.783458,-4.045016 4.14851,-6.635646 -2.017128,-3.192057 -7.636948,-0.459737 -7.826995,3.094121 -0.190795,3.555146 1.039269,4.232436 3.678485,3.541525 z"
+     style="fill:#f3f3f3"
+     id="path256" /></g></svg>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/test2rst.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+import os, os.path as op, re, sys
+
+# line starts with two chars one of which is not a space (and both are not
+# newlines obviously) and ends with one or more newlines followed by two spaces
+# on a next line (indented text)
+CODEBLOCK = re.compile(r'()\n(([^ \n][^\n]|[^\n][^ \n])[^\n]*)\n+  ')
+
+INDEX = '''
+Mercurial tests
+===============
+
+.. toctree::
+   :maxdepth: 1
+'''
+
+
+def rstify(orig, name):
+    header = '%s\n%s\n\n' % (name, '=' * len(name))
+    content = header + orig
+    content = CODEBLOCK.sub(r'\n\1\n\n::\n\n  ', content)
+    return content
+
+
+def main(base):
+    if os.path.isdir(base):
+        one_dir(base)
+    else:
+        one_file(base)
+
+
+def one_dir(base):
+    index = INDEX
+    #doc = lambda x: op.join(op.dirname(__file__), 'docs', x)
+
+    for fn in sorted(os.listdir(base)):
+        if not fn.endswith('.t'):
+            continue
+        name = os.path.splitext(fn)[0]
+        content = one_file(op.join(base, fn))
+        target = op.join(base, name + '.rst')
+        #with file(doc(name + '.rst'), 'w') as f:
+        with file(target, 'w') as f:
+            f.write(content)
+
+        index += '\n   ' + name
+
+    #with file(doc('index.rst'), 'w') as f:
+    #    f.write(index)
+
+
+def one_file(path):
+    name = os.path.basename(path)[:-2]
+    return rstify(file(path).read(), name)
+
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print 'Please supply a path to tests dir as parameter'
+        sys.exit()
+    main(sys.argv[1])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/tutorials/tutorial.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,1 @@
+../../tests/test-tutorial.t
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/user-guide.rst	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,601 @@
+.. Copyright © 2014 Greg Ward <greg@gerg.ca>
+
+------------------
+Evolve: User Guide
+------------------
+
+.. contents::
+
+Life without ``evolve``
+-----------------------
+
+Before we dive into learning about ``evolve``, let's look into some
+features of core Mercurial that interact with ``evolve``. ``commit``
+affects ``evolve``, and ``evolve`` modifies how ``commit --amend``
+works.
+
+Example 1: Commit a new changeset
+=================================
+
+To create a new changeset, simply run ``hg commit`` as usual.
+``evolve`` does not change the behaviour of ``commit`` at all.
+
+However, it's important to understand that new changesets are in the
+*draft* phase by default: they are mutable. This means that they can
+be modified by Mercurial's existing history-editing commands
+(``rebase``, ``histedit``, etc.), and also by the ``evolve``
+extension. Specifically, ``evolve`` adds a number of commands that can
+be used to modify history: ``amend``, ``uncommit``, ``prune``,
+``fold``, and ``evolve``. Generally speaking, changesets remain in
+*draft* phase until they are pushed to another repository, at which
+point they enter *public* phase. ::
+
+  $ hg commit -m 'implement feature X'
+  $ hg phase -r .
+  1: draft
+
+(Strictly speaking, changesets only become public when they are pushed
+to a *publishing* repository. But all repositories are publishing by
+default; you have to explicitly configure repositories to be
+*non-publishing*. Non-publishing repositories are an advanced topic
+which we'll see when we get to `sharing mutable history`_.)
+
+.. _`sharing mutable history`: sharing.html
+
+Example 2: Amend a changeset (traditional)
+==========================================
+
+Imagine you've just committed a new changeset, and then you discover a
+mistake. Maybe you forgot to run the tests and a failure slipped in.
+You want to modify history so that you push one perfect changeset,
+rather than one flawed changeset followed by an "oops" commit. (Or
+perhaps you made a typo in the commit message—this is really feature
+*Y*, not feature X. You can't fix that with a followup commit.)
+
+This is actually trivial with plain vanilla Mercurial since 2.2: fix
+your mistake and run ::
+
+  $ hg commit --amend -m 'implement feature Y'
+
+to create a new, amended changeset. The drawback of doing this with
+vanilla Mercurial is that your original, flawed, changeset is removed
+from the repository. This is *unsafe* history editing. It's probably
+not too serious if all you did was fix a syntax error, but still.
+
+.. figure:: figures/figure-ug01.svg
+
+   Figure 1: unsafe history modification with core Mercurial (not
+   using ``evolve``): the original revision 1 is destroyed.
+
+(Incidentally, Mercurial's traditional history modification mechanism
+isn't *really* unsafe: any changeset(s) removed from the repository
+are kept in a backup directory, so you can manually restore them later
+if you change your mind. But it's awkward and inconvenient compared to
+the features provided by ``evolve`` and changeset obsolescence.)
+
+Life with ``evolve`` (basic usage)
+----------------------------------
+
+Once you enable the ``evolve`` extension, a number of features are
+available to you. First, we're going to explore several examples of
+painless, trouble-free history modification.
+
+Example 3: Amend a changeset (with ``evolve``)
+==============================================
+
+Outwardly, amending a changeset with ``evolve`` can look exactly the
+same as it does with core Mercurial (example 2)::
+
+  $ hg commit --amend -m 'implement feature Y'
+
+Alternately, you can use the new ``amend`` command added by
+``evolve``::
+
+  $ hg amend -m 'implement feature Y'
+
+(``hg amend`` is nearly synonymous with ``hg commit --amend``. The
+difference is that ``hg amend`` reuses the existing commit message by
+default, whereas ``hg commit --amend`` runs your editor if you don't
+pass ``-m`` or ``-l``.)
+
+Under the hood, though, things are quite different. Mercurial has
+simply marked the old changeset *obsolete*, replacing it with a new
+one. We'll explore what this means in detail later, after working
+through a few more examples.
+
+Example 4: Prune an unwanted changeset
+======================================
+
+Sometimes you make a change, and then decide it was such a bad idea
+that you don't want anyone to know about it. Or maybe it was a
+debugging hack that you needed to keep around for a while, but do not
+intend to ever push publicly. ::
+
+  $ echo 'debug hack' >> file1.c
+  $ hg commit -m 'debug hack'
+
+In either case, ``hg prune`` is the answer. ``prune`` simply marks
+changesets obsolete without creating any new changesets to replace
+them::
+
+  $ hg prune .
+  1 changesets pruned
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory now at 934359450037
+
+Outwardly, it appears that your “debug hack” commit never happened;
+we're right back where we started::
+
+  $ hg parents --template '{rev}:{node|short}  {desc|firstline}\n'
+  3:934359450037  implement feature Y
+
+In reality, though, the “debug hack” is still there, obsolete and hidden.
+
+Example 5: Uncommit changes to certain files
+============================================
+
+Occasionally you commit more than you intended: perhaps you made
+unrelated changes to different files, and thus intend to commit
+different files separately. ::
+
+  $ echo 'relevant' >> file1.c
+  $ echo 'irrelevant' >> file2.c
+
+If you forget to specify filenames on the ``commit`` command line,
+Mercurial commits all those changes together::
+
+  $ hg commit -m 'fix bug 234'          # oops: too many files
+
+Luckily, this mistake is easy to fix with ``uncommit``::
+
+  $ hg uncommit file2.c
+  $ hg status
+  M file2.c
+
+Let's verify that the replacement changeset looks right (i.e.,
+modifies only ``file1.c``)::
+
+  $ hg parents --template '{rev}:{node|short}  {desc|firstline}\n{files}\n'
+  6:c8defeecf7a4  fix bug 234
+  file1.c
+
+As before, the original flawed changeset is still there, but obsolete
+and hidden. It won't be exchanged with other repositories by ``push``,
+``pull``, or ``clone``.
+
+Example 6: Fold multiple changesets together into one
+=====================================================
+
+If you're making extensive changes to fragile source code, you might
+commit more frequently than normal so that you can fallback on a
+known good state if one step goes badly. ::
+
+  $ echo step1 >> file1.c
+  $ hg commit -m 'step 1'               # revision 7
+  $ echo step2 >> file1.c
+  $ hg commit -m 'step 2'               # revision 8
+  $ echo step3 >> file2.c
+  $ hg commit -m 'step 3'               # revision 9
+
+At the end of such a sequence, you often end up with a series of small
+changesets that are tedious to review individually. It might make more
+sense to combine them into a single changeset using the ``fold``
+command.
+
+To make sure we pass the right revisions to ``fold``, let's review the
+changesets we just created, from revision 7::
+
+  $ hg log --template '{rev}:{node|short}  {desc|firstline}\n' -r 7::
+  7:05e61aab8294  step 1
+  8:be6d5bc8e4cc  step 2
+  9:35f432d9f7c1  step 3
+
+and fold them::
+
+  $ hg fold -m 'fix bug 64' -r 7::
+  3 changesets folded
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+This time, Mercurial marks three changesets obsolete, replacing them
+all with a single *successor*.
+
+(You might be familiar with this operation under other names, like
+*squash* or *collapse*.)
+
+Changeset obsolescence under the hood
+-------------------------------------
+
+So far, everything has gone just fine: we haven't run into merge
+conflicts or other trouble. Before we start exploring advanced usage
+that can run into trouble, let's step back and see what happens when
+Mercurial marks changesets obsolete. That will make it much easier to
+understand the more advanced use cases we'll see later.
+
+When you have the ``evolve`` extension enabled, all history
+modification uses the same underlying mechanism: the original
+changesets are marked *obsolete* and replaced by zero or more
+*successors*. The obsolete changesets are the *precursors* of their
+successors. This applies equally to built-in commands (``commit
+--amend``), commands added by ``evolve`` (``amend``, ``prune``,
+``uncommit``, ``fold``), and commands provided by other extensions
+(``rebase``, ``histedit``).
+
+Another way of looking at it is that obsolescence is second-order
+version control, i.e. the history of your history. We'll cover this in
+more detail (and mathematical precision) in the `concepts`_ guide.
+
+.. _`concepts`: concepts.html
+
+Under the hood: Amend a changeset
+=================================
+
+Consider Example 2, amending a changeset with ``evolve``. We saw above
+that you can do this using the exact same command-line syntax as core
+Mercurial, namely ``hg commit --amend``. But the implementation is
+quite different, and Figure 2 shows how.
+
+.. figure:: figures/figure-ug02.svg
+
+   Figure 2: safe history modification using ``evolve``: the original
+   revision 1 is preserved as an obsolete changeset. (The "temporary
+   amend commit", marked with T, is an implementation detail stemming
+   from limitations in Mercurial's current merge machinery. Future
+   versions of Mercurial will not create them.)
+
+In this case, the obsolete changesets are also *hidden*. That is the
+usual end state for obsolete changesets. But many scenarios result in
+obsolete changesets that are still visible, which indicates your
+history modification work is not yet done. We'll see examples of that
+later, when we cover advanced usage.
+
+
+Understanding revision numbers and hidden changesets
+====================================================
+
+As the name implies, hidden changesets are normally not visible. If
+you run ``hg log`` on the repository from Figure 2, Mercurial will
+show revisions 0 and 3, but not 1 and 2. That's something you don't
+see with plain vanilla Mercurial—normally, revision *N* is always
+followed by revision *N* + 1.
+
+This is just the visible manifestation of hidden changesets. If
+revision 0 is followed by revision 3, that means there are two hidden
+changesets, 1 and 2, in between.
+
+To see those hidden changesets, use the ``--hidden`` option::
+
+  $ hg --hidden log --graph --template '{rev}:{node|short}  {desc|firstline}\n'
+  @  3:934359450037  implement feature Y
+  |
+  | x  2:6c5f78d5d467  temporary amend commit for fe0ecd3bd2a4
+  | |
+  | x  1:fe0ecd3bd2a4  implement feature Y
+  |/
+  o  0:08c4b6f4efc8  init
+
+Note that changeset IDs are still the permanent, immutable identifier
+for changesets. Revision numbers are, as ever, a handy shorthand that
+work in your local repository, but cannot be used across repositories.
+They also have the useful property of showing when there are hidden
+changesets lurking under the covers, which is why this document uses
+revision numbers.
+
+
+Under the hood: Prune an unwanted changeset
+===========================================
+
+``prune`` (example 4 above) is the simplest history modification
+command provided by ``evolve``. All it does is mark the specified
+changeset(s) obsolete, with no successor/precursor relationships
+involved. (If the working directory parent was one of the obsolete
+changesets, ``prune`` updates back to a suitable ancestor.)
+
+.. figure:: figures/figure-ug03.svg
+
+   Figure 3: pruning a changeset marks it obsolete with no successors.
+
+Under the hood: Uncommit changes to certain files
+=================================================
+
+In one sense, ``uncommit`` is a simplified version of ``amend``. Like
+``amend``, it obsoletes one changeset and leaves it with a single
+successor. Unlike ``amend``, there is no ugly "temporary amend commit"
+cluttering up the repository.
+
+In another sense, ``uncommit`` is the inverse of ``amend``: ``amend``
+takes any uncommitted changes in the working dir and “adds”
+them to the working directory's parent changeset. (In reality, of
+course, it creates a successor changeset, marking the original
+obsolete.) In contrast, ``uncommit`` takes some changes in the working
+directory's parent and moves them to the working dir, creating a new
+successor changeset in the process. Figure 4 illustrates.
+
+.. figure:: figures/figure-ug04.svg
+
+   Figure 4: uncommit moves some of the changes from the working
+   directory parent into the working dir, preserving the remaining
+   changes as a new successor changeset. (N.B. revision 4 is not shown
+   here because it was marked obsolete in the previous example.)
+
+
+Under the hood: Fold multiple changesets together into one
+==========================================================
+
+The last basic example is folding multiple changesets into one, which
+marks multiple changesets obsolete, replacing them all with a single
+successor.
+
+.. figure:: figures/figure-ug05.svg
+
+   Figure 5: fold combines multiple changesets into a single
+   successor, marking the original (folded) changesets obsolete.
+
+
+Obsolete is not hidden
+======================
+
+So far, every obsolete changeset we have seen is also hidden. However,
+these are *not* the same thing—that's why they have different names.
+It's entirely possible to have obsolete changesets that are not
+hidden. We'll see examples of that soon, when we create *unstable*
+changesets.
+
+Note that all hidden changesets are obsolete: hidden is a subset of
+obsolete.
+
+
+Life with ``evolve`` (advanced usage)
+-------------------------------------
+
+Now that you've got a solid understanding of how ``evolve`` works in
+concert with changeset obsolescence, let's explore some more advanced
+scenarios. All of these scenarios will involve *unstable* changesets,
+which is an unavoidable consequence of obsolescence. What really sets
+``evolve`` apart from other history modification mechanisms is the
+fact that it recognizes troubles like unstable changesets and provides
+a consistent way for you to get out of trouble.
+
+(Incidentally, there are two other types of trouble that changesets
+can get into with ``evolve``: they may be *divergent* or *bumped*.
+Both of those states are more likely to occur when `sharing mutable
+history`_, so we won't see them in this user guide.)
+
+.. _`sharing mutable history`: sharing.html
+
+
+Example 7: Amend an older changeset
+===================================
+
+Sometimes you don't notice your mistakes until after you have
+committed new changesets on top of them. ::
+
+  $ hg commit -m 'fix bug 17'         # rev 11 (mistake here)
+  $ hg commit -m 'cleanup'            # rev 12
+  $ hg commit -m 'feature 23'         # rev 13
+
+Traditionally, your only option is to commit an "oops" changeset that
+fixes your mistake. That works, of course, but it makes you look bad:
+you made a mistake, and the record of that mistake is recorded in
+history for all eternity. (If the mistake was in the commit message,
+too bad: you cannot fix it.)
+
+More subtly, there now exist changesets that are *worse* than what
+came before—the code no longer builds, the tests don't pass, or
+similar. Anyone reviewing these patches will waste time on the error
+in the earlier patch, and then the correction later on.
+
+You can avoid all this by amending the bad changeset and *evolving*
+subsequent history. Here's how it works, assuming you have just
+committed revision 13 and noticed the mistake in revision 11::
+
+  $ hg update 11
+  [...fix mistake...]
+  $ hg amend
+
+At this point, revision 11 is *obsolete* and revisions 12 and 13—the
+descendants of 11—are in a funny state: they are *unstable*.
+
+.. figure:: figures/figure-ug06.svg
+
+   Figure 6: amending a changeset with descendants means the amended
+   changeset is obsolete but remains visible; its non-obsolete
+   descendants are *unstable*. The temporary amend commit, revision
+   14, is hidden because it has no non-obsolete descendants.
+
+All non-obsolete descendants of an obsolete changeset are unstable. An
+interesting consequence of this is that revision 11 is still visible,
+even though it is obsolete. Obsolete changesets with non-obsolete
+descendants are not hidden.
+
+The fix is to *evolve* history::
+
+  $ hg evolve --all
+
+This is a separate step, not automatically part of ``hg amend``,
+because there might be conflicts. If your amended changeset modifies a
+file that one of its descendants also modified, Mercurial has to fire
+up your merge tool to resolve the conflict. More importantly, you have
+to switch contexts from "writing code" to "resolving conflicts". That
+can be an expensive context switch, so Mercurial lets you decide when
+to do it.
+
+The end state, after ``evolve`` finishes, is that the original
+revisions (11-13) are obsolete and hidden. Their successor revisions
+(15-17) replace them.
+
+.. figure:: figures/figure-ug07.svg
+
+   Figure 7: evolve your repository (``hg evolve --all``) to take care
+   of instability. Unstable changesets become obsolete, and are
+   replaced by successors just like the amended changeset was.
+
+Example 8: Prune an older changeset
+===================================
+
+Let's say you've just committed the following changesets::
+
+  $ hg commit -m 'useful work'       # rev 18
+  $ hg commit -m 'debug hack'        # rev 19
+  $ hg commit -m 'more work'         # rev 20
+
+You want to drop revision 19, but keep 18 and 20. No problem::
+
+  $ hg prune 19
+  1 changesets pruned
+  1 new unstable changesets
+
+As above, this leaves your repository in a funny intermediate state:
+revision 20 is the non-obsolete descendant of obsolete revision 19.
+That is, revision 20 is unstable.
+
+.. figure:: figures/figure-ug08.svg
+
+   Figure 8: ``hg prune`` marks a changeset obsolete without creating
+   a successor. Just like with ``hg amend``, non-obsolete descendants
+   of the pruned changeset are now unstable.
+
+As before, the solution to unstable changesets is to evolve your
+repository::
+
+  $ hg evolve --all
+
+This rebases revision 20 on top of 18 as the new revision 21, leaving
+19 and 20 obsolete and hidden:
+
+.. figure:: figures/figure-ug09.svg
+
+   Figure 9: once again, ``hg evolve --all`` takes care of instability.
+
+Example 9: Uncommit files from an older changeset (discard changes)
+=======================================================================
+
+As in example 5, let's say you accidentally commit some unrelated
+changes together. Unlike example 5, you don't notice your mistake
+immediately, but commit a new changeset on top of the bad one. ::
+
+  $ echo 'this fixes bug 53' >> file1.c
+  $ echo 'debug hack' >> file2.c
+  $ hg commit -m 'fix bug 53'                     # rev 22 (oops)
+  $ echo 'and this handles bug 67' >> file1.c
+  $ hg commit -m 'fix bug 67'                     # rev 23 (fine)
+
+As with ``amend``, you need to travel back in time and repair revision
+22, leaving your changes to ``file2.c`` back in the working
+directory::
+
+  $ hg update 22
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg uncommit file2.c
+  1 new unstable changesets
+  $ hg status
+  M file2.c
+
+Now your repository has unstable changesets, so you need to evolve it.
+But ``hg evolve`` requires a clean working directory to resolve merge
+conflicts, so you need to decide what to do with ``file2.c``.
+
+In this case, the change to ``file2.c`` was a temporary debugging
+hack, so we can discard it and immediately evolve the instability away::
+
+  $ hg revert file2.c
+  $ hg evolve --all
+  move:[23] fix bug 67
+  atop:[24] fix bug 53
+
+Figure 10 illustrates the whole process.
+
+.. figure:: figures/figure-ug10.svg
+
+   Figure 10: ``hg uncommit`` of a changeset with descendants results
+   in instability *and* a dirty working directory, both of which must
+   be dealt with.
+
+
+Example 10: Uncommit files to an older changeset (keep changes)
+===================================================================
+
+This is very similar to example 9. The difference that this time, our
+change to ``file2.c`` is valuable enough to commit, making things a
+bit more complicated. The setup is nearly identical::
+
+  $ echo 'fix a bug' >> file1.c
+  $ echo 'useful but unrelated' >> file2.c
+  $ hg commit -u dan -d '11 0' -m 'fix a bug'     # rev 26 (oops)
+  $ echo 'new feature' >> file1.c
+  $ hg commit -u dan -d '12 0' -m 'new feature'   # rev 27 (fine)
+
+As before, we update back to the flawed changeset (this time,
+revision 26) and ``uncommit``, leaving uncommitted changes to
+``file2.c`` in the working dir::
+
+  $ hg update -q 26
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg uncommit -q file2.c                        # obsoletes rev 26, creates rev 28
+  1 new unstable changesets
+  $ hg status
+  M file2.c
+
+This time, let's save that useful change before evolving::
+
+  $ hg commit -m 'useful tweak'                   # rev 29
+
+Figure 11 shows the story so far: ``uncommit`` obsoleted revision 26
+and created revision 28, the successor of 26. Then we committed
+revision 29, a child of 28. We still have to deal with the unstable
+revision 27.
+
+.. figure:: figures/figure-ug11.svg
+
+   Figure 11: Uncommitting a file and then committing that change
+   separately will soon result in a two-headed repository.
+
+This is where things get tricky. As usual when a repository has
+unstable changesets, we want to evolve it::
+
+  $ hg evolve --all
+
+The problem is that ``hg evolve`` rebases revision 27 onto revision
+28, creating 30 (the successor of 27). This is entirely logical: 27
+was the child of 26, and 26's successor is 28. So of course 27's
+successor (30) should be the child of 26's successor (28).
+Unfortunately, that leaves us with a two-headed repository:
+
+.. figure:: figures/figure-ug12.svg
+
+   Figure 12: ``evolve`` takes care of unstable changesets; it does
+   not solve all the world's problems.
+
+As usual when faced with a two-headed repository, you can either merge
+or rebase. It's up to you.
+
+
+Example 11: Recover an obsolete changeset
+=========================================
+
+Sometimes you might obsolete a changeset, and then change your mind. You'll
+probably start looking for an “unobsolete” command to restore a changeset
+to normal state. For complicated implementation reasons, that command
+doesn't exist. (If you have already pushed an obsolescence marker to
+another repo, then Mercurial would need a way to revoke that remote
+obsolesence marker. That's a hard problem.)
+
+Instead, ``evolve`` provides a ``touch`` command to resurrect an
+obsolete changeset. An unexpected quirk: you almost certainly need to
+use ``--hidden``, since obsolete changesets tend to be hidden, and you
+can't reference a hidden changeset otherwise. Typical usage thus looks
+like ::
+
+  $ hg --hidden touch REV
+
+This creates a new, normal changeset which is the same as ``REV``—except
+with a different changeset ID. The new changeset will have the same parent
+as ``REV``, and will be a successor of ``REV``.
+
+The current implementation of ``hg touch`` is not ideal, and is likely to
+change in the future. Consider the history in Figure 12, where revision 27
+is obsolete and the child of 26, also obsolete. If we ``hg touch 27``, that
+creates a new revision which is a non-obsolete child of 26—i.e., it is
+unstable. It's also *divergent*, another type of trouble that we'll learn
+about in the `next section`_.
+
+.. _`next section`: sharing.html
--- a/hgext3rd/__init__.py	Thu Feb 23 15:19:31 2017 +0100
+++ b/hgext3rd/__init__.py	Thu Mar 02 18:07:46 2017 +0100
@@ -1,3 +1,4 @@
+# name space package to host third party extensions
 from __future__ import absolute_import
 import pkgutil
 __path__ = pkgutil.extend_path(__path__, __name__)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/__init__.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,3890 @@
+# Copyright 2011 Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
+#                Logilab SA        <contact@logilab.fr>
+#                Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+#                Patrick Mezard <patrick@mezard.eu>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+'''extends Mercurial feature related to Changeset Evolution
+
+This extension provides several commands to mutate history and deal with
+resulting issues.
+
+It also:
+
+    - enables the "Changeset Obsolescence" feature of Mercurial,
+    - alters core commands and extensions that rewrite history to use
+      this feature,
+    - improves some aspect of the early implementation in Mercurial core
+'''
+
+__version__ = '5.6.0'
+testedwith = '3.8.4 3.9.2 4.0.2 4.1'
+
+buglink = 'https://bz.mercurial-scm.org/'
+
+
+evolutionhelptext = """
+Obsolescence markers make it possible to mark changesets that have been
+deleted or superset in a new version of the changeset.
+
+Unlike the previous way of handling such changes, by stripping the old
+changesets from the repository, obsolescence markers can be propagated
+between repositories. This allows for a safe and simple way of exchanging
+mutable history and altering it after the fact. Changeset phases are
+respected, such that only draft and secret changesets can be altered (see
+:hg:`help phases` for details).
+
+Obsolescence is tracked using "obsolete markers", a piece of metadata
+tracking which changesets have been made obsolete, potential successors for
+a given changeset, the moment the changeset was marked as obsolete, and the
+user who performed the rewriting operation. The markers are stored
+separately from standard changeset data can be exchanged without any of the
+precursor changesets, preventing unnecessary exchange of obsolescence data.
+
+The complete set of obsolescence markers describes a history of changeset
+modifications that is orthogonal to the repository history of file
+modifications. This changeset history allows for detection and automatic
+resolution of edge cases arising from multiple users rewriting the same part
+of history concurrently.
+
+Current feature status
+======================
+
+This feature is still in development.  If you see this help, you have enabled an
+extension that turned this feature on.
+
+Obsolescence markers will be exchanged between repositories that explicitly
+assert support for the obsolescence feature (this can currently only be done
+via an extension).""".strip()
+
+
+import sys, os
+import random
+try:
+    import StringIO as io
+    StringIO = io.StringIO
+except ImportError:
+    import io
+    StringIO = io.StringIO
+import re
+import collections
+import socket
+import errno
+import hashlib
+import struct
+sha1re = re.compile(r'\b[0-9a-f]{6,40}\b')
+
+try:
+    from mercurial import registrar
+    registrar.templatekeyword # new in hg-3.8
+except ImportError:
+    raise ImportError('evolve needs version %s or above' %
+                      min(testedwith.split()))
+
+import mercurial
+from mercurial import util
+from mercurial import repair
+
+from mercurial import obsolete
+if not obsolete._enabled:
+    obsolete._enabled = True
+
+# Flags for enabling optional parts of evolve
+commandopt = 'allnewcommands'
+
+from mercurial import (
+    bookmarks as bookmarksmod,
+    cmdutil,
+    commands,
+    context,
+    copies,
+    error,
+    exchange,
+    extensions,
+    help,
+    hg,
+    httppeer,
+    localrepo,
+    lock as lockmod,
+    merge,
+    node,
+    patch,
+    phases,
+    revset,
+    scmutil,
+    templatekw,
+    wireproto
+)
+
+from mercurial.commands import walkopts, commitopts, commitopts2, mergetoolopts
+from mercurial.hgweb import hgweb_mod
+from mercurial.i18n import _
+from mercurial.node import nullid
+
+from . import serveronly
+
+obsexcmsg = serveronly.obsexcmsg
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+_pack = struct.pack
+_unpack = struct.unpack
+
+aliases, entry = cmdutil.findcmd('commit', commands.table)
+hasinteractivemode = any(['interactive' in e for e in entry[1]])
+if hasinteractivemode:
+    interactiveopt = [['i', 'interactive', None, _('use interactive mode')]]
+else:
+    interactiveopt = []
+# This extension contains the following code
+#
+# - Extension Helper code
+# - Obsolescence cache
+# - ...
+# - Older format compat
+
+
+#####################################################################
+### Extension helper                                              ###
+#####################################################################
+
+class exthelper(object):
+    """Helper for modular extension setup
+
+    A single helper should be instantiated for each extension. Helper
+    methods are then used as decorators for various purpose.
+
+    All decorators return the original function and may be chained.
+    """
+
+    def __init__(self):
+        self._uicallables = []
+        self._extcallables = []
+        self._repocallables = []
+        self._revsetsymbols = []
+        self._templatekws = []
+        self._commandwrappers = []
+        self._extcommandwrappers = []
+        self._functionwrappers = []
+        self._duckpunchers = []
+
+    def final_uisetup(self, ui):
+        """Method to be used as the extension uisetup
+
+        The following operations belong here:
+
+        - Changes to ui.__class__ . The ui object that will be used to run the
+          command has not yet been created. Changes made here will affect ui
+          objects created after this, and in particular the ui that will be
+          passed to runcommand
+        - Command wraps (extensions.wrapcommand)
+        - Changes that need to be visible to other extensions: because
+          initialization occurs in phases (all extensions run uisetup, then all
+          run extsetup), a change made here will be visible to other extensions
+          during extsetup
+        - Monkeypatch or wrap function (extensions.wrapfunction) of dispatch
+          module members
+        - Setup of pre-* and post-* hooks
+        - pushkey setup
+        """
+        for cont, funcname, func in self._duckpunchers:
+            setattr(cont, funcname, func)
+        for command, wrapper, opts in self._commandwrappers:
+            entry = extensions.wrapcommand(commands.table, command, wrapper)
+            if opts:
+                for short, long, val, msg in opts:
+                    entry[1].append((short, long, val, msg))
+        for cont, funcname, wrapper in self._functionwrappers:
+            extensions.wrapfunction(cont, funcname, wrapper)
+        for c in self._uicallables:
+            c(ui)
+
+    def final_extsetup(self, ui):
+        """Method to be used as a the extension extsetup
+
+        The following operations belong here:
+
+        - Changes depending on the status of other extensions. (if
+          extensions.find('mq'))
+        - Add a global option to all commands
+        - Register revset functions
+        """
+        knownexts = {}
+        for name, symbol in self._revsetsymbols:
+            revset.symbols[name] = symbol
+        for name, kw in self._templatekws:
+            templatekw.keywords[name] = kw
+        for ext, command, wrapper, opts in self._extcommandwrappers:
+            if ext not in knownexts:
+                try:
+                    e = extensions.find(ext)
+                except KeyError:
+                    # Extension isn't enabled, so don't bother trying to wrap
+                    # it.
+                    continue
+                knownexts[ext] = e.cmdtable
+            entry = extensions.wrapcommand(knownexts[ext], command, wrapper)
+            if opts:
+                for short, long, val, msg in opts:
+                    entry[1].append((short, long, val, msg))
+
+        for c in self._extcallables:
+            c(ui)
+
+    def final_reposetup(self, ui, repo):
+        """Method to be used as the extension reposetup
+
+        The following operations belong here:
+
+        - All hooks but pre-* and post-*
+        - Modify configuration variables
+        - Changes to repo.__class__, repo.dirstate.__class__
+        """
+        for c in self._repocallables:
+            c(ui, repo)
+
+    def uisetup(self, call):
+        """Decorated function will be executed during uisetup
+
+        example::
+
+            @eh.uisetup
+            def setupbabar(ui):
+                print 'this is uisetup!'
+        """
+        self._uicallables.append(call)
+        return call
+
+    def extsetup(self, call):
+        """Decorated function will be executed during extsetup
+
+        example::
+
+            @eh.extsetup
+            def setupcelestine(ui):
+                print 'this is extsetup!'
+        """
+        self._extcallables.append(call)
+        return call
+
+    def reposetup(self, call):
+        """Decorated function will be executed during reposetup
+
+        example::
+
+            @eh.reposetup
+            def setupzephir(ui, repo):
+                print 'this is reposetup!'
+        """
+        self._repocallables.append(call)
+        return call
+
+    def revset(self, symbolname):
+        """Decorated function is a revset symbol
+
+        The name of the symbol must be given as the decorator argument.
+        The symbol is added during `extsetup`.
+
+        example::
+
+            @eh.revset('hidden')
+            def revsetbabar(repo, subset, x):
+                args = revset.getargs(x, 0, 0, 'babar accept no argument')
+                return [r for r in subset if 'babar' in repo[r].description()]
+        """
+        def dec(symbol):
+            self._revsetsymbols.append((symbolname, symbol))
+            return symbol
+        return dec
+
+
+    def templatekw(self, keywordname):
+        """Decorated function is a template keyword
+
+        The name of the keyword must be given as the decorator argument.
+        The symbol is added during `extsetup`.
+
+        example::
+
+            @eh.templatekw('babar')
+            def kwbabar(ctx):
+                return 'babar'
+        """
+        def dec(keyword):
+            self._templatekws.append((keywordname, keyword))
+            return keyword
+        return dec
+
+    def wrapcommand(self, command, extension=None, opts=[]):
+        """Decorated function is a command wrapper
+
+        The name of the command must be given as the decorator argument.
+        The wrapping is installed during `uisetup`.
+
+        If the second option `extension` argument is provided, the wrapping
+        will be applied in the extension commandtable. This argument must be a
+        string that will be searched using `extension.find` if not found and
+        Abort error is raised. If the wrapping applies to an extension, it is
+        installed during `extsetup`.
+
+        example::
+
+            @eh.wrapcommand('summary')
+            def wrapsummary(orig, ui, repo, *args, **kwargs):
+                ui.note('Barry!')
+                return orig(ui, repo, *args, **kwargs)
+
+        The `opts` argument allows specifying additional arguments for the
+        command.
+
+        """
+        def dec(wrapper):
+            if extension is None:
+                self._commandwrappers.append((command, wrapper, opts))
+            else:
+                self._extcommandwrappers.append((extension, command, wrapper,
+                    opts))
+            return wrapper
+        return dec
+
+    def wrapfunction(self, container, funcname):
+        """Decorated function is a function wrapper
+
+        This function takes two arguments, the container and the name of the
+        function to wrap. The wrapping is performed during `uisetup`.
+        (there is no extension support)
+
+        example::
+
+            @eh.function(discovery, 'checkheads')
+            def wrapfunction(orig, *args, **kwargs):
+                ui.note('His head smashed in and his heart cut out')
+                return orig(*args, **kwargs)
+        """
+        def dec(wrapper):
+            self._functionwrappers.append((container, funcname, wrapper))
+            return wrapper
+        return dec
+
+    def addattr(self, container, funcname):
+        """Decorated function is to be added to the container
+
+        This function takes two arguments, the container and the name of the
+        function to wrap. The wrapping is performed during `uisetup`.
+
+        example::
+
+            @eh.function(context.changectx, 'babar')
+            def babar(ctx):
+                return 'babar' in ctx.description
+        """
+        def dec(func):
+            self._duckpunchers.append((container, funcname, func))
+            return func
+        return dec
+
+eh = exthelper()
+uisetup = eh.final_uisetup
+extsetup = eh.final_extsetup
+reposetup = eh.final_reposetup
+
+eh.extsetup(serveronly.extsetup)
+
+#####################################################################
+### Option configuration                                          ###
+#####################################################################
+
+@eh.reposetup # must be the first of its kin.
+def _configureoptions(ui, repo):
+    # If no capabilities are specified, enable everything.
+    # This is so existing evolve users don't need to change their config.
+    evolveopts = ui.configlist('experimental', 'evolution')
+    if not evolveopts:
+        evolveopts = ['all']
+        ui.setconfig('experimental', 'evolution', evolveopts, 'evolve')
+
+@eh.uisetup
+def _configurecmdoptions(ui):
+    # Unregister evolve commands if the command capability is not specified.
+    #
+    # This must be in the same function as the option configuration above to
+    # guarantee it happens after the above configuration, but before the
+    # extsetup functions.
+    evolvecommands = ui.configlist('experimental', 'evolutioncommands')
+    evolveopts = ui.configlist('experimental', 'evolution')
+    if evolveopts and (commandopt not in evolveopts and
+                       'all' not in evolveopts):
+        # We build whitelist containing the commands we want to enable
+        whitelist = set()
+        for cmd in evolvecommands:
+            matchingevolvecommands = [e for e in cmdtable.keys() if cmd in e]
+            if not matchingevolvecommands:
+                raise error.Abort(_('unknown command: %s') % cmd)
+            elif len(matchingevolvecommands) > 1:
+                msg = _('ambiguous command specification: "%s" matches %r')
+                raise error.Abort(msg % (cmd, matchingevolvecommands))
+            else:
+                whitelist.add(matchingevolvecommands[0])
+        for disabledcmd in set(cmdtable) - whitelist:
+            del cmdtable[disabledcmd]
+
+#####################################################################
+### experimental behavior                                         ###
+#####################################################################
+
+commitopts3 = [
+    ('D', 'current-date', None,
+     _('record the current date as commit date')),
+    ('U', 'current-user', None,
+     _('record the current user as committer')),
+]
+
+def _resolveoptions(ui, opts):
+    """modify commit options dict to handle related options
+
+    For now, all it does is figure out the commit date: respect -D unless
+    -d was supplied.
+    """
+    # N.B. this is extremely similar to setupheaderopts() in mq.py
+    if not opts.get('date') and opts.get('current_date'):
+        opts['date'] = '%d %d' % util.makedate()
+    if not opts.get('user') and opts.get('current_user'):
+        opts['user'] = ui.username()
+
+getrevs = obsolete.getrevs
+
+#####################################################################
+### Additional Utilities                                          ###
+#####################################################################
+
+# This section contains a lot of small utility function and method
+
+# - Function to create markers
+# - useful alias pstatus and pdiff (should probably go in evolve)
+# - "troubles" method on changectx
+# - function to travel through the obsolescence graph
+# - function to find useful changeset to stabilize
+
+
+### Useful alias
+
+@eh.uisetup
+def _installalias(ui):
+    if ui.config('alias', 'pstatus', None) is None:
+        ui.setconfig('alias', 'pstatus', 'status --rev .^', 'evolve')
+    if ui.config('alias', 'pdiff', None) is None:
+        ui.setconfig('alias', 'pdiff', 'diff --rev .^', 'evolve')
+    if ui.config('alias', 'olog', None) is None:
+        ui.setconfig('alias', 'olog', "log -r 'precursors(.)' --hidden",
+                     'evolve')
+    if ui.config('alias', 'odiff', None) is None:
+        ui.setconfig('alias', 'odiff',
+            "diff --hidden --rev 'limit(precursors(.),1)' --rev .",
+            'evolve')
+    if ui.config('alias', 'grab', None) is None:
+        if os.name == 'nt':
+            ui.setconfig('alias', 'grab',
+                "! " + util.hgexecutable() + " rebase --dest . --rev $@ && "
+                 + util.hgexecutable() + " up tip",
+                         'evolve')
+        else:
+            ui.setconfig('alias', 'grab',
+                "! $HG rebase --dest . --rev $@ && $HG up tip",
+                         'evolve')
+
+
+### Troubled revset symbol
+
+@eh.revset('troubled')
+def revsettroubled(repo, subset, x):
+    """``troubled()``
+    Changesets with troubles.
+    """
+    revset.getargs(x, 0, 0, 'troubled takes no arguments')
+    troubled = set()
+    troubled.update(getrevs(repo, 'unstable'))
+    troubled.update(getrevs(repo, 'bumped'))
+    troubled.update(getrevs(repo, 'divergent'))
+    troubled = revset.baseset(troubled)
+    troubled.sort() # set is non-ordered, enforce order
+    return subset & troubled
+
+### Obsolescence graph
+
+# XXX SOME MAJOR CLEAN UP TO DO HERE XXX
+
+def _precursors(repo, s):
+    """Precursor of a changeset"""
+    cs = set()
+    nm = repo.changelog.nodemap
+    markerbysubj = repo.obsstore.precursors
+    node = repo.changelog.node
+    for r in s:
+        for p in markerbysubj.get(node(r), ()):
+            pr = nm.get(p[0])
+            if pr is not None:
+                cs.add(pr)
+    cs -= repo.changelog.filteredrevs # nodemap has no filtering
+    return cs
+
+def _allprecursors(repo, s):  # XXX we need a better naming
+    """transitive precursors of a subset"""
+    node = repo.changelog.node
+    toproceed = [node(r) for r in s]
+    seen = set()
+    allsubjects = repo.obsstore.precursors
+    while toproceed:
+        nc = toproceed.pop()
+        for mark in allsubjects.get(nc, ()):
+            np = mark[0]
+            if np not in seen:
+                seen.add(np)
+                toproceed.append(np)
+    nm = repo.changelog.nodemap
+    cs = set()
+    for p in seen:
+        pr = nm.get(p)
+        if pr is not None:
+            cs.add(pr)
+    cs -= repo.changelog.filteredrevs # nodemap has no filtering
+    return cs
+
+def _successors(repo, s):
+    """Successors of a changeset"""
+    cs = set()
+    node = repo.changelog.node
+    nm = repo.changelog.nodemap
+    markerbyobj = repo.obsstore.successors
+    for r in s:
+        for p in markerbyobj.get(node(r), ()):
+            for sub in p[1]:
+                sr = nm.get(sub)
+                if sr is not None:
+                    cs.add(sr)
+    cs -= repo.changelog.filteredrevs # nodemap has no filtering
+    return cs
+
+def _allsuccessors(repo, s, haltonflags=0):  # XXX we need a better naming
+    """transitive successors of a subset
+
+    haltonflags allows to provide flags which prevent the evaluation of a
+    marker.  """
+    node = repo.changelog.node
+    toproceed = [node(r) for r in s]
+    seen = set()
+    allobjects = repo.obsstore.successors
+    while toproceed:
+        nc = toproceed.pop()
+        for mark in allobjects.get(nc, ()):
+            if mark[2] & haltonflags:
+                continue
+            for sub in mark[1]:
+                if sub == nullid:
+                    continue # should not be here!
+                if sub not in seen:
+                    seen.add(sub)
+                    toproceed.append(sub)
+    nm = repo.changelog.nodemap
+    cs = set()
+    for s in seen:
+        sr = nm.get(s)
+        if sr is not None:
+            cs.add(sr)
+    cs -= repo.changelog.filteredrevs # nodemap has no filtering
+    return cs
+
+
+
+
+#####################################################################
+### Extending revset and template                                 ###
+#####################################################################
+
+# this section add several useful revset symbol not yet in core.
+# they are subject to changes
+
+
+### XXX I'm not sure this revset is useful
+@eh.revset('suspended')
+def revsetsuspended(repo, subset, x):
+    """``suspended()``
+    Obsolete changesets with non-obsolete descendants.
+    """
+    revset.getargs(x, 0, 0, 'suspended takes no arguments')
+    suspended = revset.baseset(getrevs(repo, 'suspended'))
+    suspended.sort()
+    return subset & suspended
+
+
+@eh.revset('precursors')
+def revsetprecursors(repo, subset, x):
+    """``precursors(set)``
+    Immediate precursors of changesets in set.
+    """
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    s = revset.baseset(_precursors(repo, s))
+    s.sort()
+    return subset & s
+
+
+@eh.revset('allprecursors')
+def revsetallprecursors(repo, subset, x):
+    """``allprecursors(set)``
+    Transitive precursors of changesets in set.
+    """
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    s = revset.baseset(_allprecursors(repo, s))
+    s.sort()
+    return subset & s
+
+
+@eh.revset('successors')
+def revsetsuccessors(repo, subset, x):
+    """``successors(set)``
+    Immediate successors of changesets in set.
+    """
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    s = revset.baseset(_successors(repo, s))
+    s.sort()
+    return subset & s
+
+@eh.revset('allsuccessors')
+def revsetallsuccessors(repo, subset, x):
+    """``allsuccessors(set)``
+    Transitive successors of changesets in set.
+    """
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    s = revset.baseset(_allsuccessors(repo, s))
+    s.sort()
+    return subset & s
+
+### template keywords
+# XXX it does not handle troubles well :-/
+
+@eh.templatekw('obsolete')
+def obsoletekw(repo, ctx, templ, **args):
+    """:obsolete: String. Whether the changeset is ``obsolete``.
+    """
+    if ctx.obsolete():
+        return 'obsolete'
+    return ''
+
+@eh.templatekw('troubles')
+def showtroubles(repo, ctx, **args):
+    """:troubles: List of strings. Evolution troubles affecting the changeset
+    (zero or more of "unstable", "divergent" or "bumped")."""
+    return templatekw.showlist('trouble', ctx.troubles(), plural='troubles',
+                               **args)
+
+#####################################################################
+### Various trouble warning                                       ###
+#####################################################################
+
+# This section take care of issue warning to the user when troubles appear
+
+
+def _warnobsoletewc(ui, repo):
+    if repo['.'].obsolete():
+        ui.warn(_('working directory parent is obsolete!\n'))
+        if (not ui.quiet) and obsolete.isenabled(repo, commandopt):
+            ui.warn(_("(use 'hg evolve' to update to its successor)\n"))
+
+@eh.wrapcommand("update")
+@eh.wrapcommand("pull")
+def wrapmayobsoletewc(origfn, ui, repo, *args, **opts):
+    """Warn that the working directory parent is an obsolete changeset"""
+    def warnobsolete():
+        _warnobsoletewc(ui, repo)
+    wlock = None
+    try:
+        wlock = repo.wlock()
+        repo._afterlock(warnobsolete)
+        res = origfn(ui, repo, *args, **opts)
+    finally:
+        lockmod.release(wlock)
+    return res
+
+@eh.wrapcommand("parents")
+def wrapparents(origfn, ui, repo, *args, **opts):
+    res = origfn(ui, repo, *args, **opts)
+    _warnobsoletewc(ui, repo)
+    return res
+
+# XXX this could wrap transaction code
+# XXX (but this is a bit a layer violation)
+@eh.wrapcommand("commit")
+@eh.wrapcommand("import")
+@eh.wrapcommand("push")
+@eh.wrapcommand("pull")
+@eh.wrapcommand("graft")
+@eh.wrapcommand("phase")
+@eh.wrapcommand("unbundle")
+def warnobserrors(orig, ui, repo, *args, **kwargs):
+    """display warning is the command resulted in more instable changeset"""
+    # part of the troubled stuff may be filtered (stash ?)
+    # This needs a better implementation but will probably wait for core.
+    filtered = repo.changelog.filteredrevs
+    priorunstables = len(set(getrevs(repo, 'unstable')) - filtered)
+    priorbumpeds = len(set(getrevs(repo, 'bumped')) - filtered)
+    priordivergents = len(set(getrevs(repo, 'divergent')) - filtered)
+    ret = orig(ui, repo, *args, **kwargs)
+    # workaround phase stupidity
+    #phases._filterunknown(ui, repo.changelog, repo._phasecache.phaseroots)
+    filtered = repo.changelog.filteredrevs
+    newunstables = \
+        len(set(getrevs(repo, 'unstable')) - filtered) - priorunstables
+    newbumpeds = \
+        len(set(getrevs(repo, 'bumped')) - filtered) - priorbumpeds
+    newdivergents = \
+        len(set(getrevs(repo, 'divergent')) - filtered) - priordivergents
+    if newunstables > 0:
+        ui.warn(_('%i new unstable changesets\n') % newunstables)
+    if newbumpeds > 0:
+        ui.warn(_('%i new bumped changesets\n') % newbumpeds)
+    if newdivergents > 0:
+        ui.warn(_('%i new divergent changesets\n') % newdivergents)
+    return ret
+
+@eh.wrapfunction(mercurial.exchange, 'push')
+def push(orig, repo, *args, **opts):
+    """Add a hint for "hg evolve" when troubles make push fails
+    """
+    try:
+        return orig(repo, *args, **opts)
+    except error.Abort as ex:
+        hint = _("use 'hg evolve' to get a stable history "
+                 "or --force to ignore warnings")
+        if (len(ex.args) >= 1
+            and ex.args[0].startswith('push includes ')
+            and ex.hint is None):
+            ex.hint = hint
+        raise
+
+def summaryhook(ui, repo):
+    def write(fmt, count):
+        s = fmt % count
+        if count:
+            ui.write(s)
+        else:
+            ui.note(s)
+
+    state = _evolvestateread(repo)
+    if state is not None:
+        # i18n: column positioning for "hg summary"
+        ui.write(_('evolve: (evolve --continue)\n'))
+
+@eh.extsetup
+def obssummarysetup(ui):
+    cmdutil.summaryhooks.add('evolve', summaryhook)
+
+
+#####################################################################
+### Core Other extension compat                                   ###
+#####################################################################
+
+
+@eh.extsetup
+def _rebasewrapping(ui):
+    # warning about more obsolete
+    try:
+        rebase = extensions.find('rebase')
+        if rebase:
+            extensions.wrapcommand(rebase.cmdtable, 'rebase', warnobserrors)
+    except KeyError:
+        pass # rebase not found
+    try:
+        histedit = extensions.find('histedit')
+        if histedit:
+            extensions.wrapcommand(histedit.cmdtable, 'histedit', warnobserrors)
+    except KeyError:
+        pass # histedit not found
+
+#####################################################################
+### Old Evolve extension content                                  ###
+#####################################################################
+
+# XXX need clean up and proper sorting in other section
+
+### util function
+#############################
+
+### changeset rewriting logic
+#############################
+
+def rewrite(repo, old, updates, head, newbases, commitopts):
+    """Return (nodeid, created) where nodeid is the identifier of the
+    changeset generated by the rewrite process, and created is True if
+    nodeid was actually created. If created is False, nodeid
+    references a changeset existing before the rewrite call.
+    """
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction('rewrite')
+        if len(old.parents()) > 1: #XXX remove this unnecessary limitation.
+            raise error.Abort(_('cannot amend merge changesets'))
+        base = old.p1()
+        updatebookmarks = _bookmarksupdater(repo, old.node(), tr)
+
+        # commit a new version of the old changeset, including the update
+        # collect all files which might be affected
+        files = set(old.files())
+        for u in updates:
+            files.update(u.files())
+
+        # Recompute copies (avoid recording a -> b -> a)
+        copied = copies.pathcopies(base, head)
+
+
+        # prune files which were reverted by the updates
+        def samefile(f):
+            if f in head.manifest():
+                a = head.filectx(f)
+                if f in base.manifest():
+                    b = base.filectx(f)
+                    return (a.data() == b.data()
+                            and a.flags() == b.flags())
+                else:
+                    return False
+            else:
+                return f not in base.manifest()
+        files = [f for f in files if not samefile(f)]
+        # commit version of these files as defined by head
+        headmf = head.manifest()
+        def filectxfn(repo, ctx, path):
+            if path in headmf:
+                fctx = head[path]
+                flags = fctx.flags()
+                mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
+                                          islink='l' in flags,
+                                          isexec='x' in flags,
+                                          copied=copied.get(path))
+                return mctx
+            return None
+
+        message = cmdutil.logmessage(repo.ui, commitopts)
+        if not message:
+            message = old.description()
+
+        user = commitopts.get('user') or old.user()
+        date = commitopts.get('date') or None # old.date()
+        extra = dict(commitopts.get('extra', old.extra()))
+        extra['branch'] = head.branch()
+
+        new = context.memctx(repo,
+                             parents=newbases,
+                             text=message,
+                             files=files,
+                             filectxfn=filectxfn,
+                             user=user,
+                             date=date,
+                             extra=extra)
+
+        if commitopts.get('edit'):
+            new._text = cmdutil.commitforceeditor(repo, new, [])
+        revcount = len(repo)
+        newid = repo.commitctx(new)
+        new = repo[newid]
+        created = len(repo) != revcount
+        updatebookmarks(newid)
+
+        tr.close()
+        return newid, created
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+class MergeFailure(error.Abort):
+    pass
+
+def relocate(repo, orig, dest, pctx=None, keepbranch=False):
+    """rewrite <rev> on dest"""
+    if orig.rev() == dest.rev():
+        raise error.Abort(_('tried to relocate a node on top of itself'),
+                         hint=_("This shouldn't happen. If you still "
+                                "need to move changesets, please do so "
+                                "manually with nothing to rebase - working "
+                                "directory parent is also destination"))
+
+    if pctx is None:
+        if len(orig.parents()) == 2:
+            raise error.Abort(_("tried to relocate a merge commit without "
+                                "specifying which parent should be moved"),
+                              hint=_("Specify the parent by passing in pctx"))
+        pctx = orig.p1()
+
+    destbookmarks = repo.nodebookmarks(dest.node())
+    nodesrc = orig.node()
+    destphase = repo[nodesrc].phase()
+    commitmsg = orig.description()
+
+    cache = {}
+    sha1s = re.findall(sha1re, commitmsg)
+    unfi = repo.unfiltered()
+    for sha1 in sha1s:
+        ctx = None
+        try:
+            ctx = unfi[sha1]
+        except error.RepoLookupError:
+            continue
+
+        if not ctx.obsolete():
+            continue
+
+        successors = obsolete.successorssets(repo, ctx.node(), cache)
+
+        # We can't make any assumptions about how to update the hash if the
+        # cset in question was split or diverged.
+        if len(successors) == 1 and len(successors[0]) == 1:
+            newsha1 = node.hex(successors[0][0])
+            commitmsg = commitmsg.replace(sha1, newsha1[:len(sha1)])
+        else:
+            repo.ui.note(_('The stale commit message reference to %s could '
+                           'not be updated\n') % sha1)
+
+    tr = repo.currenttransaction()
+    assert tr is not None
+    try:
+        r = _evolvemerge(repo, orig, dest, pctx, keepbranch)
+        if r[-1]:  #some conflict
+            raise error.Abort(
+                    'unresolved merge conflicts (see hg help resolve)')
+        nodenew = _relocatecommit(repo, orig, commitmsg)
+    except error.Abort as exc:
+        repo.dirstate.beginparentchange()
+        repo.setparents(repo['.'].node(), nullid)
+        repo.dirstate.write(tr)
+        # fix up dirstate for copies and renames
+        copies.duplicatecopies(repo, dest.rev(), orig.p1().rev())
+        repo.dirstate.endparentchange()
+        class LocalMergeFailure(MergeFailure, exc.__class__):
+            pass
+        exc.__class__ = LocalMergeFailure
+        tr.close() # to keep changes in this transaction (e.g. dirstate)
+        raise
+    oldbookmarks = repo.nodebookmarks(nodesrc)
+    _finalizerelocate(repo, orig, dest, nodenew, tr)
+    return nodenew
+
+def _bookmarksupdater(repo, oldid, tr):
+    """Return a callable update(newid) updating the current bookmark
+    and bookmarks bound to oldid to newid.
+    """
+    def updatebookmarks(newid):
+        dirty = False
+        oldbookmarks = repo.nodebookmarks(oldid)
+        if oldbookmarks:
+            for b in oldbookmarks:
+                repo._bookmarks[b] = newid
+            dirty = True
+        if dirty:
+            repo._bookmarks.recordchange(tr)
+    return updatebookmarks
+
+### new command
+#############################
+metadataopts = [
+    ('d', 'date', '',
+     _('record the specified date in metadata'), _('DATE')),
+    ('u', 'user', '',
+     _('record the specified user in metadata'), _('USER')),
+]
+
+@eh.uisetup
+def _installimportobsolete(ui):
+    entry = cmdutil.findcmd('import', commands.table)[1]
+    entry[1].append(('', 'obsolete', False,
+                    _('mark the old node as obsoleted by '
+                      'the created commit')))
+
+@eh.wrapfunction(mercurial.cmdutil, 'tryimportone')
+def tryimportone(orig, ui, repo, hunk, parents, opts, *args, **kwargs):
+    extracted = patch.extract(ui, hunk)
+    expected = extracted.get('nodeid')
+    if expected is not None:
+        expected = node.bin(expected)
+    oldextract = patch.extract
+    try:
+        patch.extract = lambda ui, hunk: extracted
+        ret = orig(ui, repo, hunk, parents, opts, *args, **kwargs)
+    finally:
+        patch.extract = oldextract
+    created = ret[1]
+    if (opts['obsolete'] and None not in (created, expected)
+        and created != expected):
+            tr = repo.transaction('import-obs')
+            try:
+                metadata = {'user': ui.username()}
+                repo.obsstore.create(tr, expected, (created,),
+                                     metadata=metadata)
+                tr.close()
+            finally:
+                tr.release()
+    return ret
+
+
+def _deprecatealias(oldalias, newalias):
+    '''Deprecates an alias for a command in favour of another
+
+    Creates a new entry in the command table for the old alias. It creates a
+    wrapper that has its synopsis set to show that is has been deprecated.
+    The documentation will be replace with a pointer to the new alias.
+    If a user invokes the command a deprecation warning will be printed and
+    the command of the *new* alias will be invoked.
+
+    This function is loosely based on the extensions.wrapcommand function.
+    '''
+    try:
+        aliases, entry = cmdutil.findcmd(newalias, cmdtable)
+    except error.UnknownCommand:
+        # Commands may be disabled
+        return
+    for alias, e in cmdtable.items():
+        if e is entry:
+            break
+
+    synopsis = '(DEPRECATED)'
+    if len(entry) > 2:
+        fn, opts, _syn = entry
+    else:
+        fn, opts, = entry
+    deprecationwarning = _('%s have been deprecated in favor of %s\n') % (
+        oldalias, newalias)
+    def newfn(*args, **kwargs):
+        ui = args[0]
+        ui.warn(deprecationwarning)
+        util.checksignature(fn)(*args, **kwargs)
+    newfn.__doc__  = deprecationwarning
+    cmdwrapper = command(oldalias, opts, synopsis)
+    cmdwrapper(newfn)
+
+@eh.extsetup
+def deprecatealiases(ui):
+    _deprecatealias('gup', 'next')
+    _deprecatealias('gdown', 'previous')
+
+@command('debugrecordpruneparents', [], '')
+def cmddebugrecordpruneparents(ui, repo):
+    """add parent data to prune markers when possible
+
+    This command searches the repo for prune markers without parent information.
+    If the pruned node is locally known, it creates a new marker with parent
+    data.
+    """
+    pgop = 'reading markers'
+
+    # lock from the beginning to prevent race
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction('recordpruneparents')
+        unfi = repo.unfiltered()
+        nm = unfi.changelog.nodemap
+        store = repo.obsstore
+        pgtotal = len(store._all)
+        for idx, mark in enumerate(list(store._all)):
+            if not mark[1]:
+                rev = nm.get(mark[0])
+                if rev is not None:
+                    ctx = unfi[rev]
+                    parents = tuple(p.node() for p in ctx.parents())
+                    before = len(store._all)
+                    store.create(tr, mark[0], mark[1], mark[2], mark[3],
+                                 parents=parents)
+                    if len(store._all) - before:
+                        ui.write(_('created new markers for %i\n') % rev)
+            ui.progress(pgop, idx, total=pgtotal)
+        tr.close()
+        ui.progress(pgop, None)
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+@command('debugobsstorestat', [], '')
+def cmddebugobsstorestat(ui, repo):
+    """print statistics about obsolescence markers in the repo"""
+    def _updateclustermap(nodes, mark, clustersmap):
+        c = (set(nodes), set([mark]))
+        toproceed = set(nodes)
+        while toproceed:
+            n = toproceed.pop()
+            other = clustersmap.get(n)
+            if (other is not None
+                and other is not c):
+                other[0].update(c[0])
+                other[1].update(c[1])
+                for on in c[0]:
+                    if on in toproceed:
+                        continue
+                    clustersmap[on] = other
+                c = other
+            clustersmap[n] = c
+
+    store = repo.obsstore
+    unfi = repo.unfiltered()
+    nm = unfi.changelog.nodemap
+    ui.write(_('markers total:              %9i\n') % len(store._all))
+    sucscount = [0, 0 , 0, 0]
+    known = 0
+    parentsdata = 0
+    metakeys = {}
+    # node -> cluster mapping
+    #   a cluster is a (set(nodes), set(markers)) tuple
+    clustersmap = {}
+    # same data using parent information
+    pclustersmap = {}
+    for mark in store:
+        if mark[0] in nm:
+            known += 1
+        nbsucs = len(mark[1])
+        sucscount[min(nbsucs, 3)] += 1
+        meta = mark[3]
+        for key, value in meta:
+            metakeys.setdefault(key, 0)
+            metakeys[key] += 1
+        meta = dict(meta)
+        parents = [meta.get('p1'), meta.get('p2')]
+        parents = [node.bin(p) for p in parents if p is not None]
+        if parents:
+            parentsdata += 1
+        # cluster handling
+        nodes = set(mark[1])
+        nodes.add(mark[0])
+        _updateclustermap(nodes, mark, clustersmap)
+        # same with parent data
+        nodes.update(parents)
+        _updateclustermap(nodes, mark, pclustersmap)
+
+    # freezing the result
+    for c in clustersmap.values():
+        fc = (frozenset(c[0]), frozenset(c[1]))
+        for n in fc[0]:
+            clustersmap[n] = fc
+    # same with parent data
+    for c in pclustersmap.values():
+        fc = (frozenset(c[0]), frozenset(c[1]))
+        for n in fc[0]:
+            pclustersmap[n] = fc
+    ui.write(('    for known precursors:   %9i\n' % known))
+    ui.write(('    with parents data:      %9i\n' % parentsdata))
+    # successors data
+    ui.write(('markers with no successors: %9i\n' % sucscount[0]))
+    ui.write(('              1 successors: %9i\n' % sucscount[1]))
+    ui.write(('              2 successors: %9i\n' % sucscount[2]))
+    ui.write(('    more than 2 successors: %9i\n' % sucscount[3]))
+    # meta data info
+    ui.write(('    available  keys:\n'))
+    for key in sorted(metakeys):
+        ui.write(('    %15s:        %9i\n' % (key, metakeys[key])))
+
+    allclusters = list(set(clustersmap.values()))
+    allclusters.sort(key=lambda x: len(x[1]))
+    ui.write(('disconnected clusters:      %9i\n' % len(allclusters)))
+
+    ui.write('        any known node:     %9i\n'
+             % len([c for c in allclusters
+                    if [n for n in c[0] if nm.get(n) is not None]]))
+    if allclusters:
+        nbcluster = len(allclusters)
+        ui.write(('        smallest length:    %9i\n' % len(allclusters[0][1])))
+        ui.write(('        longer length:      %9i\n'
+                 % len(allclusters[-1][1])))
+        median = len(allclusters[nbcluster//2][1])
+        ui.write(('        median length:      %9i\n' % median))
+        mean = sum(len(x[1]) for x in allclusters) // nbcluster
+        ui.write(('        mean length:        %9i\n' % mean))
+    allpclusters = list(set(pclustersmap.values()))
+    allpclusters.sort(key=lambda x: len(x[1]))
+    ui.write(('    using parents data:     %9i\n' % len(allpclusters)))
+    ui.write('        any known node:     %9i\n'
+             % len([c for c in allclusters
+                    if [n for n in c[0] if nm.get(n) is not None]]))
+    if allpclusters:
+        nbcluster = len(allpclusters)
+        ui.write(('        smallest length:    %9i\n'
+                 % len(allpclusters[0][1])))
+        ui.write(('        longer length:      %9i\n'
+                 % len(allpclusters[-1][1])))
+        median = len(allpclusters[nbcluster//2][1])
+        ui.write(('        median length:      %9i\n' % median))
+        mean = sum(len(x[1]) for x in allpclusters) // nbcluster
+        ui.write(('        mean length:        %9i\n' % mean))
+
+def _solveone(ui, repo, ctx, dryrun, confirm, progresscb, category):
+    """Resolve the troubles affecting one revision"""
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction("evolve")
+        if 'unstable' == category:
+            result = _solveunstable(ui, repo, ctx, dryrun, confirm, progresscb)
+        elif 'bumped' == category:
+            result = _solvebumped(ui, repo, ctx, dryrun, confirm, progresscb)
+        elif 'divergent' == category:
+            result = _solvedivergent(ui, repo, ctx, dryrun, confirm,
+                                   progresscb)
+        else:
+            assert False, "unknown trouble category: %s" % (category)
+        tr.close()
+        return result
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+def _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat):
+    """Used by the evolve function to display an error message when
+    no troubles can be resolved"""
+    troublecategories = ['bumped', 'divergent', 'unstable']
+    unselectedcategories = [c for c in troublecategories if c != targetcat]
+    msg = None
+    hint = None
+
+    troubled = {
+            "unstable": repo.revs("unstable()"),
+            "divergent": repo.revs("divergent()"),
+            "bumped": repo.revs("bumped()"),
+            "all": repo.revs("troubled()"),
+    }
+
+
+    hintmap = {
+            'bumped': _("do you want to use --bumped"),
+            'bumped+divergent': _("do you want to use --bumped or --divergent"),
+            'bumped+unstable': _("do you want to use --bumped or --unstable"),
+            'divergent': _("do you want to use --divergent"),
+            'divergent+unstable': _("do you want to use --divergent"
+                                    " or --unstable"),
+            'unstable': _("do you want to use --unstable"),
+            'any+bumped': _("do you want to use --any (or --rev) and --bumped"),
+            'any+bumped+divergent': _("do you want to use --any (or --rev) and"
+                                      " --bumped or --divergent"),
+            'any+bumped+unstable': _("do you want to use --any (or --rev) and"
+                                     "--bumped or --unstable"),
+            'any+divergent': _("do you want to use --any (or --rev) and"
+                               " --divergent"),
+            'any+divergent+unstable': _("do you want to use --any (or --rev)"
+                                        " and --divergent or --unstable"),
+            'any+unstable': _("do you want to use --any (or --rev)"
+                              "and --unstable"),
+    }
+
+    if revopt:
+        revs = scmutil.revrange(repo, revopt)
+        if not revs:
+            msg = _("set of specified revisions is empty")
+        else:
+            msg = _("no %s changesets in specified revisions") % targetcat
+            othertroubles = []
+            for cat in unselectedcategories:
+                if revs & troubled[cat]:
+                    othertroubles.append(cat)
+            if othertroubles:
+                hint = hintmap['+'.join(othertroubles)]
+
+    elif anyopt:
+        msg = _("no %s changesets to evolve") % targetcat
+        othertroubles = []
+        for cat in unselectedcategories:
+            if troubled[cat]:
+                othertroubles.append(cat)
+        if othertroubles:
+            hint = hintmap['+'.join(othertroubles)]
+
+    else:
+        # evolve without any option = relative to the current wdir
+        if targetcat == 'unstable':
+            msg = _("nothing to evolve on current working copy parent")
+        else:
+            msg = _("current working copy parent is not %s") % targetcat
+
+        p1 = repo['.'].rev()
+        othertroubles = []
+        for cat in unselectedcategories:
+            if p1 in troubled[cat]:
+                othertroubles.append(cat)
+        if othertroubles:
+            hint = hintmap['+'.join(othertroubles)]
+        else:
+            l = len(troubled[targetcat])
+            if l:
+                hint = _("%d other %s in the repository, do you want --any "
+                        "or --rev") % (l, targetcat)
+            else:
+                othertroubles = []
+                for cat in unselectedcategories:
+                    if troubled[cat]:
+                        othertroubles.append(cat)
+                if othertroubles:
+                    hint = hintmap['any+'+('+'.join(othertroubles))]
+                else:
+                    msg = _("no troubled changesets")
+
+    assert msg is not None
+    ui.write_err(msg+"\n")
+    if hint:
+        ui.write_err("("+hint+")\n")
+        return 2
+    else:
+        return 1
+
+def _cleanup(ui, repo, startnode, showprogress):
+    if showprogress:
+        ui.progress(_('evolve'), None)
+    if repo['.'] != startnode:
+        ui.status(_('working directory is now at %s\n') % repo['.'])
+
+class MultipleSuccessorsError(RuntimeError):
+    """Exception raised by _singlesuccessor when multiple successor sets exists
+
+    The object contains the list of successorssets in its 'successorssets'
+    attribute to call to easily recover.
+    """
+
+    def __init__(self, successorssets):
+        self.successorssets = successorssets
+
+def _singlesuccessor(repo, p):
+    """returns p (as rev) if not obsolete or its unique latest successors
+
+    fail if there are no such successor"""
+
+    if not p.obsolete():
+        return p.rev()
+    obs = repo[p]
+    ui = repo.ui
+    newer = obsolete.successorssets(repo, obs.node())
+    # search of a parent which is not killed
+    while not newer:
+        ui.debug("stabilize target %s is plain dead,"
+                 " trying to stabilize on its parent\n" %
+                 obs)
+        obs = obs.parents()[0]
+        newer = obsolete.successorssets(repo, obs.node())
+    if len(newer) > 1 or len(newer[0]) > 1:
+        raise MultipleSuccessorsError(newer)
+
+    return repo[newer[0][0]].rev()
+
+def builddependencies(repo, revs):
+    """returns dependency graphs giving an order to solve instability of revs
+    (see _orderrevs for more information on usage)"""
+
+    # For each troubled revision we keep track of what instability if any should
+    # be resolved in order to resolve it. Example:
+    # dependencies = {3: [6], 6:[]}
+    # Means that: 6 has no dependency, 3 depends on 6 to be solved
+    dependencies = {}
+    # rdependencies is the inverted dict of dependencies
+    rdependencies = collections.defaultdict(set)
+
+    for r in revs:
+        dependencies[r] = set()
+        for p in repo[r].parents():
+            try:
+                succ = _singlesuccessor(repo, p)
+            except MultipleSuccessorsError as exc:
+                dependencies[r] = exc.successorssets
+                continue
+            if succ in revs:
+                dependencies[r].add(succ)
+                rdependencies[succ].add(r)
+    return dependencies, rdependencies
+
+def _dedupedivergents(repo, revs):
+    """Dedupe the divergents revs in revs to get one from each group with the
+    lowest revision numbers
+    """
+    repo = repo.unfiltered()
+    res = set()
+    # To not reevaluate divergents of the same group once one is encountered
+    discarded = set()
+    for rev in revs:
+        if rev in discarded:
+            continue
+        divergent = repo[rev]
+        base, others = divergentdata(divergent)
+        othersrevs = [o.rev() for o in others]
+        res.add(min([divergent.rev()] + othersrevs))
+        discarded.update(othersrevs)
+    return res
+
+def _selectrevs(repo, allopt, revopt, anyopt, targetcat):
+    """select troubles in repo matching according to given options"""
+    revs = set()
+    if allopt or revopt:
+        revs = repo.revs(targetcat+'()')
+        if revopt:
+            revs = scmutil.revrange(repo, revopt) & revs
+        elif not anyopt:
+            topic = getattr(repo, 'currenttopic', '')
+            if topic:
+                revs = repo.revs('topic(%s)', topic) & revs
+            elif targetcat == 'unstable':
+                revs = _aspiringdescendant(repo,
+                                           repo.revs('(.::) - obsolete()::'))
+                revs = set(revs)
+        if targetcat == 'divergent':
+            # Pick one divergent per group of divergents
+            revs = _dedupedivergents(repo, revs)
+    elif anyopt:
+        revs = repo.revs('first(%s())' % (targetcat))
+    elif targetcat == 'unstable':
+        revs = set(_aspiringchildren(repo, repo.revs('(.::) - obsolete()::')))
+        if 1 < len(revs):
+            msg = "multiple evolve candidates"
+            hint = (_("select one of %s with --rev")
+                    % ', '.join([str(repo[r]) for r in sorted(revs)]))
+            raise error.Abort(msg, hint=hint)
+    elif targetcat in repo['.'].troubles():
+        revs = set([repo['.'].rev()])
+    return revs
+
+
+def _orderrevs(repo, revs):
+    """Compute an ordering to solve instability for the given revs
+
+    revs is a list of unstable revisions.
+
+    Returns the same revisions ordered to solve their instability from the
+    bottom to the top of the stack that the stabilization process will produce
+    eventually.
+
+    This ensures the minimal number of stabilizations, as we can stabilize each
+    revision on its final stabilized destination.
+    """
+    # Step 1: Build the dependency graph
+    dependencies, rdependencies = builddependencies(repo, revs)
+    # Step 2: Build the ordering
+    # Remove the revisions with no dependency(A) and add them to the ordering.
+    # Removing these revisions leads to new revisions with no dependency (the
+    # one depending on A) that we can remove from the dependency graph and add
+    # to the ordering. We progress in a similar fashion until the ordering is
+    # built
+    solvablerevs = collections.deque([r for r in sorted(dependencies.keys())
+                                      if not dependencies[r]])
+    ordering = []
+    while solvablerevs:
+        rev = solvablerevs.popleft()
+        for dependent in rdependencies[rev]:
+            dependencies[dependent].remove(rev)
+            if not dependencies[dependent]:
+                solvablerevs.append(dependent)
+        del dependencies[rev]
+        ordering.append(rev)
+
+    ordering.extend(sorted(dependencies))
+    return ordering
+
+def divergentsets(repo, ctx):
+    """Compute sets of commits divergent with a given one"""
+    cache = {}
+    succsets = {}
+    base = {}
+    for n in obsolete.allprecursors(repo.obsstore, [ctx.node()]):
+        if n == ctx.node():
+            # a node can't be a base for divergence with itself
+            continue
+        nsuccsets = obsolete.successorssets(repo, n, cache)
+        for nsuccset in nsuccsets:
+            if ctx.node() in nsuccset:
+                # we are only interested in *other* successor sets
+                continue
+            if tuple(nsuccset) in base:
+                # we already know the latest base for this divergency
+                continue
+            base[tuple(nsuccset)] = n
+    divergence = []
+    for divset, b in base.iteritems():
+        divergence.append({
+            'divergentnodes': divset,
+            'commonprecursor': b
+        })
+
+    return divergence
+
+def _preparelistctxs(items, condition):
+    return [item.hex() for item in items if condition(item)]
+
+def _formatctx(fm, ctx):
+    fm.data(node=ctx.hex())
+    fm.data(desc=ctx.description())
+    fm.data(date=ctx.date())
+    fm.data(user=ctx.user())
+
+def listtroubles(ui, repo, troublecategories, **opts):
+    """Print all the troubles for the repo (or given revset)"""
+    troublecategories = troublecategories or ['divergent', 'unstable', 'bumped']
+    showunstable = 'unstable' in troublecategories
+    showbumped = 'bumped' in troublecategories
+    showdivergent = 'divergent' in troublecategories
+
+    revs = repo.revs('+'.join("%s()" % t for t in troublecategories))
+    if opts.get('rev'):
+        revs = revs & repo.revs(opts.get('rev'))
+
+    fm = ui.formatter('evolvelist', opts)
+    for rev in revs:
+        ctx = repo[rev]
+        unpars = _preparelistctxs(ctx.parents(), lambda p: p.unstable())
+        obspars = _preparelistctxs(ctx.parents(), lambda p: p.obsolete())
+        imprecs = _preparelistctxs(repo.set("allprecursors(%n)", ctx.node()),
+                                   lambda p: not p.mutable())
+        dsets = divergentsets(repo, ctx)
+
+        fm.startitem()
+        # plain formatter section
+        hashlen, desclen = 12, 60
+        desc = ctx.description()
+        if desc:
+            desc = desc.splitlines()[0]
+        desc = (desc[:desclen] + '...') if len(desc) > desclen else desc
+        fm.plain('%s: ' % ctx.hex()[:hashlen])
+        fm.plain('%s\n' % desc)
+        fm.data(node=ctx.hex(), rev=ctx.rev(), desc=desc, phase=ctx.phasestr())
+
+        for unpar in unpars if showunstable else []:
+            fm.plain('  unstable: %s (unstable parent)\n' % unpar[:hashlen])
+        for obspar in obspars if showunstable else []:
+            fm.plain('  unstable: %s (obsolete parent)\n' % obspar[:hashlen])
+        for imprec in imprecs if showbumped else []:
+            fm.plain('  bumped: %s (immutable precursor)\n' % imprec[:hashlen])
+
+        if dsets and showdivergent:
+            for dset in dsets:
+                fm.plain('  divergent: ')
+                first = True
+                for n in dset['divergentnodes']:
+                    t = "%s (%s)" if first else " %s (%s)"
+                    first = False
+                    fm.plain(t % (node.hex(n)[:hashlen], repo[n].phasestr()))
+                comprec = node.hex(dset['commonprecursor'])[:hashlen]
+                fm.plain(" (precursor %s)\n" % comprec)
+        fm.plain("\n")
+
+        # templater-friendly section
+        _formatctx(fm, ctx)
+        troubles = []
+        for unpar in unpars:
+            troubles.append({'troubletype': 'unstable', 'sourcenode': unpar,
+                             'sourcetype': 'unstableparent'})
+        for obspar in obspars:
+            troubles.append({'troubletype': 'unstable', 'sourcenode': obspar,
+                             'sourcetype': 'obsoleteparent'})
+        for imprec in imprecs:
+            troubles.append({'troubletype': 'bumped', 'sourcenode': imprec,
+                             'sourcetype': 'immutableprecursor'})
+        for dset in dsets:
+            divnodes = [{'node': node.hex(n),
+                         'phase': repo[n].phasestr(),
+                        } for n in dset['divergentnodes']]
+            troubles.append({'troubletype': 'divergent',
+                             'commonprecursor': node.hex(dset['commonprecursor']),
+                             'divergentnodes': divnodes})
+        fm.data(troubles=troubles)
+
+    fm.end()
+
+@command('^evolve|stabilize|solve',
+    [('n', 'dry-run', False,
+        _('do not perform actions, just print what would be done')),
+     ('', 'confirm', False,
+        _('ask for confirmation before performing the action')),
+    ('A', 'any', False,
+        _('also consider troubled changesets unrelated to current working '
+          'directory')),
+    ('r', 'rev', [], _('solves troubles of these revisions')),
+    ('', 'bumped', False, _('solves only bumped changesets')),
+    ('', 'divergent', False, _('solves only divergent changesets')),
+    ('', 'unstable', False, _('solves only unstable changesets (default)')),
+    ('a', 'all', False, _('evolve all troubled changesets related to the '
+                          'current  working directory and its descendants')),
+    ('c', 'continue', False, _('continue an interrupted evolution')),
+    ('l', 'list', False, 'provide details on troubled changesets in the repo'),
+    ] + mergetoolopts,
+    _('[OPTIONS]...'))
+def evolve(ui, repo, **opts):
+    """solve troubled changesets in your repository
+
+    Modifying history can lead to various types of troubled changesets:
+    unstable, bumped, or divergent. The evolve command resolves your troubles
+    by executing one of the following actions:
+
+    - update working copy to a successor
+    - rebase an unstable changeset
+    - extract the desired changes from a bumped changeset
+    - fuse divergent changesets back together
+
+    If you pass no arguments, evolve works in automatic mode: it will execute a
+    single action to reduce instability related to your working copy. There are
+    two cases for this action. First, if the parent of your working copy is
+    obsolete, evolve updates to the parent's successor. Second, if the working
+    copy parent is not obsolete but has obsolete predecessors, then evolve
+    determines if there is an unstable changeset that can be rebased onto the
+    working copy parent in order to reduce instability.
+    If so, evolve rebases that changeset. If not, evolve refuses to guess your
+    intention, and gives a hint about what you might want to do next.
+
+    Any time evolve creates a changeset, it updates the working copy to the new
+    changeset. (Currently, every successful evolve operation involves an update
+    as well; this may change in future.)
+
+    Automatic mode only handles common use cases. For example, it avoids taking
+    action in the case of ambiguity, and it ignores unstable changesets that
+    are not related to your working copy.
+    It also refuses to solve bumped or divergent changesets unless you explicity
+    request such behavior (see below).
+
+    Eliminating all instability around your working copy may require multiple
+    invocations of :hg:`evolve`. Alternately, use ``--all`` to recursively
+    select and evolve all unstable changesets that can be rebased onto the
+    working copy parent.
+    This is more powerful than successive invocations, since ``--all`` handles
+    ambiguous cases (e.g. unstable changesets with multiple children) by
+    evolving all branches.
+
+    When your repository cannot be handled by automatic mode, you might need to
+    use ``--rev`` to specify a changeset to evolve. For example, if you have
+    an unstable changeset that is not related to the working copy parent,
+    you could use ``--rev`` to evolve it. Or, if some changeset has multiple
+    unstable children, evolve in automatic mode refuses to guess which one to
+    evolve; you have to use ``--rev`` in that case.
+
+    Alternately, ``--any`` makes evolve search for the next evolvable changeset
+    regardless of whether it is related to the working copy parent.
+
+    You can supply multiple revisions to evolve multiple troubled changesets
+    in a single invocation. In revset terms, ``--any`` is equivalent to ``--rev
+    first(unstable())``. ``--rev`` and ``--all`` are mutually exclusive, as are
+    ``--rev`` and ``--any``.
+
+    ``hg evolve --any --all`` is useful for cleaning up instability across all
+    branches, letting evolve figure out the appropriate order and destination.
+
+    When you have troubled changesets that are not unstable, :hg:`evolve`
+    refuses to consider them unless you specify the category of trouble you
+    wish to resolve, with ``--bumped`` or ``--divergent``. These options are
+    currently mutually exclusive with each other and with ``--unstable``
+    (the default). You can combine ``--bumped`` or ``--divergent`` with
+    ``--rev``, ``--all``, or ``--any``.
+
+    You can also use the evolve command to list the troubles affecting your
+    repository by using the --list flag. You can choose to display only some
+    categories of troubles with the --unstable, --divergent or --bumped flags.
+    """
+
+    # Options
+    listopt = opts['list']
+    contopt = opts['continue']
+    anyopt = opts['any']
+    allopt = opts['all']
+    startnode = repo['.']
+    dryrunopt = opts['dry_run']
+    confirmopt = opts['confirm']
+    revopt = opts['rev']
+    troublecategories = ['bumped', 'divergent', 'unstable']
+    specifiedcategories = [t for t in troublecategories if opts[t]]
+    if listopt:
+        listtroubles(ui, repo, specifiedcategories, **opts)
+        return
+
+    targetcat = 'unstable'
+    if 1 < len(specifiedcategories):
+        msg = _('cannot specify more than one trouble category to solve (yet)')
+        raise error.Abort(msg)
+    elif len(specifiedcategories) == 1:
+        targetcat = specifiedcategories[0]
+    elif repo['.'].obsolete():
+        displayer = cmdutil.show_changeset(ui, repo,
+                                           {'template': shorttemplate})
+        # no args and parent is obsolete, update to successors
+        try:
+            ctx = repo[_singlesuccessor(repo, repo['.'])]
+        except MultipleSuccessorsError as exc:
+            repo.ui.write_err('parent is obsolete with multiple successors:\n')
+            for ln in exc.successorssets:
+                for n in ln:
+                    displayer.show(repo[n])
+            return 2
+
+
+        ui.status(_('update:'))
+        if not ui.quiet:
+            displayer.show(ctx)
+
+        if dryrunopt:
+            return 0
+        res = hg.update(repo, ctx.rev())
+        if ctx != startnode:
+            ui.status(_('working directory is now at %s\n') % ctx)
+        return res
+
+    ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve')
+    troubled = set(repo.revs('troubled()'))
+
+    # Progress handling
+    seen = 1
+    count = allopt and len(troubled) or 1
+    showprogress = allopt
+
+    def progresscb():
+        if revopt or allopt:
+            ui.progress(_('evolve'), seen, unit=_('changesets'), total=count)
+
+    # Continuation handling
+    if contopt:
+        if anyopt:
+            raise error.Abort('cannot specify both "--any" and "--continue"')
+        if allopt:
+            raise error.Abort('cannot specify both "--all" and "--continue"')
+        state = _evolvestateread(repo)
+        if state is None:
+            raise error.Abort('no evolve to continue')
+        orig = repo[state['current']]
+        # XXX This is a terrible terrible hack, please get rid of it.
+        lock = repo.wlock()
+        try:
+            repo.opener.write('graftstate', orig.hex() + '\n')
+            try:
+                graftcmd = commands.table['graft'][0]
+                ret = graftcmd(ui, repo, old_obsolete=True, **{'continue': True})
+                _evolvestatedelete(repo)
+                return ret
+            finally:
+                util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
+        finally:
+            lock.release()
+    cmdutil.bailifchanged(repo)
+
+
+    if revopt and allopt:
+        raise error.Abort('cannot specify both "--rev" and "--all"')
+    if revopt and anyopt:
+        raise error.Abort('cannot specify both "--rev" and "--any"')
+
+    revs = _selectrevs(repo, allopt, revopt, anyopt, targetcat)
+
+    if not revs:
+        return _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat)
+
+    # For the progress bar to show
+    count = len(revs)
+    # Order the revisions
+    if targetcat == 'unstable':
+        revs = _orderrevs(repo, revs)
+    for rev in revs:
+        progresscb()
+        _solveone(ui, repo, repo[rev], dryrunopt, confirmopt,
+                progresscb, targetcat)
+        seen += 1
+    progresscb()
+    _cleanup(ui, repo, startnode, showprogress)
+
+def _possibledestination(repo, rev):
+    """return all changesets that may be a new parent for REV"""
+    tonode = repo.changelog.node
+    parents = repo.changelog.parentrevs
+    torev = repo.changelog.rev
+    dest = set()
+    tovisit = list(parents(rev))
+    while tovisit:
+        r = tovisit.pop()
+        succsets = obsolete.successorssets(repo, tonode(r))
+        if not succsets:
+            tovisit.extend(parents(r))
+        else:
+            # We should probably pick only one destination from split
+            # (case where '1 < len(ss)'), This could be the currently tipmost
+            # but logic is less clear when result of the split are now on
+            # multiple branches.
+            for ss in succsets:
+                for n in ss:
+                    dest.add(torev(n))
+    return dest
+
+def _aspiringchildren(repo, revs):
+    """Return a list of changectx which can be stabilized on top of pctx or
+    one of its descendants. Empty list if none can be found."""
+    target = set(revs)
+    result = []
+    for r in repo.revs('unstable() - %ld', revs):
+        dest = _possibledestination(repo, r)
+        if target & dest:
+            result.append(r)
+    return result
+
+def _aspiringdescendant(repo, revs):
+    """Return a list of changectx which can be stabilized on top of pctx or
+    one of its descendants recursively. Empty list if none can be found."""
+    target = set(revs)
+    result = set(target)
+    paths = collections.defaultdict(set)
+    for r in repo.revs('unstable() - %ld', revs):
+        for d in _possibledestination(repo, r):
+            paths[d].add(r)
+
+    result = set(target)
+    tovisit = list(revs)
+    while tovisit:
+        base = tovisit.pop()
+        for unstable in paths[base]:
+            if unstable not in result:
+                tovisit.append(unstable)
+                result.add(unstable)
+    return sorted(result - target)
+
+def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,
+                   progresscb=None):
+    """Stabilize an unstable changeset"""
+    pctx = orig.p1()
+    if len(orig.parents()) == 2:
+        if not pctx.obsolete():
+            pctx = orig.p2()  # second parent is obsolete ?
+        elif orig.p2().obsolete():
+            hint = _("Redo the merge (%s) and use `hg prune <old> "
+                     "--succ <new>` to obsolete the old one") % orig.hex()[:12]
+            ui.warn(_("warning: no support for evolving merge changesets "
+                      "with two obsolete parents yet\n") +
+                    _("(%s)\n") % hint)
+            return False
+
+    if not pctx.obsolete():
+        ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
+        return False
+    obs = pctx
+    newer = obsolete.successorssets(repo, obs.node())
+    # search of a parent which is not killed
+    while not newer or newer == [()]:
+        ui.debug("stabilize target %s is plain dead,"
+                 " trying to stabilize on its parent\n" %
+                 obs)
+        obs = obs.parents()[0]
+        newer = obsolete.successorssets(repo, obs.node())
+    if len(newer) > 1:
+        msg = _("skipping %s: divergent rewriting. can't choose "
+                "destination\n") % obs
+        ui.write_err(msg)
+        return 2
+    targets = newer[0]
+    assert targets
+    if len(targets) > 1:
+        # split target, figure out which one to pick, are they all in line?
+        targetrevs = [repo[r].rev() for r in targets]
+        roots = repo.revs('roots(%ld)', targetrevs)
+        heads = repo.revs('heads(%ld)', targetrevs)
+        if len(roots) > 1 or len(heads) > 1:
+            msg = "cannot solve split accross two branches\n"
+            ui.write_err(msg)
+            return 2
+        target = repo[heads.first()]
+    else:
+        target = targets[0]
+    displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+    target = repo[target]
+    if not ui.quiet or confirm:
+        repo.ui.write(_('move:'))
+        displayer.show(orig)
+        repo.ui.write(_('atop:'))
+        displayer.show(target)
+    if confirm and ui.prompt('perform evolve? [Ny]', 'n') != 'y':
+            raise error.Abort(_('evolve aborted by user'))
+    if progresscb: progresscb()
+    todo = 'hg rebase -r %s -d %s\n' % (orig, target)
+    if dryrun:
+        repo.ui.write(todo)
+    else:
+        repo.ui.note(todo)
+        if progresscb: progresscb()
+        keepbranch = orig.p1().branch() != orig.branch()
+        try:
+            relocate(repo, orig, target, pctx, keepbranch)
+        except MergeFailure:
+            _evolvestatewrite(repo, {'current': orig.node()})
+            repo.ui.write_err(_('evolve failed!\n'))
+            repo.ui.write_err(
+                _("fix conflict and run 'hg evolve --continue'"
+                  " or use 'hg update -C .' to abort\n"))
+            raise
+
+def _solvebumped(ui, repo, bumped, dryrun=False, confirm=False,
+                 progresscb=None):
+    """Stabilize a bumped changeset"""
+    repo = repo.unfiltered()
+    bumped = repo[bumped.rev()]
+    # For now we deny bumped merge
+    if len(bumped.parents()) > 1:
+        msg = _('skipping %s : we do not handle merge yet\n') % bumped
+        ui.write_err(msg)
+        return 2
+    prec = repo.set('last(allprecursors(%d) and public())', bumped).next()
+    # For now we deny target merge
+    if len(prec.parents()) > 1:
+        msg = _('skipping: %s: public version is a merge, '
+                'this is not handled yet\n') % prec
+        ui.write_err(msg)
+        return 2
+
+    displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+    if not ui.quiet or confirm:
+        repo.ui.write(_('recreate:'))
+        displayer.show(bumped)
+        repo.ui.write(_('atop:'))
+        displayer.show(prec)
+    if confirm and ui.prompt('perform evolve? [Ny]', 'n') != 'y':
+        raise error.Abort(_('evolve aborted by user'))
+    if dryrun:
+        todo = 'hg rebase --rev %s --dest %s;\n' % (bumped, prec.p1())
+        repo.ui.write(todo)
+        repo.ui.write(('hg update %s;\n' % prec))
+        repo.ui.write(('hg revert --all --rev %s;\n' % bumped))
+        repo.ui.write(('hg commit --msg "bumped update to %s"'))
+        return 0
+    if progresscb: progresscb()
+    newid = tmpctx = None
+    tmpctx = bumped
+    # Basic check for common parent. Far too complicated and fragile
+    tr = repo.currenttransaction()
+    assert tr is not None
+    bmupdate = _bookmarksupdater(repo, bumped.node(), tr)
+    if not list(repo.set('parents(%d) and parents(%d)', bumped, prec)):
+        # Need to rebase the changeset at the right place
+        repo.ui.status(
+            _('rebasing to destination parent: %s\n') % prec.p1())
+        try:
+            tmpid = relocate(repo, bumped, prec.p1())
+            if tmpid is not None:
+                tmpctx = repo[tmpid]
+                obsolete.createmarkers(repo, [(bumped, (tmpctx,))])
+        except MergeFailure:
+            repo.opener.write('graftstate', bumped.hex() + '\n')
+            repo.ui.write_err(_('evolution failed!\n'))
+            repo.ui.write_err(
+                _("fix conflict and run 'hg evolve --continue'\n"))
+            raise
+    # Create the new commit context
+    repo.ui.status(_('computing new diff\n'))
+    files = set()
+    copied = copies.pathcopies(prec, bumped)
+    precmanifest = prec.manifest().copy()
+    # 3.3.2 needs a list.
+    # future 3.4 don't detect the size change during iteration
+    # this is fishy
+    for key, val in list(bumped.manifest().iteritems()):
+        precvalue = precmanifest.get(key, None)
+        if precvalue is not None:
+            del precmanifest[key]
+        if precvalue != val:
+            files.add(key)
+    files.update(precmanifest)  # add missing files
+    # commit it
+    if files: # something to commit!
+        def filectxfn(repo, ctx, path):
+            if path in bumped:
+                fctx = bumped[path]
+                flags = fctx.flags()
+                mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
+                                          islink='l' in flags,
+                                          isexec='x' in flags,
+                                          copied=copied.get(path))
+                return mctx
+            return None
+        text = 'bumped update to %s:\n\n' % prec
+        text += bumped.description()
+
+        new = context.memctx(repo,
+                             parents=[prec.node(), node.nullid],
+                             text=text,
+                             files=files,
+                             filectxfn=filectxfn,
+                             user=bumped.user(),
+                             date=bumped.date(),
+                             extra=bumped.extra())
+
+        newid = repo.commitctx(new)
+    if newid is None:
+        obsolete.createmarkers(repo, [(tmpctx, ())])
+        newid = prec.node()
+    else:
+        phases.retractboundary(repo, tr, bumped.phase(), [newid])
+        obsolete.createmarkers(repo, [(tmpctx, (repo[newid],))],
+                               flag=obsolete.bumpedfix)
+    bmupdate(newid)
+    repo.ui.status(_('committed as %s\n') % node.short(newid))
+    # reroute the working copy parent to the new changeset
+    repo.dirstate.beginparentchange()
+    repo.dirstate.setparents(newid, node.nullid)
+    repo.dirstate.endparentchange()
+
+def _solvedivergent(ui, repo, divergent, dryrun=False, confirm=False,
+                    progresscb=None):
+    repo = repo.unfiltered()
+    divergent = repo[divergent.rev()]
+    base, others = divergentdata(divergent)
+    if len(others) > 1:
+        othersstr = "[%s]" % (','.join([str(i) for i in others]))
+        msg = _("skipping %d:divergent with a changeset that got splitted"
+                " into multiple ones:\n"
+                 "|[%s]\n"
+                 "| This is not handled by automatic evolution yet\n"
+                 "| You have to fallback to manual handling with commands "
+                 "such as:\n"
+                 "| - hg touch -D\n"
+                 "| - hg prune\n"
+                 "| \n"
+                 "| You should contact your local evolution Guru for help.\n"
+                 ) % (divergent, othersstr)
+        ui.write_err(msg)
+        return 2
+    other = others[0]
+    if len(other.parents()) > 1:
+        msg = _("skipping %s: divergent changeset can't be "
+                "a merge (yet)\n") % divergent
+        ui.write_err(msg)
+        hint = _("You have to fallback to solving this by hand...\n"
+                 "| This probably means redoing the merge and using \n"
+                 "| `hg prune` to kill older version.\n")
+        ui.write_err(hint)
+        return 2
+    if other.p1() not in divergent.parents():
+        msg = _("skipping %s: have a different parent than %s "
+                "(not handled yet)\n") % (divergent, other)
+        hint = _("| %(d)s, %(o)s are not based on the same changeset.\n"
+                 "| With the current state of its implementation, \n"
+                 "| evolve does not work in that case.\n"
+                 "| rebase one of them next to the other and run \n"
+                 "| this command again.\n"
+                 "| - either: hg rebase --dest 'p1(%(d)s)' -r %(o)s\n"
+                 "| - or:     hg rebase --dest 'p1(%(o)s)' -r %(d)s\n"
+                 ) % {'d': divergent, 'o': other}
+        ui.write_err(msg)
+        ui.write_err(hint)
+        return 2
+
+    displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+    if not ui.quiet or confirm:
+        ui.write(_('merge:'))
+        displayer.show(divergent)
+        ui.write(_('with: '))
+        displayer.show(other)
+        ui.write(_('base: '))
+        displayer.show(base)
+    if confirm and ui.prompt(_('perform evolve? [Ny]'), 'n') != 'y':
+        raise error.Abort(_('evolve aborted by user'))
+    if dryrun:
+        ui.write(('hg update -c %s &&\n' % divergent))
+        ui.write(('hg merge %s &&\n' % other))
+        ui.write(('hg commit -m "auto merge resolving conflict between '
+                 '%s and %s"&&\n' % (divergent, other)))
+        ui.write(('hg up -C %s &&\n' % base))
+        ui.write(('hg revert --all --rev tip &&\n'))
+        ui.write(('hg commit -m "`hg log -r %s --template={desc}`";\n'
+                 % divergent))
+        return
+    if divergent not in repo[None].parents():
+        repo.ui.status(_('updating to "local" conflict\n'))
+        hg.update(repo, divergent.rev())
+    repo.ui.note(_('merging divergent changeset\n'))
+    if progresscb: progresscb()
+    stats = merge.update(repo,
+                         other.node(),
+                         branchmerge=True,
+                         force=False,
+                         ancestor=base.node(),
+                         mergeancestor=True)
+    hg._showstats(repo, stats)
+    if stats[3]:
+        repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
+                         "or 'hg update -C .' to abort\n"))
+    if stats[3] > 0:
+        raise error.Abort('merge conflict between several amendments '
+            '(this is not automated yet)',
+            hint="""/!\ You can try:
+/!\ * manual merge + resolve => new cset X
+/!\ * hg up to the parent of the amended changeset (which are named W and Z)
+/!\ * hg revert --all -r X
+/!\ * hg ci -m "same message as the amended changeset" => new cset Y
+/!\ * hg prune -n Y W Z
+""")
+    if progresscb: progresscb()
+    emtpycommitallowed = repo.ui.backupconfig('ui', 'allowemptycommit')
+    tr = repo.currenttransaction()
+    assert tr is not None
+    try:
+        repo.ui.setconfig('ui', 'allowemptycommit', True, 'evolve')
+        repo.dirstate.beginparentchange()
+        repo.dirstate.setparents(divergent.node(), node.nullid)
+        repo.dirstate.endparentchange()
+        oldlen = len(repo)
+        amend(ui, repo, message='', logfile='')
+        if oldlen == len(repo):
+            new = divergent
+            # no changes
+        else:
+            new = repo['.']
+        obsolete.createmarkers(repo, [(other, (new,))])
+        phases.retractboundary(repo, tr, other.phase(), [new.node()])
+    finally:
+        repo.ui.restoreconfig(emtpycommitallowed)
+
+def divergentdata(ctx):
+    """return base, other part of a conflict
+
+    This only return the first one.
+
+    XXX this woobly function won't survive XXX
+    """
+    repo = ctx._repo.unfiltered()
+    for base in repo.set('reverse(allprecursors(%d))', ctx):
+        newer = obsolete.successorssets(ctx._repo, base.node())
+        # drop filter and solution including the original ctx
+        newer = [n for n in newer if n and ctx.node() not in n]
+        if newer:
+            return base, tuple(ctx._repo[o] for o in newer[0])
+    raise error.Abort("base of divergent changeset %s not found" % ctx,
+                     hint='this case is not yet handled')
+
+
+
+shorttemplate = '[{rev}] {desc|firstline}\n'
+
+@command('^previous',
+         [('B', 'move-bookmark', False,
+             _('move active bookmark after update')),
+          ('', 'merge', False, _('bring uncommitted change along')),
+          ('', 'no-topic', False, _('ignore topic and move topologically')),
+          ('n', 'dry-run', False,
+             _('do not perform actions, just print what would be done'))],
+         '[OPTION]...')
+def cmdprevious(ui, repo, **opts):
+    """update to parent revision
+
+    Displays the summary line of the destination for clarity."""
+    wlock = None
+    dryrunopt = opts['dry_run']
+    if not dryrunopt:
+        wlock = repo.wlock()
+    try:
+        wkctx = repo[None]
+        wparents = wkctx.parents()
+        if len(wparents) != 1:
+            raise error.Abort('merge in progress')
+        if not opts['merge']:
+            try:
+                cmdutil.bailifchanged(repo)
+            except error.Abort as exc:
+                exc.hint = _('do you want --merge?')
+                raise
+
+        parents = wparents[0].parents()
+        topic = getattr(repo, 'currenttopic', '')
+        if topic and not opts.get("no_topic", False):
+            parents = [ctx for ctx in parents if ctx.topic() == topic]
+        displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+        if not parents:
+            ui.warn(_('no parent in topic "%s"\n') % topic)
+            ui.warn(_('(do you want --no-topic)\n'))
+        elif len(parents) == 1:
+            p = parents[0]
+            bm = repo._activebookmark
+            shouldmove = opts.get('move_bookmark') and bm is not None
+            if dryrunopt:
+                ui.write(('hg update %s;\n' % p.rev()))
+                if shouldmove:
+                    ui.write(('hg bookmark %s -r %s;\n' % (bm, p.rev())))
+            else:
+                ret = hg.update(repo, p.rev())
+                if not ret:
+                    tr = lock = None
+                    try:
+                        lock = repo.lock()
+                        tr = repo.transaction('previous')
+                        if shouldmove:
+                            repo._bookmarks[bm] = p.node()
+                            repo._bookmarks.recordchange(tr)
+                        else:
+                            bookmarksmod.deactivate(repo)
+                        tr.close()
+                    finally:
+                        lockmod.release(tr, lock)
+
+            displayer.show(p)
+            return 0
+        else:
+            for p in parents:
+                displayer.show(p)
+            ui.warn(_('multiple parents, explicitly update to one\n'))
+            return 1
+    finally:
+        lockmod.release(wlock)
+
+@command('^next',
+         [('B', 'move-bookmark', False,
+             _('move active bookmark after update')),
+          ('', 'merge', False, _('bring uncommitted change along')),
+          ('', 'evolve', False, _('evolve the next changeset if necessary')),
+          ('', 'no-topic', False, _('ignore topic and move topologically')),
+          ('n', 'dry-run', False,
+              _('do not perform actions, just print what would be done'))],
+              '[OPTION]...')
+def cmdnext(ui, repo, **opts):
+    """update to next child revision
+
+    Use the ``--evolve`` flag to evolve unstable children on demand.
+
+    Displays the summary line of the destination for clarity.
+    """
+    wlock = None
+    dryrunopt = opts['dry_run']
+    if not dryrunopt:
+        wlock = repo.wlock()
+    try:
+        wkctx = repo[None]
+        wparents = wkctx.parents()
+        if len(wparents) != 1:
+            raise error.Abort('merge in progress')
+        if not opts['merge']:
+            try:
+                cmdutil.bailifchanged(repo)
+            except error.Abort as exc:
+                exc.hint = _('do you want --merge?')
+                raise
+
+        children = [ctx for ctx in wparents[0].children() if not ctx.obsolete()]
+        topic = getattr(repo, 'currenttopic', '')
+        filtered = []
+        if topic and not opts.get("no_topic", False):
+            filtered = [ctx for ctx in children if ctx.topic() != topic]
+            # XXX N-square membership on children
+            children = [ctx for ctx in children if ctx not in filtered]
+        displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+        if len(children) == 1:
+            c = children[0]
+            bm = repo._activebookmark
+            shouldmove = opts.get('move_bookmark') and bm is not None
+            if dryrunopt:
+                ui.write(('hg update %s;\n' % c.rev()))
+                if shouldmove:
+                    ui.write(('hg bookmark %s -r %s;\n' % (bm, c.rev())))
+            else:
+                ret = hg.update(repo, c.rev())
+                if not ret:
+                    lock = tr = None
+                    try:
+                        lock = repo.lock()
+                        tr = repo.transaction('next')
+                        if shouldmove:
+                            repo._bookmarks[bm] = c.node()
+                            repo._bookmarks.recordchange(tr)
+                        else:
+                            bookmarksmod.deactivate(repo)
+                        tr.close()
+                    finally:
+                        lockmod.release(tr, lock)
+            displayer.show(c)
+            result = 0
+        elif children:
+            ui.warn(_("ambigious next changeset:\n"))
+            for c in children:
+                displayer.show(c)
+            ui.warn(_('explicitly update to one of them\n'))
+            result = 1
+        else:
+            aspchildren = _aspiringchildren(repo, [repo['.'].rev()])
+            if topic:
+                filtered.extend(repo[c] for c in children
+                                if repo[c].topic() != topic)
+                # XXX N-square membership on children
+                aspchildren = [ctx for ctx in aspchildren if ctx not in filtered]
+            if not opts['evolve'] or not aspchildren:
+                if filtered:
+                    ui.warn(_('no children on topic "%s"\n') % topic)
+                    ui.warn(_('do you want --no-topic\n'))
+                else:
+                    ui.warn(_('no children\n'))
+                if aspchildren:
+                    msg = _('(%i unstable changesets to be evolved here, '
+                            'do you want --evolve?)\n')
+                    ui.warn(msg % len(aspchildren))
+                result = 1
+            elif 1 < len(aspchildren):
+                ui.warn(_("ambigious next (unstable) changeset:\n"))
+                for c in aspchildren:
+                    displayer.show(repo[c])
+                ui.warn(_("(run 'hg evolve --rev REV' on one of them)\n"))
+                return 1
+            else:
+                cmdutil.bailifchanged(repo)
+                result = _solveone(ui, repo, repo[aspchildren[0]], dryrunopt,
+                                   False, lambda:None, category='unstable')
+                if not result:
+                    ui.status(_('working directory now at %s\n') % repo['.'])
+                return result
+            return 1
+        return result
+    finally:
+        lockmod.release(wlock)
+
+def _reachablefrombookmark(repo, revs, bookmarks):
+    """filter revisions and bookmarks reachable from the given bookmark
+    yoinked from mq.py
+    """
+    repomarks = repo._bookmarks
+    if not bookmarks.issubset(repomarks):
+        raise error.Abort(_("bookmark '%s' not found") %
+            ','.join(sorted(bookmarks - set(repomarks.keys()))))
+
+    # If the requested bookmark is not the only one pointing to a
+    # a revision we have to only delete the bookmark and not strip
+    # anything. revsets cannot detect that case.
+    nodetobookmarks = {}
+    for mark, node in repomarks.iteritems():
+        nodetobookmarks.setdefault(node, []).append(mark)
+    for marks in nodetobookmarks.values():
+        if bookmarks.issuperset(marks):
+           rsrevs = repair.stripbmrevset(repo, marks[0])
+           revs = set(revs)
+           revs.update(set(rsrevs))
+           revs = sorted(revs)
+    return repomarks, revs
+
+def _deletebookmark(repo, repomarks, bookmarks):
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction('prune')
+        for bookmark in bookmarks:
+            del repomarks[bookmark]
+        repomarks.recordchange(tr)
+        tr.close()
+        for bookmark in sorted(bookmarks):
+            repo.ui.write(_("bookmark '%s' deleted\n") % bookmark)
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+
+
+def _getmetadata(**opts):
+    metadata = {}
+    date = opts.get('date')
+    user = opts.get('user')
+    if date:
+        metadata['date'] = '%i %i' % util.parsedate(date)
+    if user:
+        metadata['user'] = user
+    return metadata
+
+
+@command('^prune|obsolete',
+    [('n', 'new', [], _("successor changeset (DEPRECATED)")),
+     ('s', 'succ', [], _("successor changeset")),
+     ('r', 'rev', [], _("revisions to prune")),
+     ('k', 'keep', None, _("does not modify working copy during prune")),
+     ('', 'biject', False, _("do a 1-1 map between rev and successor ranges")),
+     ('', 'fold', False,
+        _("record a fold (multiple precursors, one successors)")),
+     ('', 'split', False,
+        _("record a split (on precursor, multiple successors)")),
+     ('B', 'bookmark', [], _("remove revs only reachable from given"
+                             " bookmark"))] + metadataopts,
+    _('[OPTION] [-r] REV...'))
+    # -U  --noupdate option to prevent wc update and or bookmarks update ?
+def cmdprune(ui, repo, *revs, **opts):
+    """hide changesets by marking them obsolete
+
+    Pruned changesets are obsolete with no successors. If they also have no
+    descendants, they are hidden (invisible to all commands).
+
+    Non-obsolete descendants of pruned changesets become "unstable". Use :hg:`evolve`
+    to handle this situation.
+
+    When you prune the parent of your working copy, Mercurial updates the working
+    copy to a non-obsolete parent.
+
+    You can use ``--succ`` to tell Mercurial that a newer version (successor) of the
+    pruned changeset exists. Mercurial records successor revisions in obsolescence
+    markers.
+
+    You can use the ``--biject`` option to specify a 1-1 mapping (bijection) between
+    revisions to pruned (precursor) and successor changesets. This option may be
+    removed in a future release (with the functionality provided automatically).
+
+    If you specify multiple revisions in ``--succ``, you are recording a "split" and
+    must acknowledge it by passing ``--split``. Similarly, when you prune multiple
+    changesets with a single successor, you must pass the ``--fold`` option.
+    """
+    revs = scmutil.revrange(repo, list(revs) + opts.get('rev'))
+    succs = opts['new'] + opts['succ']
+    bookmarks = set(opts.get('bookmark'))
+    metadata = _getmetadata(**opts)
+    biject = opts.get('biject')
+    fold = opts.get('fold')
+    split = opts.get('split')
+
+    options = [o for o in ('biject', 'fold', 'split') if opts.get(o)]
+    if 1 < len(options):
+        raise error.Abort(_("can only specify one of %s") % ', '.join(options))
+
+    if bookmarks:
+        repomarks, revs = _reachablefrombookmark(repo, revs, bookmarks)
+        if not revs:
+            # no revisions to prune - delete bookmark immediately
+            _deletebookmark(repo, repomarks, bookmarks)
+
+    if not revs:
+        raise error.Abort(_('nothing to prune'))
+
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction('prune')
+        # defines pruned changesets
+        precs = []
+        revs.sort()
+        for p in revs:
+            cp = repo[p]
+            if not cp.mutable():
+                # note: createmarkers() would have raised something anyway
+                raise error.Abort('cannot prune immutable changeset: %s' % cp,
+                                 hint="see 'hg help phases' for details")
+            precs.append(cp)
+        if not precs:
+            raise error.Abort('nothing to prune')
+
+        if _disallowednewunstable(repo, revs):
+            raise error.Abort(_("cannot prune in the middle of a stack"),
+                        hint = _("new unstable changesets are not allowed"))
+
+        # defines successors changesets
+        sucs = scmutil.revrange(repo, succs)
+        sucs.sort()
+        sucs = tuple(repo[n] for n in sucs)
+        if not biject and len(sucs) > 1 and len(precs) > 1:
+            msg = "Can't use multiple successors for multiple precursors"
+            hint = _("use --biject to mark a series as a replacement"
+                     " for another")
+            raise error.Abort(msg, hint=hint)
+        elif biject and len(sucs) != len(precs):
+            msg = "Can't use %d successors for %d precursors" \
+                % (len(sucs), len(precs))
+            raise error.Abort(msg)
+        elif (len(precs) == 1 and len(sucs) > 1) and not split:
+            msg = "please add --split if you want to do a split"
+            raise error.Abort(msg)
+        elif len(sucs) == 1 and len(precs) > 1 and not fold:
+            msg = "please add --fold if you want to do a fold"
+            raise error.Abort(msg)
+        elif biject:
+            relations = [(p, (s,)) for p, s in zip(precs, sucs)]
+        else:
+            relations = [(p, sucs) for p in precs]
+
+        wdp = repo['.']
+
+        if len(sucs) == 1 and len(precs) == 1 and wdp in precs:
+            # '.' killed, so update to the successor
+            newnode = sucs[0]
+        else:
+            # update to an unkilled parent
+            newnode = wdp
+
+            while newnode in precs or newnode.obsolete():
+                newnode = newnode.parents()[0]
+
+
+        if newnode.node() != wdp.node():
+            if opts.get('keep', False):
+                # This is largely the same as the implementation in
+                # strip.stripcmd(). We might want to refactor this somewhere
+                # common at some point.
+
+                # only reset the dirstate for files that would actually change
+                # between the working context and uctx
+                descendantrevs = repo.revs("%d::." % newnode.rev())
+                changedfiles = []
+                for rev in descendantrevs:
+                    # blindly reset the files, regardless of what actually
+                    # changed
+                    changedfiles.extend(repo[rev].files())
+
+                # reset files that only changed in the dirstate too
+                dirstate = repo.dirstate
+                dirchanges = [f for f in dirstate if dirstate[f] != 'n']
+                changedfiles.extend(dirchanges)
+                repo.dirstate.rebuild(newnode.node(), newnode.manifest(),
+                                      changedfiles)
+                dirstate.write(tr)
+            else:
+                bookactive = repo._activebookmark
+                # Active bookmark that we don't want to delete (with -B option)
+                # we deactivate and move it before the update and reactivate it
+                # after
+                movebookmark = bookactive and not bookmarks
+                if movebookmark:
+                    bookmarksmod.deactivate(repo)
+                    repo._bookmarks[bookactive] = newnode.node()
+                    repo._bookmarks.recordchange(tr)
+                commands.update(ui, repo, newnode.rev())
+                ui.status(_('working directory now at %s\n') % newnode)
+                if movebookmark:
+                    bookmarksmod.activate(repo, bookactive)
+
+        # update bookmarks
+        if bookmarks:
+            _deletebookmark(repo, repomarks, bookmarks)
+
+        # create markers
+        obsolete.createmarkers(repo, relations, metadata=metadata)
+
+        # informs that changeset have been pruned
+        ui.status(_('%i changesets pruned\n') % len(precs))
+
+        for ctx in repo.unfiltered().set('bookmark() and %ld', precs):
+            # used to be:
+            #
+            #   ldest = list(repo.set('max((::%d) - obsolete())', ctx))
+            #   if ldest:
+            #      c = ldest[0]
+            #
+            # but then revset took a lazy arrow in the knee and became much
+            # slower. The new forms makes as much sense and a much faster.
+            for dest in ctx.ancestors():
+                if not dest.obsolete():
+                    updatebookmarks = _bookmarksupdater(repo, ctx.node(), tr)
+                    updatebookmarks(dest.node())
+                    break
+
+        tr.close()
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+@command('amend|refresh',
+    [('A', 'addremove', None,
+     _('mark new/missing files as added/removed before committing')),
+    ('e', 'edit', False, _('invoke editor on commit messages')),
+    ('', 'close-branch', None,
+     _('mark a branch as closed, hiding it from the branch list')),
+    ('s', 'secret', None, _('use the secret phase for committing')),
+    ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
+    _('[OPTION]... [FILE]...'))
+def amend(ui, repo, *pats, **opts):
+    """combine a changeset with updates and replace it with a new one
+
+    Commits a new changeset incorporating both the changes to the given files
+    and all the changes from the current parent changeset into the repository.
+
+    See :hg:`commit` for details about committing changes.
+
+    If you don't specify -m, the parent's message will be reused.
+
+    Behind the scenes, Mercurial first commits the update as a regular child
+    of the current parent. Then it creates a new commit on the parent's parents
+    with the updated contents. Then it changes the working copy parent to this
+    new combined changeset. Finally, the old changeset and its update are hidden
+    from :hg:`log` (unless you use --hidden with log).
+
+    Returns 0 on success, 1 if nothing changed.
+    """
+    opts = opts.copy()
+    edit = opts.pop('edit', False)
+    log = opts.get('logfile')
+    opts['amend'] = True
+    if not (edit or opts['message'] or log):
+        opts['message'] = repo['.'].description()
+    _resolveoptions(ui, opts)
+    _alias, commitcmd = cmdutil.findcmd('commit', commands.table)
+    return commitcmd[0](ui, repo, *pats, **opts)
+
+
+def _touchedbetween(repo, source, dest, match=None):
+    touched = set()
+    for files in repo.status(source, dest, match=match)[:3]:
+        touched.update(files)
+    return touched
+
+def _commitfiltered(repo, ctx, match, target=None):
+    """Recommit ctx with changed files not in match. Return the new
+    node identifier, or None if nothing changed.
+    """
+    base = ctx.p1()
+    if target is None:
+        target = base
+    # ctx
+    initialfiles = _touchedbetween(repo, base, ctx)
+    if base == target:
+        affected = set(f for f in initialfiles if match(f))
+        newcontent = set()
+    else:
+        affected = _touchedbetween(repo, target, ctx, match=match)
+        newcontent = _touchedbetween(repo, target, base, match=match)
+    # The commit touchs all existing files
+    # + all file that needs a new content
+    # - the file affected bny uncommit with the same content than base.
+    files = (initialfiles - affected) | newcontent
+    if not newcontent and files == initialfiles:
+        return None
+
+    # Filter copies
+    copied = copies.pathcopies(target, ctx)
+    copied = dict((dst, src) for dst, src in copied.iteritems()
+                  if dst in files)
+    def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent):
+        if path in redirect:
+            return filectxfn(repo, memctx, path, contentctx=target, redirect=())
+        if path not in contentctx:
+            return None
+        fctx = contentctx[path]
+        flags = fctx.flags()
+        mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
+                                  islink='l' in flags,
+                                  isexec='x' in flags,
+                                  copied=copied.get(path))
+        return mctx
+
+    new = context.memctx(repo,
+                         parents=[base.node(), node.nullid],
+                         text=ctx.description(),
+                         files=files,
+                         filectxfn=filectxfn,
+                         user=ctx.user(),
+                         date=ctx.date(),
+                         extra=ctx.extra())
+    # commitctx always create a new revision, no need to check
+    newid = repo.commitctx(new)
+    return newid
+
+def _uncommitdirstate(repo, oldctx, match):
+    """Fix the dirstate after switching the working directory from
+    oldctx to a copy of oldctx not containing changed files matched by
+    match.
+    """
+    ctx = repo['.']
+    ds = repo.dirstate
+    copies = dict(ds.copies())
+    m, a, r = repo.status(oldctx.p1(), oldctx, match=match)[:3]
+    for f in m:
+        if ds[f] == 'r':
+            # modified + removed -> removed
+            continue
+        ds.normallookup(f)
+
+    for f in a:
+        if ds[f] == 'r':
+            # added + removed -> unknown
+            ds.drop(f)
+        elif ds[f] != 'a':
+            ds.add(f)
+
+    for f in r:
+        if ds[f] == 'a':
+            # removed + added -> normal
+            ds.normallookup(f)
+        elif ds[f] != 'r':
+            ds.remove(f)
+
+    # Merge old parent and old working dir copies
+    oldcopies = {}
+    for f in (m + a):
+        src = oldctx[f].renamed()
+        if src:
+            oldcopies[f] = src[0]
+    oldcopies.update(copies)
+    copies = dict((dst, oldcopies.get(src, src))
+                  for dst, src in oldcopies.iteritems())
+    # Adjust the dirstate copies
+    for dst, src in copies.iteritems():
+        if (src not in ctx or dst in ctx or ds[dst] != 'a'):
+            src = None
+        ds.copy(src, dst)
+
+@command('^uncommit',
+    [('a', 'all', None, _('uncommit all changes when no arguments given')),
+     ('r', 'rev', '', _('revert commit content to REV instead')),
+     ] + commands.walkopts,
+    _('[OPTION]... [NAME]'))
+def uncommit(ui, repo, *pats, **opts):
+    """move changes from parent revision to working directory
+
+    Changes to selected files in the checked out revision appear again as
+    uncommitted changed in the working directory. A new revision
+    without the selected changes is created, becomes the checked out
+    revision, and obsoletes the previous one.
+
+    The --include option specifies patterns to uncommit.
+    The --exclude option specifies patterns to keep in the commit.
+
+    The --rev argument let you change the commit file to a content of another
+    revision. It still does not change the content of your file in the working
+    directory.
+
+    Return 0 if changed files are uncommitted.
+    """
+
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        wctx = repo[None]
+        if len(wctx.parents()) <= 0:
+            raise error.Abort(_("cannot uncommit null changeset"))
+        if len(wctx.parents()) > 1:
+            raise error.Abort(_("cannot uncommit while merging"))
+        old = repo['.']
+        if old.phase() == phases.public:
+            raise error.Abort(_("cannot rewrite immutable changeset"))
+        if len(old.parents()) > 1:
+            raise error.Abort(_("cannot uncommit merge changeset"))
+        oldphase = old.phase()
+
+
+        rev = None
+        if opts.get('rev'):
+            rev = scmutil.revsingle(repo, opts.get('rev'))
+            ctx = repo[None]
+            if ctx.p1() == rev or ctx.p2() == rev:
+                raise error.Abort(_("cannot uncommit to parent changeset"))
+
+        onahead = old.rev() in repo.changelog.headrevs()
+        disallowunstable = not obsolete.isenabled(repo,
+                                                  obsolete.allowunstableopt)
+        if disallowunstable and not onahead:
+            raise error.Abort(_("cannot uncommit in the middle of a stack"))
+
+        # Recommit the filtered changeset
+        tr = repo.transaction('uncommit')
+        updatebookmarks = _bookmarksupdater(repo, old.node(), tr)
+        newid = None
+        includeorexclude = opts.get('include') or opts.get('exclude')
+        if (pats or includeorexclude or opts.get('all')):
+            match = scmutil.match(old, pats, opts)
+            newid = _commitfiltered(repo, old, match, target=rev)
+        if newid is None:
+            raise error.Abort(_('nothing to uncommit'),
+                             hint=_("use --all to uncommit all files"))
+        # Move local changes on filtered changeset
+        obsolete.createmarkers(repo, [(old, (repo[newid],))])
+        phases.retractboundary(repo, tr, oldphase, [newid])
+        repo.dirstate.beginparentchange()
+        repo.dirstate.setparents(newid, node.nullid)
+        _uncommitdirstate(repo, old, match)
+        repo.dirstate.endparentchange()
+        updatebookmarks(newid)
+        if not repo[newid].files():
+            ui.warn(_("new changeset is empty\n"))
+            ui.status(_("(use 'hg prune .' to remove it)\n"))
+        tr.close()
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+@eh.wrapcommand('commit')
+def commitwrapper(orig, ui, repo, *arg, **kwargs):
+    tr = None
+    if kwargs.get('amend', False):
+        wlock = lock = None
+    else:
+        wlock = repo.wlock()
+        lock = repo.lock()
+    try:
+        obsoleted = kwargs.get('obsolete', [])
+        if obsoleted:
+            obsoleted = repo.set('%lr', obsoleted)
+        result = orig(ui, repo, *arg, **kwargs)
+        if not result: # commit succeeded
+            new = repo['-1']
+            oldbookmarks = []
+            markers = []
+            for old in obsoleted:
+                oldbookmarks.extend(repo.nodebookmarks(old.node()))
+                markers.append((old, (new,)))
+            if markers:
+                obsolete.createmarkers(repo, markers)
+            for book in oldbookmarks:
+                repo._bookmarks[book] = new.node()
+            if oldbookmarks:
+                if not wlock:
+                    wlock = repo.wlock()
+                if not lock:
+                    lock = repo.lock()
+                tr = repo.transaction('commit')
+                repo._bookmarks.recordchange(tr)
+                tr.close()
+        return result
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+@command('^split',
+    [('r', 'rev', [], _("revision to split")),
+    ] + commitopts + commitopts2,
+    _('hg split [OPTION]... [-r] REV'))
+def cmdsplit(ui, repo, *revs, **opts):
+    """split a changeset into smaller changesets
+
+    By default, split the current revision by prompting for all its hunks to be
+    redistributed into new changesets.
+
+    Use --rev to split a given changeset instead.
+    """
+    tr = wlock = lock = None
+    newcommits = []
+
+    revarg = (list(revs) + opts.get('rev')) or ['.']
+    if len(revarg) != 1:
+        msg = _("more than one revset is given")
+        hnt = _("use either `hg split <rs>` or `hg split --rev <rs>`, not both")
+        raise error.Abort(msg, hint=hnt)
+
+    rev = scmutil.revsingle(repo, revarg[0])
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        cmdutil.bailifchanged(repo)
+        tr = repo.transaction('split')
+        ctx = repo[rev]
+        r = ctx.rev()
+        disallowunstable = not obsolete.isenabled(repo,
+                                                  obsolete.allowunstableopt)
+        if disallowunstable:
+            # XXX We should check head revs
+            if repo.revs("(%d::) - %d", rev, rev):
+                raise error.Abort(_("cannot split commit: %s not a head") % ctx)
+
+        if len(ctx.parents()) > 1:
+            raise error.Abort(_("cannot split merge commits"))
+        prev = ctx.p1()
+        bmupdate = _bookmarksupdater(repo, ctx.node(), tr)
+        bookactive = repo._activebookmark
+        if bookactive is not None:
+            repo.ui.status(_("(leaving bookmark %s)\n") % repo._activebookmark)
+        bookmarksmod.deactivate(repo)
+        hg.update(repo, prev)
+
+        commands.revert(ui, repo, rev=r, all=True)
+        def haschanges():
+            modified, added, removed, deleted = repo.status()[:4]
+            return modified or added or removed or deleted
+        msg = ("HG: This is the original pre-split commit message. "
+               "Edit it as appropriate.\n\n")
+        msg += ctx.description()
+        opts['message'] = msg
+        opts['edit'] = True
+        while haschanges():
+            pats = ()
+            cmdutil.dorecord(ui, repo, commands.commit, 'commit', False,
+                             cmdutil.recordfilter, *pats, **opts)
+            # TODO: Does no seem like the best way to do this
+            # We should make dorecord return the newly created commit
+            newcommits.append(repo['.'])
+            if haschanges():
+                if ui.prompt('Done splitting? [yN]', default='n') == 'y':
+                    commands.commit(ui, repo, **opts)
+                    newcommits.append(repo['.'])
+                    break
+            else:
+                ui.status(_("no more change to split\n"))
+
+        if newcommits:
+            tip = repo[newcommits[-1]]
+            bmupdate(tip.node())
+            if bookactive is not None:
+                bookmarksmod.activate(repo, bookactive)
+            obsolete.createmarkers(repo, [(repo[r], newcommits)])
+        tr.close()
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+
+@eh.wrapcommand('strip', extension='strip', opts=[
+    ('', 'bundle', None, _("delete the commit entirely and move it to a "
+        "backup bundle")),
+    ])
+def stripwrapper(orig, ui, repo, *revs, **kwargs):
+    if (not ui.configbool('experimental', 'prunestrip') or
+        kwargs.get('bundle', False)):
+        return orig(ui, repo, *revs, **kwargs)
+
+    if kwargs.get('force'):
+        ui.warn(_("warning: --force has no effect during strip with evolve "
+                  "enabled\n"))
+    if kwargs.get('no_backup', False):
+        ui.warn(_("warning: --no-backup has no effect during strips with "
+                  "evolve enabled\n"))
+
+    revs = list(revs) + kwargs.pop('rev', [])
+    revs = set(scmutil.revrange(repo, revs))
+    revs = repo.revs("(%ld)::", revs)
+    kwargs['rev'] = []
+    kwargs['new'] = []
+    kwargs['succ'] = []
+    kwargs['biject'] = False
+    return cmdprune(ui, repo, *revs, **kwargs)
+
+@command('^touch',
+    [('r', 'rev', [], 'revision to update'),
+     ('D', 'duplicate', False,
+      'do not mark the new revision as successor of the old one'),
+     ('A', 'allowdivergence', False,
+      'mark the new revision as successor of the old one potentially creating '
+      'divergence')],
+    # allow to choose the seed ?
+    _('[-r] revs'))
+def touch(ui, repo, *revs, **opts):
+    """create successors that are identical to their predecessors except
+    for the changeset ID
+
+    This is used to "resurrect" changesets
+    """
+    duplicate = opts['duplicate']
+    allowdivergence = opts['allowdivergence']
+    revs = list(revs)
+    revs.extend(opts['rev'])
+    if not revs:
+        revs = ['.']
+    revs = scmutil.revrange(repo, revs)
+    if not revs:
+        ui.write_err('no revision to touch\n')
+        return 1
+    if not duplicate and repo.revs('public() and %ld', revs):
+        raise error.Abort("can't touch public revision")
+    displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction('touch')
+        revs.sort() # ensure parent are run first
+        newmapping = {}
+        for r in revs:
+            ctx = repo[r]
+            extra = ctx.extra().copy()
+            extra['__touch-noise__'] = random.randint(0, 0xffffffff)
+            # search for touched parent
+            p1 = ctx.p1().node()
+            p2 = ctx.p2().node()
+            p1 = newmapping.get(p1, p1)
+            p2 = newmapping.get(p2, p2)
+
+            if not (duplicate or allowdivergence):
+                # The user hasn't yet decided what to do with the revived
+                # cset, let's ask
+                sset = obsolete.successorssets(repo, ctx.node())
+                nodivergencerisk = len(sset) == 0 or (
+                                    len(sset) == 1 and
+                                    len(sset[0]) == 1 and
+                                    repo[sset[0][0]].rev() == ctx.rev()
+                                   )
+                if nodivergencerisk:
+                    duplicate = False
+                else:
+                    displayer.show(ctx)
+                    index = ui.promptchoice(
+                        _("reviving this changeset will create divergence"
+                        " unless you make a duplicate.\n(a)llow divergence or"
+                        " (d)uplicate the changeset? $$ &Allowdivergence $$ "
+                        "&Duplicate"), 0)
+                    choice = ['allowdivergence', 'duplicate'][index]
+                    if choice == 'allowdivergence':
+                        duplicate = False
+                    else:
+                        duplicate = True
+
+            new, unusedvariable = rewrite(repo, ctx, [], ctx,
+                                          [p1, p2],
+                                          commitopts={'extra': extra})
+            # store touched version to help potential children
+            newmapping[ctx.node()] = new
+
+            if not duplicate:
+                obsolete.createmarkers(repo, [(ctx, (repo[new],))])
+            phases.retractboundary(repo, tr, ctx.phase(), [new])
+            if ctx in repo[None].parents():
+                repo.dirstate.beginparentchange()
+                repo.dirstate.setparents(new, node.nullid)
+                repo.dirstate.endparentchange()
+        tr.close()
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+@command('^fold|squash',
+    [('r', 'rev', [], _("revision to fold")),
+     ('', 'exact', None, _("only fold specified revisions")),
+     ('', 'from', None, _("fold revisions linearly to working copy parent"))
+    ] + commitopts + commitopts2,
+    _('hg fold [OPTION]... [-r] REV'))
+def fold(ui, repo, *revs, **opts):
+    """fold multiple revisions into a single one
+
+    With --from, folds all the revisions linearly between the given revisions
+    and the parent of the working directory.
+
+    With --exact, folds only the specified revisions while ignoring the
+    parent of the working directory. In this case, the given revisions must
+    form a linear unbroken chain.
+
+    .. container:: verbose
+
+     Some examples:
+
+     - Fold the current revision with its parent::
+
+         hg fold --from .^
+
+     - Fold all draft revisions with working directory parent::
+
+         hg fold --from 'draft()'
+
+       See :hg:`help phases` for more about draft revisions and
+       :hg:`help revsets` for more about the `draft()` keyword
+
+     - Fold revisions between 3 and 6 with the working directory parent::
+
+         hg fold --from 3::6
+
+     - Fold revisions 3 and 4:
+
+        hg fold "3 + 4" --exact
+
+     - Only fold revisions linearly between foo and @::
+
+         hg fold foo::@ --exact
+    """
+    revs = list(revs)
+    revs.extend(opts['rev'])
+    if not revs:
+        raise error.Abort(_('no revisions specified'))
+
+    revs = scmutil.revrange(repo, revs)
+
+    if opts['from'] and opts['exact']:
+        raise error.Abort(_('cannot use both --from and --exact'))
+    elif opts['from']:
+        # Try to extend given revision starting from the working directory
+        extrevs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
+        discardedrevs = [r for r in revs if r not in extrevs]
+        if discardedrevs:
+            raise error.Abort(_("cannot fold non-linear revisions"),
+                               hint=_("given revisions are unrelated to parent "
+                                      "of working directory"))
+        revs = extrevs
+    elif opts['exact']:
+        # Nothing to do; "revs" is already set correctly
+        pass
+    else:
+        raise error.Abort(_('must specify either --from or --exact'))
+
+    if not revs:
+        raise error.Abort(_('specified revisions evaluate to an empty set'),
+                          hint=_('use different revision arguments'))
+    elif len(revs) == 1:
+        ui.write_err(_('single revision specified, nothing to fold\n'))
+        return 1
+
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+
+        root, head = _foldcheck(repo, revs)
+
+        tr = repo.transaction('fold')
+        try:
+            commitopts = opts.copy()
+            allctx = [repo[r] for r in revs]
+            targetphase = max(c.phase() for c in allctx)
+
+            if commitopts.get('message') or commitopts.get('logfile'):
+                commitopts['edit'] = False
+            else:
+                msgs = ["HG: This is a fold of %d changesets." % len(allctx)]
+                msgs += ["HG: Commit message of changeset %s.\n\n%s\n" %
+                         (c.rev(), c.description()) for c in allctx]
+                commitopts['message'] =  "\n".join(msgs)
+                commitopts['edit'] = True
+
+            newid, unusedvariable = rewrite(repo, root, allctx, head,
+                                            [root.p1().node(),
+                                             root.p2().node()],
+                                            commitopts=commitopts)
+            phases.retractboundary(repo, tr, targetphase, [newid])
+            obsolete.createmarkers(repo, [(ctx, (repo[newid],))
+                                 for ctx in allctx])
+            tr.close()
+        finally:
+            tr.release()
+        ui.status('%i changesets folded\n' % len(revs))
+        if repo['.'].rev() in revs:
+            hg.update(repo, newid)
+    finally:
+        lockmod.release(lock, wlock)
+
+@command('^metaedit',
+         [('r', 'rev', [], _("revision to edit")),
+         ('', 'fold', None, _("also fold specified revisions into one")),
+         ] + commitopts + commitopts2,
+         _('hg metaedit [OPTION]... [-r] [REV]'))
+def metaedit(ui, repo, *revs, **opts):
+    """edit commit information
+
+    Edits the commit information for the specified revisions. By default, edits
+    commit information for the working directory parent.
+
+    With --fold, also folds multiple revisions into one if necessary. In this
+    case, the given revisions must form a linear unbroken chain.
+
+    .. container:: verbose
+
+     Some examples:
+
+     - Edit the commit message for the working directory parent::
+
+         hg metaedit
+
+     - Change the username for the working directory parent::
+
+         hg metaedit --user 'New User <new-email@example.com>'
+
+     - Combine all draft revisions that are ancestors of foo but not of @ into
+       one::
+
+         hg metaedit --fold 'draft() and only(foo,@)'
+
+       See :hg:`help phases` for more about draft revisions, and
+       :hg:`help revsets` for more about the `draft()` and `only()` keywords.
+    """
+    revs = list(revs)
+    revs.extend(opts['rev'])
+    if not revs:
+        if opts['fold']:
+            raise error.Abort(_('revisions must be specified with --fold'))
+        revs = ['.']
+
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+
+        revs = scmutil.revrange(repo, revs)
+        if not opts['fold'] and len(revs) > 1:
+            # TODO: handle multiple revisions. This is somewhat tricky because
+            # if we want to edit a series of commits:
+            #
+            #   a ---- b ---- c
+            #
+            # we need to rewrite a first, then directly rewrite b on top of the
+            # new a, then rewrite c on top of the new b. So we need to handle
+            # revisions in topological order.
+            raise error.Abort(_('editing multiple revisions without --fold is '
+                                'not currently supported'))
+
+        if opts['fold']:
+            root, head = _foldcheck(repo, revs)
+        else:
+            if repo.revs("%ld and public()", revs):
+                raise error.Abort(_('cannot edit commit information for public '
+                                    'revisions'))
+            newunstable = _disallowednewunstable(repo, revs)
+            if newunstable:
+                raise error.Abort(
+                    _('cannot edit commit information in the middle of a '\
+                    'stack'), hint=_('%s will become unstable and new unstable'\
+                    ' changes are not allowed') % repo[newunstable.first()])
+            root = head = repo[revs.first()]
+
+        wctx = repo[None]
+        p1 = wctx.p1()
+        tr = repo.transaction('metaedit')
+        newp1 = None
+        try:
+            commitopts = opts.copy()
+            allctx = [repo[r] for r in revs]
+            targetphase = max(c.phase() for c in allctx)
+
+            if commitopts.get('message') or commitopts.get('logfile'):
+                commitopts['edit'] = False
+            else:
+                if opts['fold']:
+                    msgs = ["HG: This is a fold of %d changesets." % len(allctx)]
+                    msgs += ["HG: Commit message of changeset %s.\n\n%s\n" %
+                             (c.rev(), c.description()) for c in allctx]
+                else:
+                    msgs = [head.description()]
+                commitopts['message'] =  "\n".join(msgs)
+                commitopts['edit'] = True
+
+            # TODO: if the author and message are the same, don't create a new
+            # hash. Right now we create a new hash because the date can be
+            # different.
+            newid, created = rewrite(repo, root, allctx, head,
+                                     [root.p1().node(), root.p2().node()],
+                                     commitopts=commitopts)
+            if created:
+                if p1.rev() in revs:
+                    newp1 = newid
+                phases.retractboundary(repo, tr, targetphase, [newid])
+                obsolete.createmarkers(repo, [(ctx, (repo[newid],))
+                                              for ctx in allctx])
+            else:
+                ui.status(_("nothing changed\n"))
+            tr.close()
+        finally:
+            tr.release()
+
+        if opts['fold']:
+            ui.status('%i changesets folded\n' % len(revs))
+        if newp1 is not None:
+            hg.update(repo, newp1)
+    finally:
+        lockmod.release(lock, wlock)
+
+def _foldcheck(repo, revs):
+    roots = repo.revs('roots(%ld)', revs)
+    if len(roots) > 1:
+        raise error.Abort(_("cannot fold non-linear revisions "
+                           "(multiple roots given)"))
+    root = repo[roots.first()]
+    if root.phase() <= phases.public:
+        raise error.Abort(_("cannot fold public revisions"))
+    heads = repo.revs('heads(%ld)', revs)
+    if len(heads) > 1:
+        raise error.Abort(_("cannot fold non-linear revisions "
+                           "(multiple heads given)"))
+    head = repo[heads.first()]
+    if _disallowednewunstable(repo, revs):
+        raise error.Abort(_("cannot fold chain not ending with a head "\
+                            "or with branching"), hint = _("new unstable"\
+                            " changesets are not allowed"))
+    return root, head
+
+def _disallowednewunstable(repo, revs):
+    allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
+    if allowunstable:
+        return revset.baseset()
+    return repo.revs("(%ld::) - %ld", revs, revs)
+
+@eh.wrapcommand('graft')
+def graftwrapper(orig, ui, repo, *revs, **kwargs):
+    kwargs = dict(kwargs)
+    revs = list(revs) + kwargs.get('rev', [])
+    kwargs['rev'] = []
+    obsoleted = kwargs.setdefault('obsolete', [])
+
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        if kwargs.get('old_obsolete'):
+            if kwargs.get('continue'):
+                obsoleted.extend(repo.opener.read('graftstate').splitlines())
+            else:
+                obsoleted.extend(revs)
+        # convert obsolete target into revs to avoid alias joke
+        obsoleted[:] = [str(i) for i in repo.revs('%lr', obsoleted)]
+        if obsoleted and len(revs) > 1:
+
+            raise error.Abort(_('cannot graft multiple revisions while '
+                                'obsoleting (for now).'))
+
+        return commitwrapper(orig, ui, repo,*revs, **kwargs)
+    finally:
+        lockmod.release(lock, wlock)
+
+@eh.extsetup
+def oldevolveextsetup(ui):
+    for cmd in ['prune', 'uncommit', 'touch', 'fold']:
+        try:
+            entry = extensions.wrapcommand(cmdtable, cmd,
+                                           warnobserrors)
+        except error.UnknownCommand:
+            # Commands may be disabled
+            continue
+
+    entry = cmdutil.findcmd('commit', commands.table)[1]
+    entry[1].append(('o', 'obsolete', [],
+                     _("make commit obsolete this revision (DEPRECATED)")))
+    entry = cmdutil.findcmd('graft', commands.table)[1]
+    entry[1].append(('o', 'obsolete', [],
+                     _("make graft obsoletes this revision (DEPRECATED)")))
+    entry[1].append(('O', 'old-obsolete', False,
+                     _("make graft obsoletes its source (DEPRECATED)")))
+
+#####################################################################
+### Obsolescence marker exchange experimenation                   ###
+#####################################################################
+
+def obsexcprg(ui, *args, **kwargs):
+    topic = 'obsmarkers exchange'
+    if ui.configbool('experimental', 'verbose-obsolescence-exchange', False):
+        topic = 'OBSEXC'
+    ui.progress(topic, *args, **kwargs)
+
+@eh.wrapfunction(exchange, '_pushdiscoveryobsmarkers')
+def _pushdiscoveryobsmarkers(orig, pushop):
+    if (obsolete.isenabled(pushop.repo, obsolete.exchangeopt)
+        and pushop.repo.obsstore
+        and 'obsolete' in pushop.remote.listkeys('namespaces')):
+        repo = pushop.repo
+        obsexcmsg(repo.ui, "computing relevant nodes\n")
+        revs = list(repo.revs('::%ln', pushop.futureheads))
+        unfi = repo.unfiltered()
+        cl = unfi.changelog
+        if not pushop.remote.capable('_evoext_obshash_0'):
+            # do not trust core yet
+            # return orig(pushop)
+            nodes = [cl.node(r) for r in revs]
+            if nodes:
+                obsexcmsg(repo.ui, "computing markers relevant to %i nodes\n"
+                                   % len(nodes))
+                pushop.outobsmarkers = repo.obsstore.relevantmarkers(nodes)
+            else:
+                obsexcmsg(repo.ui, "markers already in sync\n")
+                pushop.outobsmarkers = []
+                pushop.outobsmarkers = repo.obsstore.relevantmarkers(nodes)
+            return
+
+        common = []
+        obsexcmsg(repo.ui, "looking for common markers in %i nodes\n"
+                           % len(revs))
+        commonrevs = list(unfi.revs('::%ln', pushop.outgoing.commonheads))
+        common = findcommonobsmarkers(pushop.ui, unfi, pushop.remote,
+                                      commonrevs)
+
+        revs = list(unfi.revs('%ld - (::%ln)', revs, common))
+        nodes = [cl.node(r) for r in revs]
+        if nodes:
+            obsexcmsg(repo.ui, "computing markers relevant to %i nodes\n"
+                               % len(nodes))
+            pushop.outobsmarkers = repo.obsstore.relevantmarkers(nodes)
+        else:
+            obsexcmsg(repo.ui, "markers already in sync\n")
+            pushop.outobsmarkers = []
+
+@eh.extsetup
+def _installobsmarkersdiscovery(ui):
+    olddisco = exchange.pushdiscoverymapping['obsmarker']
+    def newdisco(pushop):
+        _pushdiscoveryobsmarkers(olddisco, pushop)
+    exchange.pushdiscoverymapping['obsmarker'] = newdisco
+
+### Set discovery START
+
+from mercurial import dagutil
+from mercurial import setdiscovery
+
+@eh.addattr(localrepo.localpeer, 'evoext_obshash')
+def local_obshash(peer, nodes):
+    return serveronly._obshash(peer._repo, nodes)
+
+@eh.addattr(localrepo.localpeer, 'evoext_obshash1')
+def local_obshash1(peer, nodes):
+    return serveronly._obshash(peer._repo, nodes, version=1)
+
+@eh.addattr(wireproto.wirepeer, 'evoext_obshash')
+def peer_obshash(self, nodes):
+    d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes))
+    try:
+        return wireproto.decodelist(d)
+    except ValueError:
+        self._abort(error.ResponseError(_("unexpected response:"), d))
+
+@eh.addattr(wireproto.wirepeer, 'evoext_obshash1')
+def peer_obshash1(self, nodes):
+    d = self._call("evoext_obshash1", nodes=wireproto.encodelist(nodes))
+    try:
+        return wireproto.decodelist(d)
+    except ValueError:
+        self._abort(error.ResponseError(_("unexpected response:"), d))
+
+def findcommonobsmarkers(ui, local, remote, probeset,
+                         initialsamplesize=100,
+                         fullsamplesize=200):
+    # from discovery
+    roundtrips = 0
+    cl = local.changelog
+    dag = dagutil.revlogdag(cl)
+    missing = set()
+    common = set()
+    undecided = set(probeset)
+    totalnb = len(undecided)
+    ui.progress(_("comparing with other"), 0, total=totalnb)
+    _takefullsample = setdiscovery._takefullsample
+    if remote.capable('_evoext_obshash_1'):
+        getremotehash = remote.evoext_obshash1
+        localhash = serveronly._obsrelsethashtreefm1(local)
+    else:
+        getremotehash = remote.evoext_obshash
+        localhash = serveronly._obsrelsethashtreefm0(local)
+
+    while undecided:
+
+        ui.note(_("sampling from both directions\n"))
+        if len(undecided) < fullsamplesize:
+            sample = set(undecided)
+        else:
+            sample = _takefullsample(dag, undecided, size=fullsamplesize)
+
+        roundtrips += 1
+        ui.progress(_("comparing with other"), totalnb - len(undecided),
+                    total=totalnb)
+        ui.debug("query %i; still undecided: %i, sample size is: %i\n"
+                 % (roundtrips, len(undecided), len(sample)))
+        # indices between sample and externalized version must match
+        sample = list(sample)
+        remotehash = getremotehash(dag.externalizeall(sample))
+
+        yesno = [localhash[ix][1] == remotehash[si]
+                 for si, ix in enumerate(sample)]
+
+        commoninsample = set(n for i, n in enumerate(sample) if yesno[i])
+        common.update(dag.ancestorset(commoninsample, common))
+
+        missinginsample = [n for i, n in enumerate(sample) if not yesno[i]]
+        missing.update(dag.descendantset(missinginsample, missing))
+
+        undecided.difference_update(missing)
+        undecided.difference_update(common)
+
+
+    ui.progress(_("comparing with other"), None)
+    result = dag.headsetofconnecteds(common)
+    ui.debug("%d total queries\n" % roundtrips)
+
+    if not result:
+        return set([nullid])
+    return dag.externalizeall(result)
+
+
+_pushkeyescape = getattr(obsolete, '_pushkeyescape', None)
+
+class pushobsmarkerStringIO(StringIO):
+    """hacky string io for progress"""
+
+    @util.propertycache
+    def length(self):
+        return len(self.getvalue())
+
+    def read(self, size=None):
+        obsexcprg(self.ui, self.tell(), unit=_("bytes"), total=self.length)
+        return StringIO.read(self, size)
+
+    def __iter__(self):
+        d = self.read(4096)
+        while d:
+            yield d
+            d = self.read(4096)
+
+@eh.wrapfunction(exchange, '_pushobsolete')
+def _pushobsolete(orig, pushop):
+    """utility function to push obsolete markers to a remote"""
+    stepsdone = getattr(pushop, 'stepsdone', None)
+    if stepsdone is not None:
+        if 'obsmarkers' in stepsdone:
+            return
+        stepsdone.add('obsmarkers')
+    if pushop.cgresult == 0:
+        return
+    pushop.ui.debug('try to push obsolete markers to remote\n')
+    repo = pushop.repo
+    remote = pushop.remote
+    if (obsolete.isenabled(repo, obsolete.exchangeopt) and repo.obsstore and
+        'obsolete' in remote.listkeys('namespaces')):
+        markers = pushop.outobsmarkers
+        if not markers:
+            obsexcmsg(repo.ui, "no marker to push\n")
+        elif remote.capable('_evoext_pushobsmarkers_0'):
+            obsdata = pushobsmarkerStringIO()
+            for chunk in obsolete.encodemarkers(markers, True):
+                obsdata.write(chunk)
+            obsdata.seek(0)
+            obsdata.ui = repo.ui
+            obsexcmsg(repo.ui, "pushing %i obsolescence markers (%i bytes)\n"
+                               % (len(markers), len(obsdata.getvalue())),
+                      True)
+            remote.evoext_pushobsmarkers_0(obsdata)
+            obsexcprg(repo.ui, None)
+        else:
+            rslts = []
+            remotedata = _pushkeyescape(markers).items()
+            totalbytes = sum(len(d) for k, d in remotedata)
+            sentbytes = 0
+            obsexcmsg(repo.ui, "pushing %i obsolescence markers in %i "
+                               "pushkey payload (%i bytes)\n"
+                               % (len(markers), len(remotedata), totalbytes),
+                      True)
+            for key, data in remotedata:
+                obsexcprg(repo.ui, sentbytes, item=key, unit=_("bytes"),
+                          total=totalbytes)
+                rslts.append(remote.pushkey('obsolete', key, '', data))
+                sentbytes += len(data)
+                obsexcprg(repo.ui, sentbytes, item=key, unit=_("bytes"),
+                          total=totalbytes)
+            obsexcprg(repo.ui, None)
+            if [r for r in rslts if not r]:
+                msg = _('failed to push some obsolete markers!\n')
+                repo.ui.warn(msg)
+        obsexcmsg(repo.ui, "DONE\n")
+
+
+@eh.addattr(wireproto.wirepeer, 'evoext_pushobsmarkers_0')
+def client_pushobsmarkers(self, obsfile):
+    """wireprotocol peer method"""
+    self.requirecap('_evoext_pushobsmarkers_0',
+                    _('push obsolete markers faster'))
+    ret, output = self._callpush('evoext_pushobsmarkers_0', obsfile)
+    for l in output.splitlines(True):
+        self.ui.status(_('remote: '), l)
+    return ret
+
+@eh.addattr(httppeer.httppeer, 'evoext_pushobsmarkers_0')
+def httpclient_pushobsmarkers(self, obsfile):
+    """httpprotocol peer method
+    (Cannot simply use _callpush as http is doing some special handling)"""
+    self.requirecap('_evoext_pushobsmarkers_0',
+                    _('push obsolete markers faster'))
+    try:
+        r = self._call('evoext_pushobsmarkers_0', data=obsfile)
+        vals = r.split('\n', 1)
+        if len(vals) < 2:
+            raise error.ResponseError(_("unexpected response:"), r)
+
+        for l in vals[1].splitlines(True):
+            if l.strip():
+                self.ui.status(_('remote: '), l)
+        return vals[0]
+    except socket.error as err:
+        if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
+            raise error.Abort(_('push failed: %s') % err.args[1])
+        raise error.Abort(err.args[1])
+
+@eh.wrapfunction(localrepo.localrepository, '_restrictcapabilities')
+def local_pushobsmarker_capabilities(orig, repo, caps):
+    caps = orig(repo, caps)
+    caps.add('_evoext_pushobsmarkers_0')
+    return caps
+
+@eh.addattr(localrepo.localpeer, 'evoext_pushobsmarkers_0')
+def local_pushobsmarkers(peer, obsfile):
+    data = obsfile.read()
+    serveronly._pushobsmarkers(peer._repo, data)
+
+def _buildpullobsmarkersboundaries(pullop):
+    """small funtion returning the argument for pull markers call
+    may to contains 'heads' and 'common'. skip the key for None.
+
+    Its a separed functio to play around with strategy for that."""
+    repo = pullop.repo
+    remote = pullop.remote
+    unfi = repo.unfiltered()
+    revs = unfi.revs('::(%ln - null)', pullop.common)
+    common = [nullid]
+    if remote.capable('_evoext_obshash_0'):
+        obsexcmsg(repo.ui, "looking for common markers in %i nodes\n"
+                           % len(revs))
+        common = findcommonobsmarkers(repo.ui, repo, remote, revs)
+    return {'heads': pullop.pulledsubset, 'common': common}
+
+@eh.uisetup
+def addgetbundleargs(self):
+    wireproto.gboptsmap['evo_obscommon'] = 'nodes'
+
+@eh.wrapfunction(exchange, '_pullbundle2extraprepare')
+def _addobscommontob2pull(orig, pullop, kwargs):
+    ret = orig(pullop, kwargs)
+    if ('obsmarkers' in kwargs and
+        pullop.remote.capable('_evoext_getbundle_obscommon')):
+        boundaries = _buildpullobsmarkersboundaries(pullop)
+        common = boundaries['common']
+        if common != [nullid]:
+            kwargs['evo_obscommon'] = common
+    return ret
+
+@eh.wrapfunction(exchange, '_pullobsolete')
+def _pullobsolete(orig, pullop):
+    if not obsolete.isenabled(pullop.repo, obsolete.exchangeopt):
+        return None
+    if 'obsmarkers' not in getattr(pullop, 'todosteps', ['obsmarkers']):
+        return None
+    if 'obsmarkers' in getattr(pullop, 'stepsdone', []):
+        return None
+    wirepull = pullop.remote.capable('_evoext_pullobsmarkers_0')
+    if not wirepull:
+        return orig(pullop)
+    if 'obsolete' not in pullop.remote.listkeys('namespaces'):
+        return None # remote opted out of obsolescence marker exchange
+    tr = None
+    ui = pullop.repo.ui
+    boundaries = _buildpullobsmarkersboundaries(pullop)
+    if not set(boundaries['heads']) - set(boundaries['common']):
+        obsexcmsg(ui, "nothing to pull\n")
+        return None
+
+    obsexcmsg(ui, "pull obsolescence markers\n", True)
+    new = 0
+
+    if wirepull:
+        obsdata = pullop.remote.evoext_pullobsmarkers_0(**boundaries)
+        obsdata = obsdata.read()
+        if len(obsdata) > 5:
+            obsexcmsg(ui, "merging obsolescence markers (%i bytes)\n"
+                           % len(obsdata))
+            tr = pullop.gettransaction()
+            old = len(pullop.repo.obsstore._all)
+            pullop.repo.obsstore.mergemarkers(tr, obsdata)
+            new = len(pullop.repo.obsstore._all) - old
+            obsexcmsg(ui, "%i obsolescence markers added\n" % new, True)
+        else:
+            obsexcmsg(ui, "no unknown remote markers\n")
+        obsexcmsg(ui, "DONE\n")
+    if new:
+        pullop.repo.invalidatevolatilesets()
+    return tr
+
+@eh.addattr(wireproto.wirepeer, 'evoext_pullobsmarkers_0')
+def client_pullobsmarkers(self, heads=None, common=None):
+    self.requirecap('_evoext_pullobsmarkers_0', _('look up remote obsmarkers'))
+    opts = {}
+    if heads is not None:
+        opts['heads'] = wireproto.encodelist(heads)
+    if common is not None:
+        opts['common'] = wireproto.encodelist(common)
+    f = self._callcompressable("evoext_pullobsmarkers_0", **opts)
+    length = int(f.read(20))
+    chunk = 4096
+    current = 0
+    data = StringIO()
+    ui = self.ui
+    obsexcprg(ui, current, unit=_("bytes"), total=length)
+    while current < length:
+        readsize = min(length - current, chunk)
+        data.write(f.read(readsize))
+        current += readsize
+        obsexcprg(ui, current, unit=_("bytes"), total=length)
+    obsexcprg(ui, None)
+    data.seek(0)
+    return data
+
+@eh.addattr(localrepo.localpeer, 'evoext_pullobsmarkers_0')
+def local_pullobsmarkers(self, heads=None, common=None):
+    return serveronly._getobsmarkersstream(self._repo, heads=heads,
+                                           common=common)
+
+@command('debugobsrelsethashtree',
+        [('', 'v0', None, 'hash on marker format "0"'),
+         ('', 'v1', None, 'hash on marker format "1" (default)')] , _(''))
+def debugobsrelsethashtree(ui, repo, v0=False, v1=False):
+    """display Obsolete markers, Relevant Set, Hash Tree
+    changeset-node obsrelsethashtree-node
+
+    It computed form the "orsht" of its parent and markers
+    relevant to the changeset itself."""
+    if v0 and v1:
+        raise error.Abort('cannot only specify one format')
+    elif v0:
+        treefunc = serveronly._obsrelsethashtreefm0
+    else:
+        treefunc = serveronly._obsrelsethashtreefm1
+
+    for chg, obs in treefunc(repo):
+        ui.status('%s %s\n' % (node.hex(chg), node.hex(obs)))
+
+_bestformat = max(obsolete.formats.keys())
+
+
+@eh.wrapfunction(obsolete, '_checkinvalidmarkers')
+def _checkinvalidmarkers(orig, markers):
+    """search for marker with invalid data and raise error if needed
+
+    Exist as a separated function to allow the evolve extension for a more
+    subtle handling.
+    """
+    if 'debugobsconvert' in sys.argv:
+        return
+    for mark in markers:
+        if node.nullid in mark[1]:
+            raise error.Abort(_('bad obsolescence marker detected: '
+                               'invalid successors nullid'),
+                             hint=_('You should run `hg debugobsconvert`'))
+
+@command(
+    'debugobsconvert',
+    [('', 'new-format', _bestformat, _('Destination format for markers.'))],
+    '')
+def debugobsconvert(ui, repo, new_format):
+    origmarkers = repo.obsstore._all  # settle version
+    if new_format == repo.obsstore._version:
+        msg = _('New format is the same as the old format, not upgrading!')
+        raise error.Abort(msg)
+    f = repo.svfs('obsstore', 'wb', atomictemp=True)
+    known = set()
+    markers = []
+    for m in origmarkers:
+        # filter out invalid markers
+        if nullid in m[1]:
+            m = list(m)
+            m[1] = tuple(s for s in m[1] if s != nullid)
+            m = tuple(m)
+        if m in known:
+            continue
+        known.add(m)
+        markers.append(m)
+    ui.write(_('Old store is version %d, will rewrite in version %d\n') % (
+        repo.obsstore._version, new_format))
+    map(f.write, obsolete.encodemarkers(markers, True, new_format))
+    f.close()
+    ui.write(_('Done!\n'))
+
+
+def _helploader(ui):
+    return help.gettext(evolutionhelptext)
+
+@eh.uisetup
+def _setuphelp(ui):
+    for entry in help.helptable:
+        if entry[0] == "evolution":
+            break
+    else:
+        help.helptable.append((["evolution"], _("Safely Rewriting History"),
+                      _helploader))
+        help.helptable.sort()
+
+def _relocatecommit(repo, orig, commitmsg):
+    if commitmsg is None:
+        commitmsg = orig.description()
+    extra = dict(orig.extra())
+    if 'branch' in extra:
+        del extra['branch']
+    extra['rebase_source'] = orig.hex()
+
+    backup = repo.ui.backupconfig('phases', 'new-commit')
+    try:
+        targetphase = max(orig.phase(), phases.draft)
+        repo.ui.setconfig('phases', 'new-commit', targetphase, 'evolve')
+        # Commit might fail if unresolved files exist
+        nodenew = repo.commit(text=commitmsg, user=orig.user(),
+                              date=orig.date(), extra=extra)
+    finally:
+        repo.ui.restoreconfig(backup)
+    return nodenew
+
+def _finalizerelocate(repo, orig, dest, nodenew, tr):
+    destbookmarks = repo.nodebookmarks(dest.node())
+    nodesrc = orig.node()
+    destphase = repo[nodesrc].phase()
+    oldbookmarks = repo.nodebookmarks(nodesrc)
+    if nodenew is not None:
+        phases.retractboundary(repo, tr, destphase, [nodenew])
+        obsolete.createmarkers(repo, [(repo[nodesrc], (repo[nodenew],))])
+        for book in oldbookmarks:
+            repo._bookmarks[book] = nodenew
+    else:
+        obsolete.createmarkers(repo, [(repo[nodesrc], ())])
+        # Behave like rebase, move bookmarks to dest
+        for book in oldbookmarks:
+            repo._bookmarks[book] = dest.node()
+    for book in destbookmarks: # restore bookmark that rebase move
+        repo._bookmarks[book] = dest.node()
+    if oldbookmarks or destbookmarks:
+        repo._bookmarks.recordchange(tr)
+
+evolvestateversion = 0
+
+@eh.uisetup
+def setupevolveunfinished(ui):
+    data = ('evolvestate', True, False, _('evolve in progress'),
+           _("use 'hg evolve --continue' or 'hg update -C .' to abort"))
+    cmdutil.unfinishedstates.append(data)
+
+@eh.wrapfunction(hg, 'clean')
+def clean(orig, repo, *args, **kwargs):
+    ret = orig(repo, *args, **kwargs)
+    util.unlinkpath(repo.join('evolvestate'), ignoremissing=True)
+    return ret
+
+def _evolvestatewrite(repo, state):
+    # [version]
+    # [type][length][content]
+    #
+    # `version` is a 4 bytes integer (handled at higher level)
+    # `type` is a single character, `length` is a 4 byte integer, and
+    # `content` is an arbitrary byte sequence of length `length`.
+    f = repo.vfs('evolvestate', 'w')
+    try:
+        f.write(_pack('>I', evolvestateversion))
+        current = state['current']
+        key = 'C' # as in 'current'
+        format = '>sI%is' % len(current)
+        f.write(_pack(format, key, len(current), current))
+    finally:
+        f.close()
+
+def _evolvestateread(repo):
+    try:
+        f = repo.vfs('evolvestate')
+    except IOError as err:
+        if err.errno != errno.ENOENT:
+            raise
+        return None
+    try:
+        versionblob = f.read(4)
+        if len(versionblob) < 4:
+            repo.ui.debug('ignoring corrupted evolvestte (file contains %i bits)'
+                          % len(versionblob))
+            return None
+        version = _unpack('>I', versionblob)[0]
+        if version != evolvestateversion:
+            raise error.Abort(_('unknown evolvestate version %i')
+                                % version, hint=_('upgrade your evolve'))
+        records = []
+        data = f.read()
+        off = 0
+        end = len(data)
+        while off < end:
+            rtype = data[off]
+            off += 1
+            length = _unpack('>I', data[off:(off + 4)])[0]
+            off += 4
+            record = data[off:(off + length)]
+            off += length
+            if rtype == 't':
+                rtype, record = record[0], record[1:]
+            records.append((rtype, record))
+        state = {}
+        for rtype, rdata in records:
+            if rtype == 'C':
+                state['current'] = rdata
+            elif rtype.lower():
+                repo.ui.debug('ignore evolve state record type %s' % rtype)
+            else:
+                raise error.Abort(_('unknown evolvestate field type %r')
+                                  % rtype, hint=_('upgrade your evolve'))
+        return state
+    finally:
+        f.close()
+
+def _evolvestatedelete(repo):
+    util.unlinkpath(repo.join('evolvestate'), ignoremissing=True)
+
+def _evolvemerge(repo, orig, dest, pctx, keepbranch):
+    """Used by the evolve function to merge dest on top of pctx.
+    return the same tuple as merge.graft"""
+    if repo['.'].rev() != dest.rev():
+        merge.update(repo,
+                     dest,
+                     branchmerge=False,
+                     force=True)
+    if repo._activebookmark:
+       repo.ui.status(_("(leaving bookmark %s)\n") % repo._activebookmark)
+    bookmarksmod.deactivate(repo)
+    if keepbranch:
+       repo.dirstate.setbranch(orig.branch())
+    if util.safehasattr(repo, 'currenttopic'):
+        # uurrgs
+        # there no other topic setter yet
+        if not orig.topic() and repo.vfs.exists('topic'):
+                repo.vfs.unlink('topic')
+        else:
+            with repo.vfs.open('topic', 'w') as f:
+                f.write(orig.topic())
+
+    return merge.graft(repo, orig, pctx, ['local', 'graft'], True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/hack/directaccess.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,194 @@
+""" This extension provides direct access
+It is the ability to refer and access hidden sha in commands provided that you
+know their value.
+For example hg log -r xxx where xxx is a commit has should work whether xxx is
+hidden or not as we assume that the user knows what he is doing when referring
+to xxx.
+"""
+from mercurial import extensions
+from mercurial import cmdutil
+from mercurial import repoview
+from mercurial import branchmap
+from mercurial import revset
+from mercurial import error
+from mercurial import commands
+from mercurial import hg
+from mercurial import util
+from mercurial.i18n import _
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+# By default, all the commands have directaccess with warnings
+# List of commands that have no directaccess and directaccess with no warning
+directaccesslevel = [
+    # Format:
+    # ('nowarning', 'evolve', 'prune'),
+    # means: no directaccess warning, for the command in evolve named prune
+    #
+    # ('error', None, 'serve'),
+    # means: no directaccess for the command in core named serve
+    #
+    # The list is ordered alphabetically by command names, starting with all
+    # the commands in core then all the commands in the extensions
+    #
+    # The general guideline is:
+    # - remove directaccess warnings for read only commands
+    # - no direct access for commands with consequences outside of the repo
+    # - leave directaccess warnings for all the other commands
+    #
+    ('nowarning', None, 'annotate'),
+    ('nowarning', None, 'archive'),
+    ('nowarning', None, 'bisect'),
+    ('nowarning', None, 'bookmarks'),
+    ('nowarning', None, 'bundle'),
+    ('nowarning', None, 'cat'),
+    ('nowarning', None, 'diff'),
+    ('nowarning', None, 'export'),
+    ('nowarning', None, 'identify'),
+    ('nowarning', None, 'incoming'),
+    ('nowarning', None, 'log'),
+    ('nowarning', None, 'manifest'),
+    ('error', None, 'outgoing'), # confusing if push errors and not outgoing
+    ('error', None, 'push'), # destructive
+    ('nowarning', None, 'revert'),
+    ('error', None, 'serve'),
+    ('nowarning', None, 'tags'),
+    ('nowarning', None, 'unbundle'),
+    ('nowarning', None, 'update'),
+]
+
+def reposetup(ui, repo):
+    repo._explicitaccess = set()
+
+def _computehidden(repo):
+    hidden = repoview.filterrevs(repo, 'visible')
+    cl = repo.changelog
+    dynamic = hidden & repo._explicitaccess
+    if dynamic:
+        blocked = cl.ancestors(dynamic, inclusive=True)
+        hidden = frozenset(r for r in hidden if r not in blocked)
+    return hidden
+
+def setupdirectaccess():
+    """ Add two new filtername that behave like visible to provide direct access
+    and direct access with warning. Wraps the commands to setup direct access
+    """
+    repoview.filtertable.update({'visible-directaccess-nowarn': _computehidden})
+    repoview.filtertable.update({'visible-directaccess-warn': _computehidden})
+    branchmap.subsettable['visible-directaccess-nowarn'] = 'visible'
+    branchmap.subsettable['visible-directaccess-warn'] = 'visible'
+
+    for warn, ext, cmd in directaccesslevel:
+        try:
+            cmdtable = extensions.find(ext).cmdtable if ext else commands.table
+            wrapper = wrapwitherror if warn == 'error' else wrapwithoutwarning
+            extensions.wrapcommand(cmdtable, cmd, wrapper)
+        except (error.UnknownCommand, KeyError):
+            pass
+
+def wrapwitherror(orig, ui, repo, *args, **kwargs):
+    if repo and repo.filtername == 'visible-directaccess-warn':
+        repo = repo.filtered('visible')
+    return orig(ui, repo, *args, **kwargs)
+
+def wrapwithoutwarning(orig, ui, repo, *args, **kwargs):
+    if repo and repo.filtername == 'visible-directaccess-warn':
+        repo = repo.filtered("visible-directaccess-nowarn")
+    return orig(ui, repo, *args, **kwargs)
+
+def uisetup(ui):
+    """ Change ordering of extensions to ensure that directaccess extsetup comes
+    after the one of the extensions in the loadsafter list """
+    loadsafter = ui.configlist('directaccess','loadsafter')
+    order = list(extensions._order)
+    directaccesidx = order.index('directaccess')
+
+    # The min idx for directaccess to load after all the extensions in loadafter
+    minidxdirectaccess = directaccesidx
+
+    for ext in loadsafter:
+        try:
+            minidxdirectaccess = max(minidxdirectaccess, order.index(ext))
+        except ValueError:
+            pass # extension not loaded
+
+    if minidxdirectaccess > directaccesidx:
+        order.insert(minidxdirectaccess + 1, 'directaccess')
+        order.remove('directaccess')
+        extensions._order = order
+
+def _repository(orig, *args, **kwargs):
+    """Make visible-directaccess-warn the default filter for new repos"""
+    repo = orig(*args, **kwargs)
+    return repo.filtered("visible-directaccess-warn")
+
+def extsetup(ui):
+    extensions.wrapfunction(revset, 'posttreebuilthook', _posttreebuilthook)
+    extensions.wrapfunction(hg, 'repository', _repository)
+    setupdirectaccess()
+
+hashre = util.re.compile('[0-9a-fA-F]{1,40}')
+
+_listtuple = ('symbol', '_list')
+
+def _ishashsymbol(symbol, maxrev):
+    # Returns true if symbol looks like a hash
+    try:
+        n = int(symbol)
+        if n <= maxrev:
+            # It's a rev number
+            return False
+    except ValueError:
+        pass
+    return hashre.match(symbol)
+
+def gethashsymbols(tree, maxrev):
+    # Returns the list of symbols of the tree that look like hashes
+    # for example for the revset 3::abe3ff it will return ('abe3ff')
+    if not tree:
+        return []
+
+    results = []
+    if len(tree) == 2 and tree[0] == "symbol":
+        results.append(tree[1])
+    elif tree[0] == "func" and tree[1] == _listtuple:
+        # the optimiser will group sequence of hash request
+        results += tree[2][1].split('\0')
+    elif len(tree) >= 3:
+        for subtree in tree[1:]:
+            results += gethashsymbols(subtree, maxrev)
+        # return directly, we don't need to filter symbols again
+        return results
+    return [s for s in results if _ishashsymbol(s, maxrev)]
+
+def _posttreebuilthook(orig, tree, repo):
+    # This is use to enabled direct hash access
+    # We extract the symbols that look like hashes and add them to the
+    # explicitaccess set
+    orig(tree, repo)
+    filternm = ""
+    if repo is not None:
+        filternm = repo.filtername
+    if filternm is not None and filternm.startswith('visible-directaccess'):
+        prelength = len(repo._explicitaccess)
+        accessbefore = set(repo._explicitaccess)
+        cl = repo.unfiltered().changelog
+        repo.symbols = gethashsymbols(tree, len(cl))
+        for node in repo.symbols:
+            try:
+                node = cl._partialmatch(node)
+            except error.LookupError:
+                node = None
+            if node is not None:
+                rev = cl.rev(node)
+                if rev not in repo.changelog:
+                    repo._explicitaccess.add(rev)
+        if prelength != len(repo._explicitaccess):
+            if repo.filtername != 'visible-directaccess-nowarn':
+                unhiddencommits = repo._explicitaccess - accessbefore
+                repo.ui.warn(_("Warning: accessing hidden changesets %s "
+                                "for write operation\n") %
+                                (",".join([str(repo.unfiltered()[l])
+                                    for l in unhiddencommits])))
+            repo.invalidatevolatilesets()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/hack/drophack.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,163 @@
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+'''This extension add a hacky command to drop changeset during review
+
+This extension is intended as a temporary hack to allow Matt Mackall to use
+evolve in the Mercurial review it self. You should probably not use it if your
+name is not Matt Mackall.
+'''
+
+import os
+import time
+import contextlib
+
+from mercurial.i18n import _
+from mercurial import cmdutil
+from mercurial import repair
+from mercurial import scmutil
+from mercurial import lock as lockmod
+from mercurial import util
+from mercurial import commands
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+
+@contextlib.contextmanager
+def timed(ui, caption):
+    ostart = os.times()
+    cstart = time.time()
+    yield
+    cstop = time.time()
+    ostop = os.times()
+    wall = cstop - cstart
+    user = ostop[0] - ostart[0]
+    sys  = ostop[1] - ostart[1]
+    comb = user + sys
+    ui.write("%s: wall %f comb %f user %f sys %f\n"
+             % (caption, wall, comb, user, sys))
+
+def obsmarkerchainfrom(obsstore, nodes):
+    """return all marker chain starting from node
+
+    Starting from mean "use as successors"."""
+    # XXX need something smarter for descendant of bumped changeset
+    seennodes = set(nodes)
+    seenmarkers = set()
+    pendingnodes = set(nodes)
+    precursorsmarkers = obsstore.precursors
+    while pendingnodes:
+        current = pendingnodes.pop()
+        new = set()
+        for precmark in precursorsmarkers.get(current, ()):
+            if precmark in seenmarkers:
+                continue
+            seenmarkers.add(precmark)
+            new.add(precmark[0])
+            yield precmark
+        new -= seennodes
+        pendingnodes |= new
+
+def stripmarker(ui, repo, markers):
+    """remove <markers> from the repo obsstore
+
+    The old obsstore content is saved in a `obsstore.prestrip` file
+    """
+    repo = repo.unfiltered()
+    repo.destroying()
+    oldmarkers = list(repo.obsstore._all)
+    util.rename(repo.sjoin('obsstore'),
+                repo.join('obsstore.prestrip'))
+    del repo.obsstore # drop the cache
+    newstore = repo.obsstore
+    assert not newstore # should be empty after rename
+    newmarkers = [m for m in oldmarkers if m not in markers]
+    tr = repo.transaction('drophack')
+    try:
+        newstore.add(tr, newmarkers)
+        tr.close()
+    finally:
+        tr.release()
+    repo.destroyed()
+
+
+@command('drop', [('r', 'rev', [], 'revision to update')], _('[-r] revs'))
+def cmddrop(ui, repo, *revs, **opts):
+    """I'm hacky do not use me!
+
+    This command strip a changeset, its precursors and all obsolescence marker
+    associated to its chain.
+
+    There is no way to limit the extend of the purge yet. You may have to
+    repull from other source to get some changeset and obsolescence marker
+    back.
+
+    This intended for Matt Mackall usage only. do not use me.
+    """
+    revs = list(revs)
+    revs.extend(opts['rev'])
+    if not revs:
+        revs = ['.']
+    # get the changeset
+    revs = scmutil.revrange(repo, revs)
+    if not revs:
+        ui.write_err('no revision to drop\n')
+        return 1
+    # lock from the beginning to prevent race
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        # check they have no children
+        if repo.revs('%ld and public()', revs):
+            ui.write_err('cannot drop public revision')
+            return 1
+        if repo.revs('children(%ld) - %ld', revs, revs):
+            ui.write_err('cannot drop revision with children')
+            return 1
+        if repo.revs('. and %ld', revs):
+            newrevs = repo.revs('max(::. - %ld)', revs)
+            if newrevs:
+                assert len(newrevs) == 1
+                newrev = newrevs.first()
+            else:
+                newrev = -1
+            commands.update(ui, repo, newrev)
+            ui.status(_('working directory now at %s\n') % repo[newrev])
+        # get all markers and successors up to root
+        nodes = [repo[r].node() for r in revs]
+        with timed(ui, 'search obsmarker'):
+            markers = set(obsmarkerchainfrom(repo.obsstore, nodes))
+        ui.write('%i obsmarkers found\n' % len(markers))
+        cl = repo.unfiltered().changelog
+        with timed(ui, 'search nodes'):
+            allnodes = set(nodes)
+            allnodes.update(m[0] for m in markers if cl.hasnode(m[0]))
+        ui.write('%i nodes found\n' % len(allnodes))
+        cl = repo.changelog
+        visiblenodes = set(n for n in allnodes if cl.hasnode(n))
+        # check constraint again
+        if repo.revs('%ln and public()', visiblenodes):
+            ui.write_err('cannot drop public revision')
+            return 1
+        if repo.revs('children(%ln) - %ln', visiblenodes, visiblenodes):
+            ui.write_err('cannot drop revision with children')
+            return 1
+
+        if markers:
+            # strip them
+            with timed(ui, 'strip obsmarker'):
+                stripmarker(ui, repo, markers)
+        # strip the changeset
+        with timed(ui, 'strip nodes'):
+            repair.strip(ui, repo, list(allnodes), backup="all",
+                         topic='drophack')
+
+    finally:
+        lockmod.release(lock, wlock)
+
+    # rewrite the whole file.
+    # print data.
+    # - time to compute the chain
+    # - time to strip the changeset
+    # - time to strip the obs marker.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/hack/inhibit.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,310 @@
+"""reduce the changesets evolution feature scope for early and noob friendly ui
+
+the full scale changeset evolution have some massive bleeding edge and it is
+very easy for people not very intimate with the concept to end up in intricate
+situation. in order to get some of the benefit sooner, this extension is
+disabling some of the less polished aspect of evolution. it should gradually
+get thinner and thinner as changeset evolution will get more polished. this
+extension is only recommended for large scale organisations. individual user
+should probably stick on using evolution in its current state, understand its
+concept and provide feedback
+
+This extension provides the ability to "inhibit" obsolescence markers. obsolete
+revision can be cheaply brought back to life that way.
+However as the inhibitor are not fitting in an append only model, this is
+incompatible with sharing mutable history.
+"""
+from mercurial import localrepo
+from mercurial import obsolete
+from mercurial import extensions
+from mercurial import cmdutil
+from mercurial import error
+from mercurial import scmutil
+from mercurial import commands
+from mercurial import lock as lockmod
+from mercurial import bookmarks
+from mercurial import util
+from mercurial.i18n import _
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+def _inhibitenabled(repo):
+    return util.safehasattr(repo, '_obsinhibit')
+
+def reposetup(ui, repo):
+
+    class obsinhibitedrepo(repo.__class__):
+
+        @localrepo.storecache('obsinhibit')
+        def _obsinhibit(self):
+            # XXX we should make sure it is invalidated by transaction failure
+            obsinhibit = set()
+            raw = self.svfs.tryread('obsinhibit')
+            for i in xrange(0, len(raw), 20):
+                obsinhibit.add(raw[i:i + 20])
+            return obsinhibit
+
+        def commit(self, *args, **kwargs):
+            newnode = super(obsinhibitedrepo, self).commit(*args, **kwargs)
+            if newnode is not None:
+                _inhibitmarkers(repo, [newnode])
+            return newnode
+
+    repo.__class__ = obsinhibitedrepo
+
+def _update(orig, ui, repo, *args, **kwargs):
+    """
+    When moving to a commit we want to inhibit any obsolete commit affecting
+    the changeset we are updating to. In other words we don't want any visible
+    commit to be obsolete.
+    """
+    wlock = None
+    try:
+        # Evolve is running a hook on lock release to display a warning message
+        # if the workind dir's parent is obsolete.
+        # We take the lock here to make sure that we inhibit the parent before
+        # that hook get a chance to run.
+        wlock = repo.wlock()
+        res = orig(ui, repo, *args, **kwargs)
+        newhead = repo['.'].node()
+        _inhibitmarkers(repo, [newhead])
+        return res
+    finally:
+        lockmod.release(wlock)
+
+def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
+    """ Add inhibition markers to every obsolete bookmarks """
+    repo = bkmstoreinst._repo
+    bkmstorenodes = [repo[v].node() for v in bkmstoreinst.values()]
+    _inhibitmarkers(repo, bkmstorenodes)
+    return orig(bkmstoreinst, *args, **kwargs)
+
+def _bookmark(orig, ui, repo, *bookmarks, **opts):
+    """ Add a -D option to the bookmark command, map it to prune -B """
+    haspruneopt = opts.get('prune', False)
+    if not haspruneopt:
+        return orig(ui, repo, *bookmarks, **opts)
+    elif opts.get('rename'):
+        raise error.Abort('Cannot use both -m and -D')
+    elif len(bookmarks) == 0:
+        hint = _('make sure to put a space between -D and your bookmark name')
+        raise error.Abort(_('Error, please check your command'), hint=hint)
+
+    # Call prune -B
+    evolve = extensions.find('evolve')
+    optsdict = {
+        'new': [],
+        'succ': [],
+        'rev': [],
+        'bookmark': bookmarks,
+        'keep': None,
+        'biject': False,
+    }
+    evolve.cmdprune(ui, repo, **optsdict)
+
+# obsolescence inhibitor
+########################
+
+def _schedulewrite(tr, obsinhibit):
+    """Make sure on disk content will be updated on transaction commit"""
+    def writer(fp):
+        """Serialize the inhibited list to disk.
+        """
+        raw = ''.join(obsinhibit)
+        fp.write(raw)
+    tr.addfilegenerator('obsinhibit', ('obsinhibit',), writer)
+    tr.hookargs['obs_inbihited'] = '1'
+
+def _filterpublic(repo, nodes):
+    """filter out inhibitor on public changeset
+
+    Public changesets are already immune to obsolescence"""
+    getrev = repo.changelog.nodemap.get
+    getphase = repo._phasecache.phase
+    return (n for n in nodes
+            if getrev(n) is not None and getphase(repo, getrev(n)))
+
+def _inhibitmarkers(repo, nodes):
+    """add marker inhibitor for all obsolete revision under <nodes>
+
+    Content of <nodes> and all mutable ancestors are considered. Marker for
+    obsolete revision only are created.
+    """
+    if not _inhibitenabled(repo):
+        return
+
+    # we add (non public()) as a lower boundary to
+    # - use the C code in 3.6 (no ancestors in C as this is written)
+    # - restrict the search space. Otherwise, the ancestors can spend a lot of
+    #   time iterating if you have a check very low in the repo. We do not need
+    #   to iterate over tens of thousand of public revisions with higher
+    #   revision number
+    #
+    # In addition, the revset logic could be made significantly smarter here.
+    newinhibit = repo.revs('(not public())::%ln and obsolete()', nodes)
+    if newinhibit:
+        node = repo.changelog.node
+        lock = tr = None
+        try:
+            lock = repo.lock()
+            tr = repo.transaction('obsinhibit')
+            repo._obsinhibit.update(node(r) for r in newinhibit)
+            _schedulewrite(tr, _filterpublic(repo, repo._obsinhibit))
+            repo.invalidatevolatilesets()
+            tr.close()
+        finally:
+            lockmod.release(tr, lock)
+
+def _deinhibitmarkers(repo, nodes):
+    """lift obsolescence inhibition on a set of nodes
+
+    This will be triggered when inhibited nodes received new obsolescence
+    markers. Otherwise the new obsolescence markers would also be inhibited.
+    """
+    if not _inhibitenabled(repo):
+        return
+
+    deinhibited = repo._obsinhibit & set(nodes)
+    if deinhibited:
+        tr = repo.transaction('obsinhibit')
+        try:
+            repo._obsinhibit -= deinhibited
+            _schedulewrite(tr, _filterpublic(repo, repo._obsinhibit))
+            repo.invalidatevolatilesets()
+            tr.close()
+        finally:
+            tr.release()
+
+def _createmarkers(orig, repo, relations, flag=0, date=None, metadata=None):
+    """wrap markers create to make sure we de-inhibit target nodes"""
+    # wrapping transactio to unify the one in each function
+    lock = tr = None
+    try:
+        lock = repo.lock()
+        tr = repo.transaction('add-obsolescence-marker')
+        orig(repo, relations, flag, date, metadata)
+        precs = (r[0].node() for r in relations)
+        _deinhibitmarkers(repo, precs)
+        tr.close()
+    finally:
+        lockmod.release(tr, lock)
+
+def _filterobsoleterevswrap(orig, repo, rebasesetrevs, *args, **kwargs):
+    repo._notinhibited = rebasesetrevs
+    try:
+        repo.invalidatevolatilesets()
+        r = orig(repo, rebasesetrevs, *args, **kwargs)
+    finally:
+        del repo._notinhibited
+        repo.invalidatevolatilesets()
+    return r
+
+def transactioncallback(orig, repo, desc, *args, **kwargs):
+    """ Wrap localrepo.transaction to inhibit new obsolete changes """
+    def inhibitposttransaction(transaction):
+        # At the end of the transaction we catch all the new visible and
+        # obsolete commit to inhibit them
+        visibleobsolete = repo.revs('obsolete() - hidden()')
+        ignoreset = set(getattr(repo, '_rebaseset', []))
+        ignoreset |= set(getattr(repo, '_obsoletenotrebased', []))
+        visibleobsolete = list(r for r in visibleobsolete if r not in ignoreset)
+        if visibleobsolete:
+            _inhibitmarkers(repo, [repo[r].node() for r in visibleobsolete])
+    transaction = orig(repo, desc, *args, **kwargs)
+    if desc != 'strip' and _inhibitenabled(repo):
+        transaction.addpostclose('inhibitposttransaction',
+                                 inhibitposttransaction)
+    return transaction
+
+
+# We wrap these two functions to address the following scenario:
+# - Assuming that we have markers between commits in the rebase set and
+#   destination and that these markers are inhibited
+# - At the end of the rebase the nodes are still visible because rebase operate
+#   without inhibition and skip these nodes
+# We keep track in repo._obsoletenotrebased of the obsolete commits skipped by
+# the rebase and lift the inhibition in the end of the rebase.
+
+def _computeobsoletenotrebased(orig, repo, *args, **kwargs):
+    r = orig(repo, *args, **kwargs)
+    repo._obsoletenotrebased = r.keys()
+    return r
+
+def _clearrebased(orig, ui, repo, *args, **kwargs):
+    r = orig(ui, repo, *args, **kwargs)
+    tonode = repo.changelog.node
+    if util.safehasattr(repo, '_obsoletenotrebased'):
+        _deinhibitmarkers(repo, [tonode(k) for k in repo._obsoletenotrebased])
+    return r
+
+
+def extsetup(ui):
+    # lets wrap the computation of the obsolete set
+    # We apply inhibition there
+    obsfunc = obsolete.cachefuncs['obsolete']
+    def _computeobsoleteset(repo):
+        """remove any inhibited nodes from the obsolete set
+
+        This will trickle down to other part of mercurial (hidden, log, etc)"""
+        obs = obsfunc(repo)
+        if _inhibitenabled(repo):
+            getrev = repo.changelog.nodemap.get
+            blacklist = getattr(repo, '_notinhibited', set())
+            for n in repo._obsinhibit:
+                if getrev(n) not in blacklist:
+                    obs.discard(getrev(n))
+        return obs
+    try:
+        extensions.find('directaccess')
+    except KeyError:
+        errormsg = _('cannot use inhibit without the direct access extension\n')
+        hint = _("(please enable it or inhibit won\'t work)\n")
+        ui.warn(errormsg)
+        ui.warn(hint)
+        return
+
+    # Wrapping this to inhibit obsolete revs resulting from a transaction
+    extensions.wrapfunction(localrepo.localrepository,
+                            'transaction', transactioncallback)
+
+    obsolete.cachefuncs['obsolete'] = _computeobsoleteset
+    # wrap create marker to make it able to lift the inhibition
+    extensions.wrapfunction(obsolete, 'createmarkers', _createmarkers)
+    # drop divergence computation since it is incompatible with "light revive"
+    obsolete.cachefuncs['divergent'] = lambda repo: set()
+    # drop bumped computation since it is incompatible with "light revive"
+    obsolete.cachefuncs['bumped'] = lambda repo: set()
+    # wrap update to make sure that no obsolete commit is visible after an
+    # update
+    extensions.wrapcommand(commands.table, 'update', _update)
+    try:
+        rebase = extensions.find('rebase')
+        if rebase:
+            if util.safehasattr(rebase, '_filterobsoleterevs'):
+                extensions.wrapfunction(rebase,
+                                        '_filterobsoleterevs',
+                                        _filterobsoleterevswrap)
+            extensions.wrapfunction(rebase, 'clearrebased', _clearrebased)
+            if util.safehasattr(rebase, '_computeobsoletenotrebased'):
+                extensions.wrapfunction(rebase,
+                                        '_computeobsoletenotrebased',
+                                        _computeobsoletenotrebased)
+
+    except KeyError:
+        pass
+    # There are two ways to save bookmark changes during a transation, we
+    # wrap both to add inhibition markers.
+    extensions.wrapfunction(bookmarks.bmstore, 'recordchange', _bookmarkchanged)
+    if getattr(bookmarks.bmstore, 'write', None) is not None:# mercurial < 3.9
+        extensions.wrapfunction(bookmarks.bmstore, 'write', _bookmarkchanged)
+    # Add bookmark -D option
+    entry = extensions.wrapcommand(commands.table, 'bookmark', _bookmark)
+    entry[1].append(('D','prune',None,
+                    _('delete the bookmark and prune the commits underneath')))
+
+@command('debugobsinhibit', [], '')
+def cmddebugobsinhibit(ui, repo, *revs):
+    """inhibit obsolescence markers effect on a set of revs"""
+    nodes = (repo[r].node() for r in scmutil.revrange(repo, revs))
+    _inhibitmarkers(repo, nodes)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/legacy.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,163 @@
+# Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+#                Logilab SA        <contact@logilab.fr>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""Deprecated extension that formerly introduced "Changeset Obsolescence".
+
+This concept is now partially in Mercurial core (starting with Mercurial 2.3).
+The remaining logic has been grouped with the evolve extension.
+
+Some code remains in this extensions to detect and convert prehistoric format
+of obsolete marker than early user may have create. Keep it enabled if you
+were such user.
+"""
+
+from mercurial import error
+
+try:
+    from mercurial import obsolete
+except ImportError:
+    raise error.Abort('Obsolete extension requires Mercurial 2.3 (or later)')
+
+import sys
+import json
+
+from mercurial import cmdutil
+from mercurial.i18n import _
+from mercurial.node import bin, nullid
+from mercurial import util
+
+
+#####################################################################
+### Older format management                                       ###
+#####################################################################
+
+# Code related to detection and management of older legacy format never
+# handled by core
+
+
+def reposetup(ui, repo):
+    """Detect that a repo still contains some old obsolete format
+    """
+    if not repo.local():
+        return
+    evolveopts = ui.configlist('experimental', 'evolution')
+    if not evolveopts:
+        evolveopts = 'all'
+        ui.setconfig('experimental', 'evolution', evolveopts)
+    for arg in sys.argv:
+        if 'debugc' in arg:
+            break
+    else:
+        data = repo.opener.tryread('obsolete-relations')
+        if not data:
+            data = repo.svfs.tryread('obsoletemarkers')
+        if data:
+            raise error.Abort('old format of obsolete marker detected!\n'
+                              'run `hg debugconvertobsolete` once.')
+
+def _obsdeserialize(flike):
+    """read a file like object serialized with _obsserialize
+
+    this deserialize into a {subject -> objects} mapping
+
+    this was the very first format ever."""
+    rels = {}
+    for line in flike:
+        subhex, objhex = line.split()
+        subnode = bin(subhex)
+        if subnode == nullid:
+            subnode = None
+        rels.setdefault(subnode, set()).add(bin(objhex))
+    return rels
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+@command('debugconvertobsolete', [], '')
+def cmddebugconvertobsolete(ui, repo):
+    """import markers from an .hg/obsolete-relations file"""
+    cnt = 0
+    err = 0
+    l = repo.lock()
+    some = False
+    try:
+        unlink = []
+        tr = repo.transaction('convert-obsolete')
+        try:
+            repo._importoldobsolete = True
+            store = repo.obsstore
+            ### very first format
+            try:
+                f = repo.opener('obsolete-relations')
+                try:
+                    some = True
+                    for line in f:
+                        subhex, objhex = line.split()
+                        suc = bin(subhex)
+                        prec = bin(objhex)
+                        sucs = (suc==nullid) and [] or [suc]
+                        meta = {
+                            'date':  '%i %i' % util.makedate(),
+                            'user': ui.username(),
+                            }
+                        try:
+                            store.create(tr, prec, sucs, 0, metadata=meta)
+                            cnt += 1
+                        except ValueError:
+                            repo.ui.write_err("invalid old marker line: %s"
+                                              % (line))
+                            err += 1
+                finally:
+                    f.close()
+                unlink.append(repo.join('obsolete-relations'))
+            except IOError:
+                pass
+            ### second (json) format
+            data = repo.svfs.tryread('obsoletemarkers')
+            if data:
+                some = True
+                for oldmark in json.loads(data):
+                    del oldmark['id']  # dropped for now
+                    del oldmark['reason']  # unused until then
+                    oldobject = str(oldmark.pop('object'))
+                    oldsubjects = [str(s) for s in oldmark.pop('subjects', [])]
+                    LOOKUP_ERRORS = (error.RepoLookupError, error.LookupError)
+                    if len(oldobject) != 40:
+                        try:
+                            oldobject = repo[oldobject].node()
+                        except LOOKUP_ERRORS:
+                            pass
+                    if any(len(s) != 40 for s in oldsubjects):
+                        try:
+                            oldsubjects = [repo[s].node() for s in oldsubjects]
+                        except LOOKUP_ERRORS:
+                            pass
+
+                    oldmark['date'] = '%i %i' % tuple(oldmark['date'])
+                    meta = dict((k.encode('utf-8'), v.encode('utf-8'))
+                                 for k, v in oldmark.iteritems())
+                    try:
+                        succs = [bin(n) for n in oldsubjects]
+                        succs = [n for n in succs if n != nullid]
+                        store.create(tr, bin(oldobject), succs,
+                                     0, metadata=meta)
+                        cnt += 1
+                    except ValueError:
+                        repo.ui.write_err("invalid marker %s -> %s\n"
+                                     % (oldobject, oldsubjects))
+                        err += 1
+                unlink.append(repo.sjoin('obsoletemarkers'))
+            tr.close()
+            for path in unlink:
+                util.unlink(path)
+        finally:
+            tr.release()
+    finally:
+        del repo._importoldobsolete
+        l.release()
+    if not some:
+        ui.warn(_('nothing to do\n'))
+    ui.status('%i obsolete marker converted\n' % cnt)
+    if err:
+        ui.write_err('%i conversion failed. check you graph!\n' % err)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/serveronly.py	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,259 @@
+'''enable experimental obsolescence feature of Mercurial
+
+OBSOLESCENCE IS AN EXPERIMENTAL FEATURE MAKE SURE YOU UNDERSTOOD THE INVOLVED
+CONCEPT BEFORE USING IT.
+
+/!\ THIS EXTENSION IS INTENDED FOR SERVER SIDE ONLY USAGE /!\
+
+For client side usages it is recommended to use the evolve extension for
+improved user interface.'''
+
+testedwith = '3.3 3.4-rc'
+buglink = 'https://bz.mercurial-scm.org/'
+
+import hashlib
+import struct
+from cStringIO import StringIO
+
+
+from mercurial import (
+    error,
+    exchange,
+    extensions,
+    localrepo,
+    lock as lockmod,
+    node,
+    obsolete,
+    util,
+    wireproto
+)
+from mercurial.hgweb import hgweb_mod
+from mercurial.i18n import _
+_pack = struct.pack
+
+gboptslist = gboptsmap = None
+try:
+    gboptslist = getattr(wireproto, 'gboptslist', None)
+    gboptsmap = getattr(wireproto, 'gboptsmap', None)
+except (ImportError, AttributeError):
+    raise error.Abort('Your Mercurial is too old for this version of Evolve\n'
+                      'requires version 3.0.1 or above')
+
+# Start of simple4server specific content
+
+from mercurial import pushkey
+
+# specific content also include the wrapping int extsetup
+def _nslist(orig, repo):
+    rep = orig(repo)
+    if not repo.ui.configbool('__temporary__', 'advertiseobsolete', True):
+        rep.pop('obsolete')
+    return rep
+
+# End of simple4server specific content
+
+
+def obsexcmsg(ui, message, important=False):
+    verbose = ui.configbool('experimental', 'verbose-obsolescence-exchange',
+                             False)
+    if verbose:
+        message = 'OBSEXC: ' + message
+    if important or verbose:
+        ui.status(message)
+
+def _pushobsmarkers(repo, data):
+    tr = lock = None
+    try:
+        lock = repo.lock()
+        tr = repo.transaction('pushkey: obsolete markers')
+        new = repo.obsstore.mergemarkers(tr, data)
+        if new is not None:
+            obsexcmsg(repo.ui, "%i obsolescence markers added\n" % new, True)
+        tr.close()
+    finally:
+        lockmod.release(tr, lock)
+    repo.hook('evolve_pushobsmarkers')
+
+def srv_pushobsmarkers(repo, proto):
+    """wireprotocol command"""
+    fp = StringIO()
+    proto.redirect()
+    proto.getfile(fp)
+    data = fp.getvalue()
+    fp.close()
+    _pushobsmarkers(repo, data)
+    return wireproto.pushres(0)
+
+def _getobsmarkersstream(repo, heads=None, common=None):
+    """Get a binary stream for all markers relevant to `::<heads> - ::<common>`
+    """
+    revset = ''
+    args = []
+    repo = repo.unfiltered()
+    if heads is None:
+        revset = 'all()'
+    elif heads:
+        revset += "(::%ln)"
+        args.append(heads)
+    else:
+        assert False, 'pulling no heads?'
+    if common:
+        revset += ' - (::%ln)'
+        args.append(common)
+    nodes = [c.node() for c in repo.set(revset, *args)]
+    markers = repo.obsstore.relevantmarkers(nodes)
+    obsdata = StringIO()
+    for chunk in obsolete.encodemarkers(markers, True):
+        obsdata.write(chunk)
+    obsdata.seek(0)
+    return obsdata
+
+# The wireproto.streamres API changed, handling chunking and compression
+# directly. Handle either case.
+if util.safehasattr(wireproto.abstractserverproto, 'groupchunks'):
+    # We need to handle chunking and compression directly
+    def streamres(d, proto):
+        return wireproto.streamres(proto.groupchunks(d))
+else:
+    # Leave chunking and compression to streamres
+    def streamres(d, proto):
+        return wireproto.streamres(reader=d, v1compressible=True)
+
+def srv_pullobsmarkers(repo, proto, others):
+    """serves a binary stream of markers.
+
+    Serves relevant to changeset between heads and common. The stream is prefix
+    by a -string- representation of an integer. This integer is the size of the
+    stream."""
+    opts = wireproto.options('', ['heads', 'common'], others)
+    for k, v in opts.iteritems():
+        if k in ('heads', 'common'):
+            opts[k] = wireproto.decodelist(v)
+    obsdata = _getobsmarkersstream(repo, **opts)
+    finaldata = StringIO()
+    obsdata = obsdata.getvalue()
+    finaldata.write('%20i' % len(obsdata))
+    finaldata.write(obsdata)
+    finaldata.seek(0)
+    return streamres(finaldata, proto)
+
+def _obsrelsethashtreefm0(repo):
+    return _obsrelsethashtree(repo, obsolete._fm0encodeonemarker)
+
+def _obsrelsethashtreefm1(repo):
+    return _obsrelsethashtree(repo, obsolete._fm1encodeonemarker)
+
+def _obsrelsethashtree(repo, encodeonemarker):
+    cache = []
+    unfi = repo.unfiltered()
+    markercache = {}
+    repo.ui.progress(_("preparing locally"), 0, total=len(unfi))
+    for i in unfi:
+        ctx = unfi[i]
+        entry = 0
+        sha = hashlib.sha1()
+        # add data from p1
+        for p in ctx.parents():
+            p = p.rev()
+            if p < 0:
+                p = node.nullid
+            else:
+                p = cache[p][1]
+            if p != node.nullid:
+                entry += 1
+                sha.update(p)
+        tmarkers = repo.obsstore.relevantmarkers([ctx.node()])
+        if tmarkers:
+            bmarkers = []
+            for m in tmarkers:
+                if not m in markercache:
+                    markercache[m] = encodeonemarker(m)
+                bmarkers.append(markercache[m])
+            bmarkers.sort()
+            for m in bmarkers:
+                entry += 1
+                sha.update(m)
+        if entry:
+            cache.append((ctx.node(), sha.digest()))
+        else:
+            cache.append((ctx.node(), node.nullid))
+        repo.ui.progress(_("preparing locally"), i, total=len(unfi))
+    repo.ui.progress(_("preparing locally"), None)
+    return cache
+
+def _obshash(repo, nodes, version=0):
+    if version == 0:
+        hashs = _obsrelsethashtreefm0(repo)
+    elif version ==1:
+        hashs = _obsrelsethashtreefm1(repo)
+    else:
+        assert False
+    nm = repo.changelog.nodemap
+    revs = [nm.get(n) for n in nodes]
+    return [r is None and nullid or hashs[r][1] for r in revs]
+
+def srv_obshash(repo, proto, nodes):
+    return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes)))
+
+def srv_obshash1(repo, proto, nodes):
+    return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes),
+                                version=1))
+
+def capabilities(orig, repo, proto):
+    """wrapper to advertise new capability"""
+    caps = orig(repo, proto)
+    advertise = repo.ui.configbool('__temporary__', 'advertiseobsolete', True)
+    if obsolete.isenabled(repo, obsolete.exchangeopt) and advertise:
+        caps += ' _evoext_pushobsmarkers_0'
+        caps += ' _evoext_pullobsmarkers_0'
+        caps += ' _evoext_obshash_0'
+        caps += ' _evoext_obshash_1'
+        caps += ' _evoext_getbundle_obscommon'
+    return caps
+
+def _getbundleobsmarkerpart(orig, bundler, repo, source, **kwargs):
+    if 'evo_obscommon' not in kwargs:
+        return orig(bundler, repo, source, **kwargs)
+
+    heads = kwargs.get('heads')
+    if kwargs.get('obsmarkers', False):
+        if heads is None:
+            heads = repo.heads()
+        obscommon = kwargs.get('evo_obscommon', ())
+        assert obscommon
+        obsset = repo.unfiltered().set('::%ln - ::%ln', heads, obscommon)
+        subset = [c.node() for c in obsset]
+        markers = repo.obsstore.relevantmarkers(subset)
+        exchange.buildobsmarkerspart(bundler, markers)
+
+def extsetup(ui):
+    localrepo.moderncaps.add('_evoext_b2x_obsmarkers_0')
+    gboptsmap['evo_obscommon'] = 'nodes'
+    hgweb_mod.perms['evoext_pushobsmarkers_0'] = 'push'
+    hgweb_mod.perms['evoext_pullobsmarkers_0'] = 'pull'
+    hgweb_mod.perms['evoext_obshash'] = 'pull'
+    hgweb_mod.perms['evoext_obshash1'] = 'pull'
+    wireproto.commands['evoext_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
+    wireproto.commands['evoext_pullobsmarkers_0'] = (srv_pullobsmarkers, '*')
+    # wrap module content
+    origfunc = exchange.getbundle2partsmapping['obsmarkers']
+    def newfunc(*args, **kwargs):
+        return _getbundleobsmarkerpart(origfunc, *args, **kwargs)
+    exchange.getbundle2partsmapping['obsmarkers'] = newfunc
+    extensions.wrapfunction(wireproto, 'capabilities', capabilities)
+    # wrap command content
+    oldcap, args = wireproto.commands['capabilities']
+    def newcap(repo, proto):
+        return capabilities(oldcap, repo, proto)
+    wireproto.commands['capabilities'] = (newcap, args)
+    wireproto.commands['evoext_obshash'] = (srv_obshash, 'nodes')
+    wireproto.commands['evoext_obshash1'] = (srv_obshash1, 'nodes')
+    # specific simple4server content
+    extensions.wrapfunction(pushkey, '_nslist', _nslist)
+    pushkey._namespaces['namespaces'] = (lambda *x: False, pushkey._nslist)
+
+def reposetup(ui, repo):
+    evolveopts = ui.configlist('experimental', 'evolution')
+    if not evolveopts:
+        evolveopts = 'all'
+        ui.setconfig('experimental', 'evolution', evolveopts)
--- a/setup.cfg	Thu Feb 23 15:19:31 2017 +0100
+++ b/setup.cfg	Thu Mar 02 18:07:46 2017 +0100
@@ -1,2 +1,3 @@
 [flake8]
-ignore = E261, E266, E302, E129, E731, E124, E501, E123, W503, N801
+ignore = E261, E266, E302, E305, E129, E731, E124, E501, E123, W503, N801
+
--- a/setup.py	Thu Feb 23 15:19:31 2017 +0100
+++ b/setup.py	Thu Mar 02 18:07:46 2017 +0100
@@ -1,24 +1,60 @@
+import os
 from distutils.core import setup
+from os.path import dirname, join
+
+def get_version(relpath):
+    '''Read version info from a file without importing it'''
+    for line in open(join(dirname(__file__), relpath), 'rb'):
+        # Decode to a fail-safe string for PY3
+        # (gives unicode object in PY2)
+        line = line.decode('utf8')
+        if '__version__' in line:
+          if "'" in line:
+            return line.split("'")[1]
+
+def min_hg_version(relpath):
+    '''Read version info from a file without importing it'''
+    for line in open(join(dirname(__file__), relpath), 'rb'):
+        # Decode to a fail-safe string for PY3
+        # (gives unicode object in PY2)
+        line = line.decode('utf8')
+        if 'testedwith' in line:
+          if "'" in line:
+            return min(line.split("'")[1].split())
+
+py_modules = [
+    'hgext3rd.evolve.serveronly',
+]
+py_packages = [
+    'hgext3rd',
+    'hgext3rd.topic',
+]
+
+if os.environ.get('INCLUDE_INHIBIT'):
+    py_modules.append('hgext3rd.evolve.hack.inhibit')
+    py_modules.append('hgext3rd.evolve.hack.directaccess')
+
+
+EVOLVE_PATH = 'hgext3rd/evolve/__init__.py'
 
 requires = []
 try:
     import mercurial
     mercurial.__all__
 except ImportError:
-    requires.append('mercurial')
+    requires.append('mercurial>=%s' % min_hg_version(EVOLVE_PATH))
 
 setup(
-    name='hg-topics',
-    version='1.0.0',
-    author='Augie Fackler',
-    maintainer='Augie Fackler',
-    maintainer_email='augie@google.com',
-    url='http://bitbucket.org/durin42/hg-topics/',
-    description=('Experimental tinkering with workflow ideas '
-                 'for topic branches.'),
-    long_description=open('README.md').read(),
+    name='hg-evolve',
+    version=get_version(EVOLVE_PATH),
+    author='Pierre-Yves David',
+    maintainer='Pierre-Yves David',
+    maintainer_email='pierre-yves.david@ens-lyon.org',
+    url='https://www.mercurial-scm.org/doc/evolution/',
+    description='Flexible evolution of Mercurial history.',
+    long_description=open('README').read(),
     keywords='hg mercurial',
     license='GPLv2+',
-    packages=['hgext3rd'],
-    install_requires=requires,
+    py_modules=py_modules,
+    packages=py_packages
 )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/_exc-util.sh	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,110 @@
+#!/bin/sh
+
+cat >> $HGRCPATH <<EOF
+[web]
+push_ssl = false
+allow_push = *
+
+[ui]
+logtemplate ="{node|short} ({phase}): {desc}\n"
+
+[phases]
+publish=False
+
+[experimental]
+verbose-obsolescence-exchange=false
+bundle2-exp=true
+bundle2-output-capture=True
+
+[alias]
+debugobsolete=debugobsolete -d '0 0'
+
+[extensions]
+hgext.strip=
+EOF
+echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+mkcommit() {
+   echo "$1" > "$1"
+   hg add "$1"
+   hg ci -m "$1"
+}
+getid() {
+   hg log --hidden --template '{node}\n' --rev "$1"
+}
+
+setuprepos() {
+    echo creating test repo for test case $1
+    mkdir $1
+    cd $1
+    echo - pulldest
+    hg init pushdest
+    cd pushdest
+    mkcommit O
+    hg phase --public .
+    cd ..
+    echo - main
+    hg clone -q pushdest main
+    echo - pushdest
+    hg clone -q main pulldest
+    echo 'cd into `main` and proceed with env setup'
+}
+
+dotest() {
+# dotest TESTNAME [TARGETNODE]
+
+    testcase=$1
+    shift
+    target="$1"
+    if [ $# -gt 0 ]; then
+        shift
+    fi
+    targetnode=""
+    desccall=""
+    cd $testcase
+    echo "## Running testcase $testcase"
+    if [ -n "$target" ]; then
+        desccall="desc("\'"$target"\'")"
+        targetnode="`hg -R main id -qr \"$desccall\"`"
+        echo "# testing echange of \"$target\" ($targetnode)"
+    fi
+    echo "## initial state"
+    echo "# obstore: main"
+    hg -R main     debugobsolete | sort
+    echo "# obstore: pushdest"
+    hg -R pushdest debugobsolete | sort
+    echo "# obstore: pulldest"
+    hg -R pulldest debugobsolete | sort
+
+    if [ -n "$target" ]; then
+        echo "## pushing \"$target\"" from main to pushdest
+        hg -R main push -r "$desccall" $@ pushdest
+    else
+        echo "## pushing from main to pushdest"
+        hg -R main push pushdest $@
+    fi
+    echo "## post push state"
+    echo "# obstore: main"
+    hg -R main     debugobsolete | sort
+    echo "# obstore: pushdest"
+    hg -R pushdest debugobsolete | sort
+    echo "# obstore: pulldest"
+    hg -R pulldest debugobsolete | sort
+    if [ -n "$target" ]; then
+        echo "## pulling \"$targetnode\"" from main into pulldest
+        hg -R pulldest pull -r $targetnode $@ main
+    else
+        echo "## pulling from main into pulldest"
+        hg -R pulldest pull main $@
+    fi
+    echo "## post pull state"
+    echo "# obstore: main"
+    hg -R main     debugobsolete | sort
+    echo "# obstore: pushdest"
+    hg -R pushdest debugobsolete | sort
+    echo "# obstore: pulldest"
+    hg -R pulldest debugobsolete | sort
+
+    cd ..
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fake-editor.sh	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,3 @@
+#!/bin/sh
+sleep 5
+echo "new desc" >> $1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-amend.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,161 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ glog() {
+  >   hg glog --template '{rev}@{branch}({phase}) {desc|firstline}\n' "$@"
+  > }
+
+  $ hg init repo --traceback
+  $ cd repo
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+
+Test that amend captures branches
+
+  $ hg branch foo
+  marked working directory as branch foo
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg amend -d '0 0'
+  $ hg debugobsolete
+  07f4944404050f47db2e5c5071e0e84e7a27bba9 6a022cbb61d5ba0f03f98ff2d36319dfea1034ae 0 (*) {'user': 'test'} (glob)
+  b2e32ffb533cbe1d5759638c0cd4e8abc43b2738 0 {07f4944404050f47db2e5c5071e0e84e7a27bba9} (*) {'user': 'test'} (glob)
+  $ hg branch
+  foo
+  $ hg branches
+  foo                            2:6a022cbb61d5
+  $ glog
+  @  2@foo(draft) adda
+  
+Test no-op
+
+  $ hg amend -d '0 0'
+  nothing changed
+  [1]
+  $ glog
+  @  2@foo(draft) adda
+  
+
+Test forcing the message to the same value, no intermediate revision.
+
+  $ hg amend -d '0 0' -m 'adda'
+  nothing changed
+  [1]
+  $ glog
+  @  2@foo(draft) adda
+  
+
+Test collapsing into an existing revision, no intermediate revision.
+
+  $ echo a >> a
+  $ hg ci -m changea
+  $ echo a > a
+  $ hg status
+  M a
+  $ hg pstatus
+  $ hg diff
+  diff -r f7a50201fe3a a
+  --- a/a	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	* +0000 (glob)
+  @@ -1,2 +1,1 @@
+   a
+  -a
+  $ hg pdiff
+  $ hg ci -m reseta
+  $ hg debugobsolete
+  07f4944404050f47db2e5c5071e0e84e7a27bba9 6a022cbb61d5ba0f03f98ff2d36319dfea1034ae 0 (*) {'user': 'test'} (glob)
+  b2e32ffb533cbe1d5759638c0cd4e8abc43b2738 0 {07f4944404050f47db2e5c5071e0e84e7a27bba9} (*) {'user': 'test'} (glob)
+  $ hg phase 2
+  2: draft
+  $ glog
+  @  4@foo(draft) reseta
+  |
+  o  3@foo(draft) changea
+  |
+  o  2@foo(draft) adda
+  
+Specify precise commit date with -d
+  $ hg amend -d '2001-02-03 04:05:06 +0700'
+  $ hg parents --template '{rev}  {date|date}\n'
+  5  Sat Feb 03 04:05:06 2001 +0700
+
+Specify "now" as commit date with -D
+  $ before=`date +%s`
+  $ hg amend -D
+  $ commit=`hg parents --template '{date|hgdate} rev{rev}\n'`
+  $ after=`date +%s`
+  $ (echo $before ; echo $commit; echo $after) | sort -k1 -n -s
+  \d+ (re)
+  \d+ 0 rev6 (re)
+  \d+ (re)
+
+Specify current user as committer with -U
+  $ HGUSER=newbie hg amend -U
+  $ hg parents --template '{rev}  {author}\n'
+  7  newbie
+
+Check that --logfile works
+  $ echo "logfile message" > logfile.txt
+  $ hg amend -l logfile.txt
+  $ hg log -r . -T "{desc}\n"
+  logfile message
+
+# Make sure we don't get reparented to -1 with no username (issue4211)
+  $ HGUSER=
+  $ hg amend -e --config ui.username= -m "empty user"
+  abort: no username supplied
+  (use 'hg config --edit' to set your username)
+  [255]
+  $ hg sum
+  parent: 8:* tip (glob)
+   logfile message
+  branch: foo
+  commit: 1 unknown (clean)
+  update: (current)
+  phases: 3 draft
+
+Check the help
+  $ hg amend -h
+  hg amend [OPTION]... [FILE]...
+  
+  aliases: refresh
+  
+  combine a changeset with updates and replace it with a new one
+  
+      Commits a new changeset incorporating both the changes to the given files
+      and all the changes from the current parent changeset into the repository.
+  
+      See 'hg commit' for details about committing changes.
+  
+      If you don't specify -m, the parent's message will be reused.
+  
+      Behind the scenes, Mercurial first commits the update as a regular child
+      of the current parent. Then it creates a new commit on the parent's
+      parents with the updated contents. Then it changes the working copy parent
+      to this new combined changeset. Finally, the old changeset and its update
+      are hidden from 'hg log' (unless you use --hidden with log).
+  
+      Returns 0 on success, 1 if nothing changed.
+  
+  options ([+] can be repeated):
+  
+   -A --addremove           mark new/missing files as added/removed before
+                            committing
+   -e --edit                invoke editor on commit messages
+      --close-branch        mark a branch as closed, hiding it from the branch
+                            list
+   -s --secret              use the secret phase for committing
+   -I --include PATTERN [+] include names matching the given patterns
+   -X --exclude PATTERN [+] exclude names matching the given patterns
+   -m --message TEXT        use text as commit message
+   -l --logfile FILE        read commit message from file
+   -d --date DATE           record the specified date as commit date
+   -u --user USER           record the specified user as committer
+   -D --current-date        record the current date as commit date
+   -U --current-user        record the current user as committer
+   -i --interactive         use interactive mode
+  
+  (some details hidden, use --verbose to show complete help)
--- a/tests/test-check-pyflakes.t	Thu Feb 23 15:19:31 2017 +0100
+++ b/tests/test-check-pyflakes.t	Thu Mar 02 18:07:46 2017 +0100
@@ -7,9 +7,9 @@
 run pyflakes on all tracked files ending in .py or without a file ending
 (skipping binary file random-seed)
 
-  $ hg locate 'set:**.py or grep("^!#.*python")' 2>/dev/null \
+  $ hg locate 'set:hgext3rd/topic/**.py or grep("^!#.*python")' 2>/dev/null \
   > | xargs pyflakes 2>/dev/null  
 
 run flake8 if it exists; if it doesn't, then just skip
 
-  $ type flake8 >/dev/null 2>/dev/null && hg files -0 'glob:**.py' | xargs -0 flake8 || true
+  $ type flake8 >/dev/null 2>/dev/null && hg files -0 'glob:hgext3rd/topic/**.py' | xargs -0 flake8 || true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-corrupt.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,122 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [alias]
+  > qlog = log --template='{rev} - {node|short} {desc} ({phase})\n'
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" >> "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ hg init local
+  $ hg init other
+  $ cd local
+  $ touch 1 2 3 4 5 6 7 8 9 0
+  $ hg add 1 2 3 4 5 6 7 8 9 0
+  $ mkcommit A
+  $ mkcommit B
+  $ mkcommit C
+  $ hg glog
+  @  changeset:   2:829b19580856
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add C
+  |
+  o  changeset:   1:97b8f02ab29e
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add B
+  |
+  o  changeset:   0:5d8dabd3961b
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add A
+  
+  $ hg push ../other
+  pushing to ../other
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 13 changes to 13 files
+
+
+  $ hg -R ../other verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  13 files, 3 changesets, 13 total revisions
+  $ mkcommit D
+  $ mkcommit E
+  $ hg up -q .^^
+  $ hg revert -r tip -a -q
+  $ hg ci -m 'coin' -q
+  $ hg glog
+  @  changeset:   5:8313a6afebbb
+  |  tag:         tip
+  |  parent:      2:829b19580856
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     coin
+  |
+  | o  changeset:   4:076ec8ade1ac
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     add E
+  | |
+  | o  changeset:   3:824d9bb109f6
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     add D
+  |
+  o  changeset:   2:829b19580856
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add C
+  |
+  o  changeset:   1:97b8f02ab29e
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add B
+  |
+  o  changeset:   0:5d8dabd3961b
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add A
+  
+
+  $ hg prune --fold -n -1 -- -2 -3
+  2 changesets pruned
+  $ hg push ../other
+  pushing to ../other
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 2 changes to 2 files
+  2 new obsolescence markers
+  $ hg -R ../other verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  15 files, 4 changesets, 15 total revisions
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-divergent.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,159 @@
+Tests the resolution of divergence
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline} [{troubles}]\n
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ mkcommits() {
+  >   for i in $@; do mkcommit $i ; done
+  > }
+
+Basic test of divergence: two divergent changesets with the same parents
+With --all --any we dedupe the divergent and solve the divergence once
+
+  $ hg init test1
+  $ cd test1
+  $ mkcommits _a _b
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bdivergent1
+  created new head
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bdivergent2
+  created new head
+  $ hg prune -s "desc(bdivergent1)" "desc(_b)"
+  1 changesets pruned
+  $ hg prune -s "desc(bdivergent2)" "desc(_b)" --hidden
+  1 changesets pruned
+  2 new divergent changesets
+  $ hg log -G
+  @  3:e708fd28d5cf@default(draft) add bdivergent2 [divergent]
+  |
+  | o  2:c2f698071cba@default(draft) add bdivergent1 [divergent]
+  |/
+  o  0:135f39f4bd78@default(draft) add _a []
+  
+  $ hg evolve --all --any --divergent
+  merge:[2] add bdivergent1
+  with: [3] add bdivergent2
+  base: [1] add _b
+  updating to "local" conflict
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at c26f1d3baed2
+  $ hg log -G
+  @  5:c26f1d3baed2@default(draft) add bdivergent1 []
+  |
+  o  0:135f39f4bd78@default(draft) add _a []
+  
+Test divergence resolution when it yields to an empty commit (issue4950)
+cdivergent2 contains the same content than cdivergent1 and they are divergent
+versions of the revision _c
+
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit _c
+  created new head
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit cdivergent1
+  created new head
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "cdivergent1" > cdivergent1
+  $ hg add cdivergent1
+  $ hg ci -m "cdivergent2"
+  created new head
+  $ hg prune -s "desc(cdivergent1)" "desc(_c)"
+  1 changesets pruned
+  $ hg prune -s "desc(cdivergent2)" "desc(_c)" --hidden
+  1 changesets pruned
+  2 new divergent changesets
+  $ hg log -G
+  @  8:0a768ef678d9@default(draft) cdivergent2 [divergent]
+  |
+  | o  7:26c7705fee96@default(draft) add cdivergent1 [divergent]
+  |/
+  | o  5:c26f1d3baed2@default(draft) add bdivergent1 []
+  |/
+  o  0:135f39f4bd78@default(draft) add _a []
+  
+  $ hg evolve --all --any --divergent
+  merge:[7] add cdivergent1
+  with: [8] cdivergent2
+  base: [6] add _c
+  updating to "local" conflict
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at 6602ff5a79dc
+
+Test None docstring issue of evolve divergent, which caused hg crush
+
+  $ hg init test2
+  $ cd test2
+  $ mkcommits _a _b
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bdivergent1
+  created new head
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bdivergent2
+  created new head
+  $ hg prune -s "desc(bdivergent1)" "desc(_b)"
+  1 changesets pruned
+  $ hg prune -s "desc(bdivergent2)" "desc(_b)" --hidden
+  1 changesets pruned
+  2 new divergent changesets
+  $ hg log -G
+  @  3:e708fd28d5cf@default(draft) add bdivergent2 [divergent]
+  |
+  | o  2:c2f698071cba@default(draft) add bdivergent1 [divergent]
+  |/
+  o  0:135f39f4bd78@default(draft) add _a []
+  
+  $ cat >$TESTTMP/test_extension.py  << EOF
+  > from mercurial import merge
+  > origupdate = merge.update
+  > def newupdate(*args, **kwargs):
+  >   return origupdate(*args, **kwargs)
+  > merge.update = newupdate
+  > EOF
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > testextension=$TESTTMP/test_extension.py
+  > EOF
+  $ hg evolve --all
+  nothing to evolve on current working copy parent
+  (do you want to use --divergent)
+  [2]
+  $ hg evolve --divergent
+  merge:[3] add bdivergent2
+  with: [2] add bdivergent1
+  base: [1] add _b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at aa26817f6fbe
+
+
+  $ cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-drop.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,266 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "drophack=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/hack/drophack.py" >> $HGRCPATH
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+  $ summary() {
+  > echo ============ graph ==============
+  > hg log -G
+  > echo ============ hidden =============
+  > hg log --hidden -G
+  > echo ============ obsmark ============
+  > hg debugobsolete
+  > }
+
+
+  $ hg init repo
+  $ cd repo
+  $ mkcommit base
+
+drop a single changeset without any rewrite
+================================================
+
+
+  $ mkcommit simple-single
+  $ summary
+  ============ graph ==============
+  @  changeset:   1:d4e7845543ff
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add simple-single
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ hidden =============
+  @  changeset:   1:d4e7845543ff
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add simple-single
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ obsmark ============
+  $ hg drop .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at b4952fcf48cf
+  search obsmarker: wall * comb * user * sys * (glob)
+  0 obsmarkers found
+  search nodes: wall * comb * user * sys * (glob)
+  1 nodes found
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d4e7845543ff-8ad8efe0-drophack.hg (glob)
+  strip nodes: wall * comb * user * sys * (glob)
+  $ summary
+  ============ graph ==============
+  @  changeset:   0:b4952fcf48cf
+     tag:         tip
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ hidden =============
+  @  changeset:   0:b4952fcf48cf
+     tag:         tip
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ obsmark ============
+
+Try to drop a changeset with children
+================================================
+
+  $ mkcommit parent
+  $ mkcommit child
+  $ summary
+  ============ graph ==============
+  @  changeset:   2:34b6c051bf1f
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add child
+  |
+  o  changeset:   1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ hidden =============
+  @  changeset:   2:34b6c051bf1f
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add child
+  |
+  o  changeset:   1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ obsmark ============
+  $ hg drop 1
+  cannot drop revision with children (no-eol)
+  [1]
+  $ summary
+  ============ graph ==============
+  @  changeset:   2:34b6c051bf1f
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add child
+  |
+  o  changeset:   1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ hidden =============
+  @  changeset:   2:34b6c051bf1f
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add child
+  |
+  o  changeset:   1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ obsmark ============
+
+Try to drop a public changeset
+================================================
+
+  $ hg phase --public 2
+  $ hg drop 2
+  cannot drop public revision (no-eol)
+  [1]
+
+
+Try to drop a changeset with rewrite
+================================================
+
+  $ hg phase --force --draft 2
+  $ echo babar >> child
+  $ hg commit --amend
+  $ summary
+  ============ graph ==============
+  @  changeset:   4:a2c06c884bfe
+  |  tag:         tip
+  |  parent:      1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add child
+  |
+  o  changeset:   1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ hidden =============
+  @  changeset:   4:a2c06c884bfe
+  |  tag:         tip
+  |  parent:      1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add child
+  |
+  | x  changeset:   3:87ea30a976fd
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     temporary amend commit for 34b6c051bf1f
+  | |
+  | x  changeset:   2:34b6c051bf1f
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     add child
+  |
+  o  changeset:   1:19509a42b0d0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ obsmark ============
+  34b6c051bf1f78db6aef400776de5cb964470207 a2c06c884bfe53d3840026248bd8a7eafa152df8 0 (*) {'user': 'test'} (glob)
+  87ea30a976fdf235bf096f04899cb02a903873e2 0 {34b6c051bf1f78db6aef400776de5cb964470207} (*) {'user': 'test'} (glob)
+  $ hg drop .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at 19509a42b0d0
+  search obsmarker: wall * comb * user * sys * (glob)
+  1 obsmarkers found
+  search nodes: wall * comb * user * sys * (glob)
+  2 nodes found
+  strip obsmarker: wall * comb * user * sys * (glob)
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-drophack.hg (glob)
+  strip nodes: wall * comb * user * sys * (glob)
+  $ summary
+  ============ graph ==============
+  @  changeset:   1:19509a42b0d0
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ hidden =============
+  @  changeset:   1:19509a42b0d0
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add parent
+  |
+  o  changeset:   0:b4952fcf48cf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add base
+  
+  ============ obsmark ============
+  87ea30a976fdf235bf096f04899cb02a903873e2 0 {34b6c051bf1f78db6aef400776de5cb964470207} (*) {'user': 'test'} (glob)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-bumped.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,125 @@
+  $ hg init public
+  $ cd public
+  $ echo a > a
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+  $ hg commit -A -m init
+  adding a
+  $ cd ..
+
+  $ evolvepath=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/
+  $ hg clone -U public private
+  $ cd private
+  $ cat >> .hg/hgrc <<EOF
+  > [extensions]
+  > evolve = $evolvepath
+  > [ui]
+  > logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
+  > [phases]
+  > publish = false
+  > EOF
+  $ cd ..
+
+  $ cp -a private alice
+  $ cp -a private bob
+
+  $ cd alice
+  $ hg update
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a >> a
+  $ hg commit -u alice -m 'modify a'
+  $ hg push ../private
+  pushing to ../private
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ hg log -r 'draft()'
+  1:4d1169d82e47@default(draft) modify a
+
+  $ cd ../bob
+  $ hg pull ../private
+  pulling from ../private
+  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 -r 'draft()'
+  1:4d1169d82e47@default(draft) modify a
+  $ hg push ../public
+  pushing to ../public
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ hg log -r 'draft()'
+
+  $ cd ../alice
+  $ hg amend -m 'tweak a'
+  $ hg pull ../public
+  pulling from ../public
+  searching for changes
+  no changes found
+  1 new bumped changesets
+
+  $ hg evolve -a -A --bumped
+  recreate:[2] tweak a
+  atop:[1] modify a
+  computing new diff
+  committed as 4d1169d82e47
+  working directory is now at 4d1169d82e47
+
+Bumped Merge changeset:
+-----------------------
+
+We currently cannot automatically solve bumped changeset that is the
+product of a merge, we add a test for it.
+
+  $ mkcommit _a
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit _b
+  created new head
+  $ mkcommit _c
+  $ hg log -G
+  @  5:eeaf70969381@default(draft) add _c
+  |
+  o  4:6612fc0ddeb6@default(draft) add _b
+  |
+  | o  3:154ad198ff4a@default(draft) add _a
+  |/
+  o  1:4d1169d82e47@default(public) modify a
+  |
+  o  0:d3873e73d99e@default(public) init
+  
+  $ hg merge 3
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "merge"
+  $ hg commit --amend -m "New message"
+  $ hg phase --public 551127da2a8a --hidden
+  1 new bumped changesets
+  $ hg log -G
+  @    7:b28e84916d8c@default(draft) New message
+  |\
+  +---o  6:551127da2a8a@default(public) merge
+  | |/
+  | o  5:eeaf70969381@default(public) add _c
+  | |
+  | o  4:6612fc0ddeb6@default(public) add _b
+  | |
+  o |  3:154ad198ff4a@default(public) add _a
+  |/
+  o  1:4d1169d82e47@default(public) modify a
+  |
+  o  0:d3873e73d99e@default(public) init
+  
+  $ hg evolve --all --bumped
+  skipping b28e84916d8c : we do not handle merge yet
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-list.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,80 @@
+Set up some configs
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > rebase=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+Test the instability listing
+  $ hg init r2
+  $ cd r2
+  $ echo a > a && hg ci -Am a
+  adding a
+  $ echo b > b && hg ci -Am b
+  adding b
+  $ echo c > c && hg ci -Am c
+  adding c
+  $ hg up 0
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo a >> a && hg ci --amend -m a
+  2 new unstable changesets
+  $ hg evolve --list
+  d2ae7f538514: b
+    unstable: cb9a9f314b8b (obsolete parent)
+  
+  177f92b77385: c
+    unstable: d2ae7f538514 (unstable parent)
+  
+  $ cd ..
+
+Test the bumpedness listing
+  $ hg init r3
+  $ cd r3
+  $ echo a > a && hg ci -Am a
+  adding a
+  $ echo b > b && hg ci --amend -m ab
+  $ hg phase --public --rev 0 --hidden
+  1 new bumped changesets
+  $ hg evolve --list
+  88cc282e27fc: ab
+    bumped: cb9a9f314b8b (immutable precursor)
+  
+  $ cd ..
+
+Test the divergence listing
+  $ hg init r1
+  $ cd r1
+  $ echo a > a && hg ci -Am a
+  adding a
+  $ hg up 0
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo b > b && hg ci -Am b
+  adding b
+  $ hg up 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo c > c && hg ci -Am c
+  adding c
+  created new head
+  $ hg up 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo d > d && hg ci -Am d
+  adding d
+  created new head
+  $ hg rebase -s 1 -d 2
+  rebasing 1:d2ae7f538514 "b"
+  $ hg rebase -s 1 -d 3 --hidden --config experimental.allowdivergence=True
+  rebasing 1:d2ae7f538514 "b"
+  2 new divergent changesets
+  $ hg evolve --list
+  c882616e9d84: b
+    divergent: a922b3733e98 (draft) (precursor d2ae7f538514)
+  
+  a922b3733e98: b
+    divergent: c882616e9d84 (draft) (precursor d2ae7f538514)
+  
+  $ hg phase -p a922b3733e98
+  $ hg evolve --list
+  c882616e9d84: b
+    divergent: a922b3733e98 (public) (precursor d2ae7f538514)
+  
+  $ cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-order.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,266 @@
+evolve --rev reordering
+-----------------------
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ mkstack() {
+  >    # Creates a stack of commit based on $1 with messages from $2, $3 ..
+  >    hg update "$1" -C
+  >    shift
+  >    mkcommits $*
+  > }
+
+  $ mkcommits() {
+  >   for i in $@; do mkcommit $i ; done
+  > }
+
+Initial setup
+  $ hg init testrevorder
+  $ cd testrevorder
+  $ mkcommits p _a _b _c
+  $ hg phase --public 0
+  $ hg up 'desc(_a)'
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo "aaa" > _a
+  $ hg amend
+  2 new unstable changesets
+  $ hg log -G
+  @  5:12d519679175@default(draft) add _a
+  |
+  | o  3:4d156641b718@default(draft) add _c
+  | |
+  | o  2:4d7242ebb004@default(draft) add _b
+  | |
+  | x  1:2d73fcd7f07d@default(draft) add _a
+  |/
+  o  0:f92638be10c7@default(public) add p
+  
+
+evolve --rev reorders the rev to solve instability, trivial case 2 revs wrong order
+  $ hg evolve --rev 'desc(_c) + desc(_b)'
+  move:[2] add _b
+  atop:[5] add _a
+  move:[3] add _c
+  atop:[6] add _b
+  working directory is now at 52b8f9b04f83
+
+evolve --rev reorders the rev to solve instability. Harder case, obsolescence
+accross three stacks in growing rev numbers.
+  $ hg up "desc(_c)"
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ mkcommit _d
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg amend -m "aprime"
+  3 new unstable changesets
+  $ hg evolve --rev "desc(_b)"
+  move:[6] add _b
+  atop:[9] aprime
+  working directory is now at 476c9c052aae
+  $ hg up "desc(_b) - obsolete()"
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg amend -m "bprime"
+  $ hg up "desc(aprime)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg amend -m "asecond"
+  1 new unstable changesets
+  $ hg log -G
+  @  12:9a584314f3f3@default(draft) asecond
+  |
+  | o  11:a59c79776f7c@default(draft) bprime
+  | |
+  | x  9:81a687b96d4d@default(draft) aprime
+  |/
+  | o  8:464731bc0ed0@default(draft) add _d
+  | |
+  | o  7:52b8f9b04f83@default(draft) add _c
+  | |
+  | x  6:59476c3836ef@default(draft) add _b
+  | |
+  | x  5:12d519679175@default(draft) add _a
+  |/
+  o  0:f92638be10c7@default(public) add p
+  
+  $ hg evolve --rev "unstable()"
+  move:[11] bprime
+  atop:[12] asecond
+  move:[7] add _c
+  atop:[13] bprime
+  move:[8] add _d
+  atop:[14] add _c
+  working directory is now at 739f18ac1d03
+  $ hg log -G
+  @  15:739f18ac1d03@default(draft) add _d
+  |
+  o  14:e5960578d158@default(draft) add _c
+  |
+  o  13:4ad33fa88946@default(draft) bprime
+  |
+  o  12:9a584314f3f3@default(draft) asecond
+  |
+  o  0:f92638be10c7@default(public) add p
+  
+
+Evolve --rev more complex case: two sets of stacks one with prune an no successor, the other one
+partially solvable
+ 
+First set of stack:
+  $ mkstack "desc(_d)" c1_ c2_ c3_ c4_ >/dev/null
+  $ mkstack "desc(_d)" c1prime c2prime >/dev/null
+  $ mkstack "desc(_d)" c1second >/dev/null
+  $ hg prune "desc(c1_)" -s "desc(c1prime)"
+  1 changesets pruned
+  3 new unstable changesets
+  $ hg prune "desc(c2_)" -s "desc(c2prime)"
+  1 changesets pruned
+  $ hg prune "desc(c1prime)" -s "desc(c1second)"
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg log -G -r "desc(_d)::"
+  @  22:dcf786e878fd@default(draft) add c1second
+  |
+  | o  21:507d52d715f6@default(draft) add c2prime
+  | |
+  | x  20:c995cb124ddc@default(draft) add c1prime
+  |/
+  | o  19:d096a2437fd0@default(draft) add c4_
+  | |
+  | o  18:cde95c6cba7a@default(draft) add c3_
+  | |
+  | x  17:e0d9f7a099fe@default(draft) add c2_
+  | |
+  | x  16:43b7c338b1f8@default(draft) add c1_
+  |/
+  o  15:739f18ac1d03@default(draft) add _d
+  |
+  ~
+
+Second set of stack with no successor for b2_:
+  $ mkstack "desc(_d)" b1_ b2_ b3_ b4_ >/dev/null
+  $ mkstack "desc(_d)" b1prime b3prime >/dev/null
+  $ hg prune "desc(b1_)" -s "desc(b1prime)"
+  1 changesets pruned
+  3 new unstable changesets
+  $ hg prune "desc(b3_)" -s "desc(b3prime)"
+  1 changesets pruned
+  $ hg prune "desc(b2_)"
+  1 changesets pruned
+
+  $ hg log -G -r "desc(_d)::"
+  @  28:b253ff5b65d1@default(draft) add b3prime
+  |
+  o  27:4acf61f11dfb@default(draft) add b1prime
+  |
+  | o  26:594e1fbbd61f@default(draft) add b4_
+  | |
+  | x  25:be27500cfc76@default(draft) add b3_
+  | |
+  | x  24:b54f77dc5831@default(draft) add b2_
+  | |
+  | x  23:0e1eba27e9aa@default(draft) add b1_
+  |/
+  | o  22:dcf786e878fd@default(draft) add c1second
+  |/
+  | o  21:507d52d715f6@default(draft) add c2prime
+  | |
+  | x  20:c995cb124ddc@default(draft) add c1prime
+  |/
+  | o  19:d096a2437fd0@default(draft) add c4_
+  | |
+  | o  18:cde95c6cba7a@default(draft) add c3_
+  | |
+  | x  17:e0d9f7a099fe@default(draft) add c2_
+  | |
+  | x  16:43b7c338b1f8@default(draft) add c1_
+  |/
+  o  15:739f18ac1d03@default(draft) add _d
+  |
+  ~
+
+Solve the full second stack and only part of the first one
+  $ echo "(desc(_d)::) - desc(c3_)"
+  (desc(_d)::) - desc(c3_)
+  $ hg evolve --rev "(desc(_d)::) - desc(c3_)"
+  cannot solve instability of d096a2437fd0, skipping
+  move:[21] add c2prime
+  atop:[22] add c1second
+  move:[26] add b4_
+  atop:[28] add b3prime
+  working directory is now at ea93190a9cd1
+
+Cleanup
+  $ hg evolve --rev "(desc(_d)::)"
+  move:[18] add c3_
+  atop:[29] add c2prime
+  move:[19] add c4_
+  atop:[31] add c3_
+  working directory is now at 35e7b797ace5
+  $ hg log -G -r "desc(_d)::"
+  @  32:35e7b797ace5@default(draft) add c4_
+  |
+  o  31:0b9488394e89@default(draft) add c3_
+  |
+  | o  30:ea93190a9cd1@default(draft) add b4_
+  | |
+  o |  29:881b9c092e53@default(draft) add c2prime
+  | |
+  | o  28:b253ff5b65d1@default(draft) add b3prime
+  | |
+  | o  27:4acf61f11dfb@default(draft) add b1prime
+  | |
+  o |  22:dcf786e878fd@default(draft) add c1second
+  |/
+  o  15:739f18ac1d03@default(draft) add _d
+  |
+  ~
+
+Test multiple revision with some un-evolvable because parent is splitted
+------------------------------------------------------------------------
+
+  $ hg up 'desc(c2prime)'
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit c3part1
+  created new head
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [29] add c2prime
+  $ mkcommit c3part2
+  created new head
+  $ hg prune -s 'desc(c3part1)' 'desc(c3_)'
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg prune -s 'desc(c3part2)' 'desc(c3_)'
+  1 changesets pruned
+  2 new divergent changesets
+  $ hg up 'desc(b3prime)'
+  2 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg amend -m 'b3second'
+  1 new unstable changesets
+  $ hg evolve --rev 'unstable()'
+  move:[30] add b4_
+  atop:[35] b3second
+  skipping 0b9488394e89: divergent rewriting. can't choose destination
+  working directory is now at 31809a198477
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-split.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,63 @@
+Check that evolve shows error while handling split commits
+--------------------------------------
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ hg init split
+  $ cd split
+  $ mkcommit aa
+
+Create a split commit
+  $ printf "oo" > oo;
+  $ printf "pp" > pp;
+  $ hg add oo pp
+  $ hg commit -m "oo+pp"
+  $ mkcommit uu
+  $ hg up 0
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ printf "oo" > oo;
+  $ hg add oo
+  $ hg commit -m "_oo"
+  created new head
+  $ printf "pp" > pp;
+  $ hg add pp
+  $ hg commit -m "_pp"
+  $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')" --split
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg log -G
+  @  4:d0dcf24cddd3@default(draft) _pp
+  |
+  o  3:a7fdfda64c08@default(draft) _oo
+  |
+  | o  2:f52200b086ca@default(draft) add uu
+  | |
+  | x  1:d55647aaa0c6@default(draft) oo+pp
+  |/
+  o  0:58663bb03074@default(draft) add aa
+  
+  $ hg evolve --rev "0::"
+  move:[2] add uu
+  atop:[4] _pp
+  working directory is now at 6f5bbe2e3df3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-topic.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,217 @@
+
+Check we can find the topic extensions
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > [phases]
+  > publish = False
+  > [ui]
+  > logtemplate = {rev} - \{{get(namespaces, "topics")}} {node|short} {desc} ({phase})\n
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [extensions]
+  > rebase = 
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ echo "topic=$(echo $(dirname $TESTDIR))/hgext3rd/topic/" >> $HGRCPATH
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+Create a simple setup
+
+  $ hg init repoa
+  $ cd repoa
+  $ mkcommit aaa
+  $ mkcommit bbb
+  $ hg topic foo
+  $ mkcommit ccc
+  $ mkcommit ddd
+  $ mkcommit eee
+  $ mkcommit fff
+  $ hg topic bar
+  $ mkcommit ggg
+  $ mkcommit hhh
+  $ mkcommit iii
+  $ mkcommit jjj
+
+  $ hg log -G
+  @  9 - {bar} 1d964213b023 add jjj (draft)
+  |
+  o  8 - {bar} fcab990f3261 add iii (draft)
+  |
+  o  7 - {bar} b0c2554835ac add hhh (draft)
+  |
+  o  6 - {bar} c748293f1c1a add ggg (draft)
+  |
+  o  5 - {foo} 6a6b7365c751 add fff (draft)
+  |
+  o  4 - {foo} 3969ab847d9c add eee (draft)
+  |
+  o  3 - {foo} 4e3a154f38c7 add ddd (draft)
+  |
+  o  2 - {foo} cced9bac76e3 add ccc (draft)
+  |
+  o  1 - {} a4dbed0837ea add bbb (draft)
+  |
+  o  0 - {} 199cc73e9a0b add aaa (draft)
+  
+
+Test that evolve --all evolve the current topic
+-----------------------------------------------
+
+make a mess
+
+  $ hg up foo
+  switching to topic foo
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ hg topic -l 
+  ### topic: foo (?)
+  ### branch: default (?)
+  t4@ add fff (current)
+  t3: add eee
+  t2: add ddd
+  t1: add ccc
+    ^ add bbb
+  $ hg up 'desc(ddd)'
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo ddd >> ddd
+  $ hg amend
+  6 new unstable changesets
+  $ hg up 'desc(fff)'
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo fff >> fff
+  $ hg amend
+
+  $ hg log -G
+  @  13 - {foo} e104f49bab28 add fff (draft)
+  |
+  | o  11 - {foo} d9cacd156ffc add ddd (draft)
+  | |
+  | | o  9 - {bar} 1d964213b023 add jjj (draft)
+  | | |
+  | | o  8 - {bar} fcab990f3261 add iii (draft)
+  | | |
+  | | o  7 - {bar} b0c2554835ac add hhh (draft)
+  | | |
+  | | o  6 - {bar} c748293f1c1a add ggg (draft)
+  | | |
+  +---x  5 - {foo} 6a6b7365c751 add fff (draft)
+  | |
+  o |  4 - {foo} 3969ab847d9c add eee (draft)
+  | |
+  x |  3 - {foo} 4e3a154f38c7 add ddd (draft)
+  |/
+  o  2 - {foo} cced9bac76e3 add ccc (draft)
+  |
+  o  1 - {} a4dbed0837ea add bbb (draft)
+  |
+  o  0 - {} 199cc73e9a0b add aaa (draft)
+  
+
+Run evolve --all
+
+  $ hg evolve --all
+  move:[4] add eee
+  atop:[11] add ddd
+  move:[13] add fff
+  atop:[14] add eee
+  working directory is now at 070c5573d8f9
+  $ hg log -G
+  @  15 - {foo} 070c5573d8f9 add fff (draft)
+  |
+  o  14 - {foo} 42b49017ff90 add eee (draft)
+  |
+  o  11 - {foo} d9cacd156ffc add ddd (draft)
+  |
+  | o  9 - {bar} 1d964213b023 add jjj (draft)
+  | |
+  | o  8 - {bar} fcab990f3261 add iii (draft)
+  | |
+  | o  7 - {bar} b0c2554835ac add hhh (draft)
+  | |
+  | o  6 - {bar} c748293f1c1a add ggg (draft)
+  | |
+  | x  5 - {foo} 6a6b7365c751 add fff (draft)
+  | |
+  | x  4 - {foo} 3969ab847d9c add eee (draft)
+  | |
+  | x  3 - {foo} 4e3a154f38c7 add ddd (draft)
+  |/
+  o  2 - {foo} cced9bac76e3 add ccc (draft)
+  |
+  o  1 - {} a4dbed0837ea add bbb (draft)
+  |
+  o  0 - {} 199cc73e9a0b add aaa (draft)
+  
+
+Test that evolve does not loose topic information
+-------------------------------------------------
+
+  $ hg evolve --rev 'topic(bar)'
+  move:[6] add ggg
+  atop:[15] add fff
+  move:[7] add hhh
+  atop:[16] add ggg
+  move:[8] add iii
+  atop:[17] add hhh
+  move:[9] add jjj
+  atop:[18] add iii
+  working directory is now at 9bf430c106b7
+  $ hg log -G
+  @  19 - {bar} 9bf430c106b7 add jjj (draft)
+  |
+  o  18 - {bar} d2dc89c57700 add iii (draft)
+  |
+  o  17 - {bar} 20bc4d02aa62 add hhh (draft)
+  |
+  o  16 - {bar} 16d6f664b17c add ggg (draft)
+  |
+  o  15 - {foo} 070c5573d8f9 add fff (draft)
+  |
+  o  14 - {foo} 42b49017ff90 add eee (draft)
+  |
+  o  11 - {foo} d9cacd156ffc add ddd (draft)
+  |
+  o  2 - {foo} cced9bac76e3 add ccc (draft)
+  |
+  o  1 - {} a4dbed0837ea add bbb (draft)
+  |
+  o  0 - {} 199cc73e9a0b add aaa (draft)
+  
+
+Tests next and prev behavior
+============================
+
+Basic move are restricted to the current topic
+
+  $ hg up foo
+  switching to topic foo
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [14] add eee
+  $ hg next
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [15] add fff
+  $ hg next
+  no children on topic "foo"
+  do you want --no-topic
+  [1]
+  $ hg next --no-topic
+  switching to topic bar
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [16] add ggg
+  $ hg prev
+  no parent in topic "bar"
+  (do you want --no-topic)
+  $ hg prev --no-topic
+  switching to topic foo
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [15] add fff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,1595 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > metaedit=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [alias]
+  > qlog = log --template='{rev} - {node|short} {desc} ({phase})\n'
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ mkstack() {
+  >    # Creates a stack of commit based on $1 with messages from $2, $3 ..
+  >    hg update $1 -C
+  >    shift
+  >    mkcommits $*
+  > }
+
+  $ glog() {
+  >   hg glog --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
+  > }
+
+  $ shaof() {
+  >   hg log -T {node} -r "first(desc($1))"
+  > }
+
+  $ mkcommits() {
+  >   for i in $@; do mkcommit $i ; done
+  > }
+
+Test the evolution test topic is installed
+
+  $ hg help evolution
+  Safely Rewriting History
+  """"""""""""""""""""""""
+  
+      Obsolescence markers make it possible to mark changesets that have been
+      deleted or superset in a new version of the changeset.
+  
+      Unlike the previous way of handling such changes, by stripping the old
+      changesets from the repository, obsolescence markers can be propagated
+      between repositories. This allows for a safe and simple way of exchanging
+      mutable history and altering it after the fact. Changeset phases are
+      respected, such that only draft and secret changesets can be altered (see
+      'hg help phases' for details).
+  
+      Obsolescence is tracked using "obsolete markers", a piece of metadata
+      tracking which changesets have been made obsolete, potential successors
+      for a given changeset, the moment the changeset was marked as obsolete,
+      and the user who performed the rewriting operation. The markers are stored
+      separately from standard changeset data can be exchanged without any of
+      the precursor changesets, preventing unnecessary exchange of obsolescence
+      data.
+  
+      The complete set of obsolescence markers describes a history of changeset
+      modifications that is orthogonal to the repository history of file
+      modifications. This changeset history allows for detection and automatic
+      resolution of edge cases arising from multiple users rewriting the same
+      part of history concurrently.
+  
+      Current feature status
+      ======================
+  
+      This feature is still in development.  If you see this help, you have
+      enabled an extension that turned this feature on.
+  
+      Obsolescence markers will be exchanged between repositories that
+      explicitly assert support for the obsolescence feature (this can currently
+      only be done via an extension).
+
+various init
+
+  $ hg init local
+  $ cd local
+  $ mkcommit a
+  $ mkcommit b
+  $ cat >> .hg/hgrc << EOF
+  > [phases]
+  > publish = True
+  > EOF
+  $ hg pull -q . # make 1 public
+  $ rm .hg/hgrc
+  $ mkcommit c
+  $ mkcommit d
+  $ hg up 1
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit e -q
+  created new head
+  $ mkcommit f
+  $ hg qlog
+  5 - e44648563c73 add f (draft)
+  4 - fbb94e3a0ecf add e (draft)
+  3 - 47d2a3944de8 add d (draft)
+  2 - 4538525df7e2 add c (draft)
+  1 - 7c3bad9141dc add b (public)
+  0 - 1f0dee641bb7 add a (public)
+
+test kill and immutable changeset
+
+  $ hg log -r 1 --template '{rev} {phase} {obsolete}\n'
+  1 public 
+  $ hg prune 1
+  abort: cannot prune immutable changeset: 7c3bad9141dc
+  (see 'hg help phases' for details)
+  [255]
+  $ hg log -r 1 --template '{rev} {phase} {obsolete}\n'
+  1 public 
+
+test simple kill
+
+  $ hg id -n
+  5
+  $ hg prune .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at fbb94e3a0ecf
+  1 changesets pruned
+  $ hg qlog
+  4 - fbb94e3a0ecf add e (draft)
+  3 - 47d2a3944de8 add d (draft)
+  2 - 4538525df7e2 add c (draft)
+  1 - 7c3bad9141dc add b (public)
+  0 - 1f0dee641bb7 add a (public)
+
+test multiple kill
+
+  $ hg prune 4 -r 3
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at 7c3bad9141dc
+  2 changesets pruned
+  $ hg qlog
+  2 - 4538525df7e2 add c (draft)
+  1 - 7c3bad9141dc add b (public)
+  0 - 1f0dee641bb7 add a (public)
+
+test kill with dirty changes
+
+  $ hg up 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 4 > g
+  $ hg add g
+  $ hg prune .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at 7c3bad9141dc
+  1 changesets pruned
+  $ hg st
+  A g
+
+Smoketest debugobsrelsethashtree:
+
+  $ hg debugobsrelsethashtree
+  1f0dee641bb7258c56bd60e93edfa2405381c41e 0000000000000000000000000000000000000000
+  7c3bad9141dcb46ff89abf5f61856facd56e476c * (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d * (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 * (glob)
+  fbb94e3a0ecf6d20c2cc31152ef162ce45af982f * (glob)
+  e44648563c73f75950076031c6fdf06629de95f1 * (glob)
+
+  $ cd ..
+
+##########################
+importing Parren test
+##########################
+
+  $ cat << EOF >> $HGRCPATH
+  > [ui]
+  > logtemplate = "{rev}\t{bookmarks}: {desc|firstline} - {author|user}\n"
+  > EOF
+
+Creating And Updating Changeset
+===============================
+
+Setup the Base Repo
+-------------------
+
+We start with a plain base repo::
+
+  $ hg init main; cd main
+  $ cat >main-file-1 <<-EOF
+  > One
+  > 
+  > Two
+  > 
+  > Three
+  > EOF
+  $ echo Two >main-file-2
+  $ hg add
+  adding main-file-1
+  adding main-file-2
+  $ hg commit --message base
+  $ cd ..
+
+and clone this into a new repo where we do our work::
+
+  $ hg clone main work
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd work
+
+
+Create First Patch
+------------------
+
+To begin with, we just do the changes that will be the initial version of the changeset::
+
+  $ echo One >file-from-A
+  $ sed -i'' -e s/One/Eins/ main-file-1
+  $ hg add file-from-A
+
+So this is what we would like our changeset to be::
+
+  $ hg diff
+  diff --git a/file-from-A b/file-from-A
+  new file mode 100644
+  --- /dev/null
+  +++ b/file-from-A
+  @@ -0,0 +1,1 @@
+  +One
+  diff --git a/main-file-1 b/main-file-1
+  --- a/main-file-1
+  +++ b/main-file-1
+  @@ -1,1 +1,1 @@
+  -One
+  +Eins
+
+To commit it we just - commit it::
+
+  $ hg commit --message "a nifty feature"
+
+and place a bookmark so we can easily refer to it again (which we could have done before the commit)::
+
+  $ hg book feature-A
+
+
+Create Second Patch
+-------------------
+
+Let's do this again for the second changeset::
+
+  $ echo Two >file-from-B
+  $ sed -i'' -e s/Two/Zwie/ main-file-1
+  $ hg add file-from-B
+
+Before committing, however, we need to switch to a new bookmark for the second
+changeset. Otherwise we would inadvertently move the bookmark for our first changeset.
+It is therefore advisable to always set the bookmark before committing::
+
+  $ hg book feature-B
+  $ hg commit --message "another feature (child of $(hg log -r . -T '{node|short}'))"
+
+So here we are::
+
+  $ hg book
+     feature-A                 1:568a468b60fc
+   * feature-B                 2:73296a82292a
+
+
+Fix The Second Patch
+--------------------
+
+There's a typo in feature-B. We spelled *Zwie* instead of *Zwei*::
+
+  $ hg diff --change tip | grep -F Zwie
+  +Zwie
+
+Fixing this is very easy. Just change::
+
+  $ sed -i'' -e s/Zwie/Zwei/ main-file-1
+
+and **amend**::
+
+  $ hg amend
+
+This results in a new single changeset for our amended changeset, and the old
+changeset plus the updating changeset are hidden from view by default::
+
+  $ hg log
+  4	feature-B: another feature (child of 568a468b60fc) - test
+  1	feature-A: a nifty feature - test
+  0	: base - test
+
+  $ hg up feature-A -q
+  $ hg bookmark -i feature-A
+  $ sed -i'' -e s/Eins/Un/ main-file-1
+
+(amend of public changeset denied)
+
+  $ hg phase --public 0 -v
+  phase changed for 1 changesets
+
+
+(amend of on ancestors)
+
+  $ hg amend
+  1 new unstable changesets
+  $ hg log
+  6	feature-A: a nifty feature - test
+  4	feature-B: another feature (child of 568a468b60fc) - test
+  1	: a nifty feature - test
+  0	: base - test
+  $ hg up -q 0
+  $ glog --hidden
+  o  6:ba0ec09b1bab@default(draft) a nifty feature
+  |
+  | x  5:c296b79833d1@default(draft) temporary amend commit for 568a468b60fc
+  | |
+  | | o  4:6992c59c6b06@default(draft) another feature (child of 568a468b60fc)
+  | |/
+  | | x  3:c97947cdc7a2@default(draft) temporary amend commit for 73296a82292a
+  | | |
+  | | x  2:73296a82292a@default(draft) another feature (child of 568a468b60fc)
+  | |/
+  | x  1:568a468b60fc@default(draft) a nifty feature
+  |/
+  @  0:e55e0562ee93@default(public) base
+  
+  $ hg debugobsolete
+  73296a82292a76fb8a7061969d2489ec0d84cd5e 6992c59c6b06a1b4a92e24ff884829ae026d018b 0 (*) {'user': 'test'} (glob)
+  c97947cdc7a2a11cf78419f5c2c3dd3944ec79e8 0 {73296a82292a76fb8a7061969d2489ec0d84cd5e} (*) {'user': 'test'} (glob)
+  568a468b60fc99a42d5d4ddbe181caff1eef308d ba0ec09b1babf3489b567853807f452edd46704f 0 (*) {'user': 'test'} (glob)
+  c296b79833d1d497f33144786174bf35e04e44a3 0 {568a468b60fc99a42d5d4ddbe181caff1eef308d} (*) {'user': 'test'} (glob)
+  $ hg evolve
+  move:[4] another feature (child of 568a468b60fc)
+  atop:[6] a nifty feature
+  merging main-file-1
+  working directory is now at 99833d22b0c6
+  $ hg log
+  7	feature-B: another feature (child of ba0ec09b1bab) - test
+  6	feature-A: a nifty feature - test
+  0	: base - test
+
+Test commit -o options
+
+  $ hg up 6
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg revert -r 7 --all
+  adding file-from-B
+  reverting main-file-1
+  $ sed -i'' -e s/Zwei/deux/ main-file-1
+  $ hg commit -m 'another feature that rox' -o 7
+  created new head
+  $ hg log
+  8	feature-B: another feature that rox - test
+  6	feature-A: a nifty feature - test
+  0	: base - test
+
+phase change turning obsolete changeset public issue a bumped warning
+
+  $ hg phase --hidden --public 7
+  1 new bumped changesets
+
+all solving bumped troubled
+
+  $ hg glog
+  @  8	feature-B: another feature that rox - test
+  |
+  | o  7	: another feature (child of ba0ec09b1bab) - test
+  |/
+  o  6	feature-A: a nifty feature - test
+  |
+  o  0	: base - test
+  
+  $ hg evolve --any --traceback --bumped
+  recreate:[8] another feature that rox
+  atop:[7] another feature (child of ba0ec09b1bab)
+  computing new diff
+  committed as 6707c5e1c49d
+  working directory is now at 6707c5e1c49d
+  $ hg glog
+  @  9	feature-B: bumped update to 99833d22b0c6: - test
+  |
+  o  7	: another feature (child of ba0ec09b1bab) - test
+  |
+  o  6	feature-A: a nifty feature - test
+  |
+  o  0	: base - test
+  
+  $ hg diff --hidden -r 9 -r 8
+  $ hg diff -r 9^ -r 9
+  diff --git a/main-file-1 b/main-file-1
+  --- a/main-file-1
+  +++ b/main-file-1
+  @@ -3,1 +3,1 @@
+  -Zwei
+  +deux
+  $ hg log -r 'bumped()' # no more bumped
+
+test evolve --all
+  $ sed -i'' -e s/deux/to/ main-file-1
+  $ hg commit -m 'dansk 2!'
+  $ sed -i'' -e s/Three/tre/ main-file-1
+  $ hg commit -m 'dansk 3!'
+  $ hg update 9
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ sed -i'' -e s/Un/Én/ main-file-1
+  $ hg commit --amend -m 'dansk!'
+  2 new unstable changesets
+
+(ninja test for the {trouble} template:
+
+  $ hg log -G --template '{rev} {troubles}\n'
+  @  13
+  |
+  | o  11 unstable
+  | |
+  | o  10 unstable
+  | |
+  | x  9
+  |/
+  o  7
+  |
+  o  6
+  |
+  o  0
+  
+
+
+(/ninja)
+
+  $ hg evolve --all --traceback
+  move:[10] dansk 2!
+  atop:[13] dansk!
+  merging main-file-1
+  move:[11] dansk 3!
+  atop:[14] dansk 2!
+  merging main-file-1
+  working directory is now at 68557e4f0048
+  $ hg glog
+  @  15	: dansk 3! - test
+  |
+  o  14	: dansk 2! - test
+  |
+  o  13	feature-B: dansk! - test
+  |
+  o  7	: another feature (child of ba0ec09b1bab) - test
+  |
+  o  6	feature-A: a nifty feature - test
+  |
+  o  0	: base - test
+  
+
+  $ cd ..
+
+enable general delta
+
+  $ cat << EOF >> $HGRCPATH
+  > [format]
+  > generaldelta=1
+  > EOF
+
+
+
+  $ hg init alpha
+  $ cd alpha
+  $ echo 'base' > firstfile
+  $ hg add firstfile
+  $ hg ci -m 'base'
+
+  $ cd ..
+  $ hg clone -Ur 0 alpha beta
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ cd alpha
+
+  $ cat << EOF > A
+  > We
+  > need
+  > some
+  > kind
+  > of 
+  > file
+  > big
+  > enough
+  > to
+  > prevent
+  > snapshot
+  > .
+  > yes
+  > new
+  > lines
+  > are
+  > useless
+  > .
+  > EOF
+  $ hg add A
+  $ hg commit -m 'adding A'
+  $ hg mv A B
+  $ echo '.' >> B
+  $ hg amend -m 'add B'
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  3 files, 4 changesets, 4 total revisions
+  $ hg --config extensions.hgext.mq= strip 'extinct()'
+  abort: empty revision set
+  [255]
+  $ hg --config extensions.hgext.mq= strip --hidden 'extinct()'
+  saved backup bundle to $TESTTMP/alpha/.hg/strip-backup/e87767087a57-d7bd82e9-backup.hg (glob)
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  2 files, 2 changesets, 2 total revisions
+  $ cd ..
+
+Clone just this branch
+
+  $ cd beta
+  $ hg pull -r tip ../alpha
+  pulling from ../alpha
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  $ hg up
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ cd ..
+
+Test graft --obsolete/--old-obsolete
+
+  $ hg init test-graft
+  $ cd test-graft
+  $ mkcommit 0
+  $ mkcommit 1
+  $ mkcommit 2
+  $ mkcommit 3
+  $ hg up -qC 0
+  $ mkcommit 4
+  created new head
+  $ glog --hidden
+  @  4:ce341209337f@default(draft) add 4
+  |
+  | o  3:0e84df4912da@default(draft) add 3
+  | |
+  | o  2:db038628b9e5@default(draft) add 2
+  | |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(draft) add 0
+  
+  $ hg graft -r3 -O
+  grafting 3:0e84df4912da "add 3"
+  $ hg graft -r1 -o 2
+  grafting 1:73d38bb17fd7 "add 1"
+  $ glog --hidden
+  @  6:acb28cd497b7@default(draft) add 1
+  |
+  o  5:0b9e50c35132@default(draft) add 3
+  |
+  o  4:ce341209337f@default(draft) add 4
+  |
+  | x  3:0e84df4912da@default(draft) add 3
+  | |
+  | x  2:db038628b9e5@default(draft) add 2
+  | |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(draft) add 0
+  
+  $ hg debugobsolete
+  0e84df4912da4c7cad22a3b4fcfd58ddfb7c8ae9 0b9e50c35132ff548ec0065caea6a87e1ebcef32 0 (*) {'user': 'test'} (glob)
+  db038628b9e56f51a454c0da0c508df247b41748 acb28cd497b7f8767e01ef70f68697a959573c2d 0 (*) {'user': 'test'} (glob)
+
+Test graft --continue
+
+  $ hg up -qC 0
+  $ echo 2 > 1
+  $ hg ci -Am conflict 1
+  created new head
+  $ hg up -qC 6
+  $ hg graft -O 7
+  grafting 7:a5bfd90a2f29 "conflict" (tip)
+  merging 1
+  warning: conflicts while merging 1! (edit, then use 'hg resolve --mark')
+  abort: unresolved conflicts, can't continue
+  (use 'hg resolve' and 'hg graft --continue')
+  [255]
+  $ hg log -r7 --template '{rev}:{node|short} {obsolete}\n'
+  7:a5bfd90a2f29 
+  $ echo 3 > 1
+  $ hg resolve -m 1
+  (no more unresolved files)
+  continue: hg graft --continue
+  $ hg graft --continue -O
+  grafting 7:a5bfd90a2f29 "conflict" (tip)
+  $ glog --hidden
+  @  8:920e58bb443b@default(draft) conflict
+  |
+  | x  7:a5bfd90a2f29@default(draft) conflict
+  | |
+  o |  6:acb28cd497b7@default(draft) add 1
+  | |
+  o |  5:0b9e50c35132@default(draft) add 3
+  | |
+  o |  4:ce341209337f@default(draft) add 4
+  |/
+  | x  3:0e84df4912da@default(draft) add 3
+  | |
+  | x  2:db038628b9e5@default(draft) add 2
+  | |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(draft) add 0
+  
+  $ hg debugobsolete
+  0e84df4912da4c7cad22a3b4fcfd58ddfb7c8ae9 0b9e50c35132ff548ec0065caea6a87e1ebcef32 0 (*) {'user': 'test'} (glob)
+  db038628b9e56f51a454c0da0c508df247b41748 acb28cd497b7f8767e01ef70f68697a959573c2d 0 (*) {'user': 'test'} (glob)
+  a5bfd90a2f29c7ccb8f917ff4e5013a9053d0a04 920e58bb443b73eea9d6d65570b4241051ea3229 0 (*) {'user': 'test'} (glob)
+
+Test touch
+
+  $ glog
+  @  8:920e58bb443b@default(draft) conflict
+  |
+  o  6:acb28cd497b7@default(draft) add 1
+  |
+  o  5:0b9e50c35132@default(draft) add 3
+  |
+  o  4:ce341209337f@default(draft) add 4
+  |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(draft) add 0
+  
+  $ hg touch
+  $ glog
+  @  9:*@default(draft) conflict (glob)
+  |
+  o  6:acb28cd497b7@default(draft) add 1
+  |
+  o  5:0b9e50c35132@default(draft) add 3
+  |
+  o  4:ce341209337f@default(draft) add 4
+  |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(draft) add 0
+  
+  $ hg touch .
+  $ glog
+  @  10:*@default(draft) conflict (glob)
+  |
+  o  6:acb28cd497b7@default(draft) add 1
+  |
+  o  5:0b9e50c35132@default(draft) add 3
+  |
+  o  4:ce341209337f@default(draft) add 4
+  |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(draft) add 0
+  
+
+Test fold
+
+  $ rm *.orig
+  $ hg fold
+  abort: no revisions specified
+  [255]
+  $ hg fold --from
+  abort: no revisions specified
+  [255]
+  $ hg fold .
+  abort: must specify either --from or --exact
+  [255]
+  $ hg fold --from . --exact
+  abort: cannot use both --from and --exact
+  [255]
+  $ hg fold --from .
+  single revision specified, nothing to fold
+  [1]
+  $ hg fold 0::10 --rev 1 --exact
+  abort: cannot fold non-linear revisions (multiple heads given)
+  [255]
+  $ hg fold -r 4 -r 6 --exact
+  abort: cannot fold non-linear revisions (multiple roots given)
+  [255]
+  $ hg fold --from 10 1
+  abort: cannot fold non-linear revisions
+  (given revisions are unrelated to parent of working directory)
+  [255]
+  $ hg fold --exact -r "4 and not 4"
+  abort: specified revisions evaluate to an empty set
+  (use different revision arguments)
+  [255]
+  $ hg phase --public 0
+  $ hg fold --from -r 0
+  abort: cannot fold public revisions
+  [255]
+  $ hg fold --from -r 5
+  3 changesets folded
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg fold --from 6 # want to run hg fold 6
+  abort: hidden revision '6'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg log -r 11 --template '{desc}\n'
+  add 3
+  
+  
+  add 1
+  
+  
+  conflict
+  $ hg debugrebuildstate
+  $ hg st
+
+Test fold with wc parent is not the head of the folded revision
+
+  $ hg up 4
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg fold --rev 4::11 --user victor --exact
+  2 changesets folded
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ glog
+  @  12:d26d339c513f@default(draft) add 4
+  |
+  | o  1:73d38bb17fd7@default(draft) add 1
+  |/
+  o  0:8685c6d34325@default(public) add 0
+  
+  $ hg log --template '{rev}: {author}\n'
+  12: victor
+  1: test
+  0: test
+  $ hg log -r 12 --template '{desc}\n'
+  add 4
+  
+  
+  add 3
+  
+  
+  add 1
+  
+  
+  conflict
+  $ hg debugrebuildstate
+  $ hg st
+
+Test olog
+
+  $ hg olog
+  4	: add 4 - test
+  11	: add 3 - test
+
+Test obsstore stat
+
+  $ hg debugobsstorestat
+  markers total:                     10
+      for known precursors:          10
+      with parents data:              0
+  markers with no successors:         0
+                1 successors:        10
+                2 successors:         0
+      more than 2 successors:         0
+      available  keys:
+                 user:               10
+  disconnected clusters:              1
+          any known node:             1
+          smallest length:           10
+          longer length:             10
+          median length:             10
+          mean length:               10
+      using parents data:             1
+          any known node:             1
+          smallest length:           10
+          longer length:             10
+          median length:             10
+          mean length:               10
+
+
+Test evolving renames
+
+  $ hg up null
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ echo a > a
+  $ hg ci -Am a
+  adding a
+  created new head
+  $ echo b > b
+  $ hg ci -Am b
+  adding b
+  $ hg mv a c
+  $ hg ci -m c
+  $ hg prune .^
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg stab --any
+  move:[15] c
+  atop:[13] a
+  working directory is now at 3742bde73477
+  $ hg st -C --change=tip
+  A c
+    a
+  R a
+
+Test fold with commit messages
+
+  $ cd ../work
+  $ hg fold --from .^ --message "Folding with custom commit message"
+  2 changesets folded
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ glog
+  @  16:98cb758db56d@default(draft) Folding with custom commit message
+  |
+  o  13:0a2f9b959bb4@default(draft) dansk!
+  |
+  o  7:99833d22b0c6@default(public) another feature (child of ba0ec09b1bab)
+  |
+  o  6:ba0ec09b1bab@default(public) a nifty feature
+  |
+  o  0:e55e0562ee93@default(public) base
+  
+  $ cat > commit-message <<EOF
+  > A longer
+  >                   commit message
+  > EOF
+
+  $ hg fold --from .^ --logfile commit-message
+  2 changesets folded
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg qlog
+  17 - a00182c58888 A longer
+                    commit message (draft)
+  7 - 99833d22b0c6 another feature (child of ba0ec09b1bab) (public)
+  6 - ba0ec09b1bab a nifty feature (public)
+  0 - e55e0562ee93 base (public)
+
+  $ cd ..
+
+Test branch preservation:
+===========================
+
+  $ hg init evolving-branch
+  $ cd evolving-branch
+  $ touch a
+  $ hg add a
+  $ hg ci -m 'a0'
+  $ echo 1 > a
+  $ hg ci -m 'a1'
+  $ echo 2 > a
+  $ hg ci -m 'a2'
+  $ echo 3 > a
+  $ hg ci -m 'a3'
+
+  $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
+  @  3 [default] a3
+  |
+  o  2 [default] a2
+  |
+  o  1 [default] a1
+  |
+  o  0 [default] a0
+  
+
+branch change propagated
+
+  $ hg up 'desc(a2)'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch mybranch
+  marked working directory as branch mybranch
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg amend
+  1 new unstable changesets
+
+  $ hg evolve
+  move:[3] a3
+  atop:[5] a2
+  working directory is now at 7c5649f73d11
+
+  $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
+  @  6 [mybranch] a3
+  |
+  o  5 [mybranch] a2
+  |
+  o  1 [default] a1
+  |
+  o  0 [default] a0
+  
+
+branch change preserved
+
+  $ hg up 'desc(a1)'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg amend -m 'a1_'
+  2 new unstable changesets
+  $ hg evolve
+  move:[5] a2
+  atop:[7] a1_
+  working directory is now at eb07e22a0e63
+  $ hg evolve
+  move:[6] a3
+  atop:[8] a2
+  working directory is now at 777c26ca5e78
+  $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
+  @  9 [mybranch] a3
+  |
+  o  8 [mybranch] a2
+  |
+  o  7 [default] a1_
+  |
+  o  0 [default] a0
+  
+
+Evolve from the middle of a stack pick the right changesets.
+
+  $ hg up 7
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg ci --amend -m 'a1__'
+  2 new unstable changesets
+
+  $ hg up 8
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
+  o  10 [default] a1__
+  |
+  | o  9 [mybranch] a3
+  | |
+  | @  8 [mybranch] a2
+  | |
+  | x  7 [default] a1_
+  |/
+  o  0 [default] a0
+  
+  $ hg evolve
+  nothing to evolve on current working copy parent
+  (2 other unstable in the repository, do you want --any or --rev)
+  [2]
+
+
+Evolve disables active bookmarks.
+
+  $ hg up 10
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg bookmark testbookmark
+  $ ls .hg/bookmarks*
+  .hg/bookmarks
+  .hg/bookmarks.* (glob)
+  $ hg evolve
+  move:[8] a2
+  atop:[10] a1__
+  (leaving bookmark testbookmark)
+  working directory is now at d952e93add6f
+  $ ls .hg/bookmarks*
+  .hg/bookmarks
+
+Possibility to select what trouble to solve first, asking for bumped before
+divergent
+  $ hg up 10
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg revert -r 11 --all
+  reverting a
+  $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
+  o  11 [mybranch] a2
+  |
+  @  10 [default] a1__
+  |
+  | o  9 [mybranch] a3
+  | |
+  | x  8 [mybranch] a2
+  | |
+  | x  7 [default] a1_
+  |/
+  o  0 [default] a0
+  
+  $ echo "hello world" > newfile
+  $ hg add newfile
+  $ hg commit -m "add new file bumped" -o 11
+  $ hg phase --public --hidden 11
+  1 new bumped changesets
+  $ hg glog
+  @  12	: add new file bumped - test
+  |
+  | o  11	: a2 - test
+  |/
+  o  10	testbookmark: a1__ - test
+  |
+  | o  9	: a3 - test
+  | |
+  | x  8	: a2 - test
+  | |
+  | x  7	: a1_ - test
+  |/
+  o  0	: a0 - test
+  
+
+Now we have a bumped and an unstable changeset, we solve the bumped first
+normally the unstable changeset would be solve first
+
+  $ hg glog
+  @  12	: add new file bumped - test
+  |
+  | o  11	: a2 - test
+  |/
+  o  10	testbookmark: a1__ - test
+  |
+  | o  9	: a3 - test
+  | |
+  | x  8	: a2 - test
+  | |
+  | x  7	: a1_ - test
+  |/
+  o  0	: a0 - test
+  
+  $ hg evolve -r 12 --bumped
+  recreate:[12] add new file bumped
+  atop:[11] a2
+  computing new diff
+  committed as f15d32934071
+  working directory is now at f15d32934071
+  $ hg evolve --any
+  move:[9] a3
+  atop:[13] bumped update to d952e93add6f:
+  working directory is now at cce26b684bfe
+Check that we can resolve troubles in a revset with more than one commit
+  $ hg up 14 -C
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ mkcommit gg
+  $ hg up 14 
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit gh
+  created new head
+  $ hg up 14 
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ printf "newline\nnewline\n" >> a
+  $ hg glog
+  o  16	: add gh - test
+  |
+  | o  15	: add gg - test
+  |/
+  @  14	: a3 - test
+  |
+  o  13	: bumped update to d952e93add6f: - test
+  |
+  o  11	: a2 - test
+  |
+  o  10	testbookmark: a1__ - test
+  |
+  o  0	: a0 - test
+  
+  $ hg amend
+  2 new unstable changesets
+  $ hg glog
+  @  18	: a3 - test
+  |
+  | o  16	: add gh - test
+  | |
+  | | o  15	: add gg - test
+  | |/
+  | x  14	: a3 - test
+  |/
+  o  13	: bumped update to d952e93add6f: - test
+  |
+  o  11	: a2 - test
+  |
+  o  10	testbookmark: a1__ - test
+  |
+  o  0	: a0 - test
+  
+
+Evolving an empty revset should do nothing
+  $ hg evolve --rev "16 and 15"
+  set of specified revisions is empty
+  [1]
+
+  $ hg evolve --rev "14::" --bumped
+  no bumped changesets in specified revisions
+  (do you want to use --unstable)
+  [2]
+  $ hg evolve --rev "14::" --unstable
+  move:[15] add gg
+  atop:[18] a3
+  move:[16] add gh
+  atop:[18] a3
+  working directory is now at e02107f98737
+  $ hg glog
+  @  20	: add gh - test
+  |
+  | o  19	: add gg - test
+  |/
+  o  18	: a3 - test
+  |
+  o  13	: bumped update to d952e93add6f: - test
+  |
+  o  11	: a2 - test
+  |
+  o  10	testbookmark: a1__ - test
+  |
+  o  0	: a0 - test
+  
+Enabling commands selectively, no command enabled, next and fold and unknown
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=createmarkers
+  > EOF
+  $ hg next
+  hg: unknown command 'next'
+  Mercurial Distributed SCM
+  
+  basic commands:
+  
+   add           add the specified files on the next commit
+   annotate      show changeset information by line for each file
+   clone         make a copy of an existing repository
+   commit        commit the specified files or all outstanding changes
+   diff          diff repository (or selected files)
+   export        dump the header and diffs for one or more changesets
+   forget        forget the specified files on the next commit
+   init          create a new repository in the given directory
+   log           show revision history of entire repository or files
+   merge         merge another revision into working directory
+   pull          pull changes from the specified source
+   push          push changes to the specified destination
+   remove        remove the specified files on the next commit
+   serve         start stand-alone webserver
+   status        show changed files in the working directory
+   summary       summarize working directory state
+   update        update working directory (or switch revisions)
+  
+  (use 'hg help' for the full list of commands or 'hg -v' for details)
+  [255]
+  $ hg fold
+  hg: unknown command 'fold'
+  Mercurial Distributed SCM
+  
+  basic commands:
+  
+   add           add the specified files on the next commit
+   annotate      show changeset information by line for each file
+   clone         make a copy of an existing repository
+   commit        commit the specified files or all outstanding changes
+   diff          diff repository (or selected files)
+   export        dump the header and diffs for one or more changesets
+   forget        forget the specified files on the next commit
+   init          create a new repository in the given directory
+   log           show revision history of entire repository or files
+   merge         merge another revision into working directory
+   pull          pull changes from the specified source
+   push          push changes to the specified destination
+   remove        remove the specified files on the next commit
+   serve         start stand-alone webserver
+   status        show changed files in the working directory
+   summary       summarize working directory state
+   update        update working directory (or switch revisions)
+  
+  (use 'hg help' for the full list of commands or 'hg -v' for details)
+  [255]
+Enabling commands selectively, only fold enabled, next is still unknown
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=createmarkers
+  > evolutioncommands=fold
+  > EOF
+  $ hg fold
+  abort: no revisions specified
+  [255]
+  $ hg next
+  hg: unknown command 'next'
+  Mercurial Distributed SCM
+  
+  basic commands:
+  
+   add           add the specified files on the next commit
+   annotate      show changeset information by line for each file
+   clone         make a copy of an existing repository
+   commit        commit the specified files or all outstanding changes
+   diff          diff repository (or selected files)
+   export        dump the header and diffs for one or more changesets
+   fold          fold multiple revisions into a single one
+   forget        forget the specified files on the next commit
+   init          create a new repository in the given directory
+   log           show revision history of entire repository or files
+   merge         merge another revision into working directory
+   pull          pull changes from the specified source
+   push          push changes to the specified destination
+   remove        remove the specified files on the next commit
+   serve         start stand-alone webserver
+   status        show changed files in the working directory
+   summary       summarize working directory state
+   update        update working directory (or switch revisions)
+  
+  (use 'hg help' for the full list of commands or 'hg -v' for details)
+  [255]
+
+Restore all of the evolution features
+
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=all
+  > EOF
+
+Check hg evolve --rev on singled out commit
+  $ hg up 19 -C
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit j1
+  $ mkcommit j2
+  $ mkcommit j3
+  $ hg up .^^
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo "hello" > j4
+  $ hg add j4
+  $ hg amend
+  2 new unstable changesets
+  $ glog -r "18::"
+  @  25:8dc373be86d9@default(draft) add j1
+  |
+  | o  23:d7eadcf6eccd@default(draft) add j3
+  | |
+  | o  22:2223ea564144@default(draft) add j2
+  | |
+  | x  21:48490698b269@default(draft) add j1
+  |/
+  | o  20:e02107f98737@default(draft) add gh
+  | |
+  o |  19:24e63b319adf@default(draft) add gg
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+
+  $ hg evolve --rev 23 --any
+  abort: cannot specify both "--rev" and "--any"
+  [255]
+  $ hg evolve --rev 23
+  cannot solve instability of d7eadcf6eccd, skipping
+
+Check that uncommit respects the allowunstable option
+With only createmarkers we can only uncommit on a head
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=createmarkers, allnewcommands
+  > EOF
+  $ hg up 8dc373be86d9^
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg uncommit --all
+  abort: cannot uncommit in the middle of a stack
+  [255]
+  $ hg up 8dc373be86d9
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg uncommit --all
+  new changeset is empty
+  (use 'hg prune .' to remove it)
+  $ glog -r "18::"
+  @  26:044804d0c10d@default(draft) add j1
+  |
+  | o  23:d7eadcf6eccd@default(draft) add j3
+  | |
+  | o  22:2223ea564144@default(draft) add j2
+  | |
+  | x  21:48490698b269@default(draft) add j1
+  |/
+  | o  20:e02107f98737@default(draft) add gh
+  | |
+  o |  19:24e63b319adf@default(draft) add gg
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+
+Check that prune respects the allowunstable option
+  $ hg up -C .
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg up 20
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg evolve --all
+  nothing to evolve on current working copy parent
+  (2 other unstable in the repository, do you want --any or --rev)
+  [2]
+  $ hg evolve --all --any
+  move:[22] add j2
+  atop:[26] add j1
+  move:[23] add j3
+  atop:[27] add j2
+  working directory is now at c9a20e2d74aa
+  $ glog -r "18::"
+  @  28:c9a20e2d74aa@default(draft) add j3
+  |
+  o  27:b0e3066231e2@default(draft) add j2
+  |
+  o  26:044804d0c10d@default(draft) add j1
+  |
+  | o  20:e02107f98737@default(draft) add gh
+  | |
+  o |  19:24e63b319adf@default(draft) add gg
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+  $ hg up 19
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit c5_
+  created new head
+  $ hg prune '26 + 27'
+  abort: cannot prune in the middle of a stack
+  (new unstable changesets are not allowed)
+  [255]
+  $ hg prune '19::28'
+  abort: cannot prune in the middle of a stack
+  (new unstable changesets are not allowed)
+  [255]
+  $ hg prune '26::'
+  3 changesets pruned
+  $ glog -r "18::"
+  @  29:2251801b6c91@default(draft) add c5_
+  |
+  | o  20:e02107f98737@default(draft) add gh
+  | |
+  o |  19:24e63b319adf@default(draft) add gg
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+
+Check that fold respects the allowunstable option
+  $ hg up edc3c9de504e
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit unstableifparentisfolded
+  created new head
+  $ glog -r "18::"
+  @  30:68330ac625b8@default(draft) add unstableifparentisfolded
+  |
+  | o  29:2251801b6c91@default(draft) add c5_
+  | |
+  +---o  20:e02107f98737@default(draft) add gh
+  | |
+  | o  19:24e63b319adf@default(draft) add gg
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+
+  $ hg fold --exact "19 + 18"
+  abort: cannot fold chain not ending with a head or with branching
+  (new unstable changesets are not allowed)
+  [255]
+  $ hg fold --exact "18::29"
+  abort: cannot fold chain not ending with a head or with branching
+  (new unstable changesets are not allowed)
+  [255]
+  $ hg fold --exact "19::"
+  2 changesets folded
+
+Check that evolve shows error while handling split commits
+--------------------------------------
+
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=all
+  > EOF
+
+  $ glog -r "18::"
+  o  31:580886d07058@default(draft) add gg
+  |
+  | @  30:68330ac625b8@default(draft) add unstableifparentisfolded
+  |/
+  | o  20:e02107f98737@default(draft) add gh
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+
+Create a split commit
+  $ printf "oo" > oo;
+  $ printf "pp" > pp;
+  $ hg add oo pp
+  $ hg commit -m "oo+pp"
+  $ mkcommit uu
+  $ hg up 30
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ printf "oo" > oo;
+  $ hg add oo
+  $ hg commit -m "_oo"
+  created new head
+  $ printf "pp" > pp;
+  $ hg add pp
+  $ hg commit -m "_pp"
+  $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')" --split
+  1 changesets pruned
+  1 new unstable changesets
+  $ glog -r "18::"
+  @  35:7a555adf2b4a@default(draft) _pp
+  |
+  o  34:2be4d2d5bf34@default(draft) _oo
+  |
+  | o  33:53f0c003e03e@default(draft) add uu
+  | |
+  | x  32:1bf2152f4f82@default(draft) oo+pp
+  |/
+  | o  31:580886d07058@default(draft) add gg
+  | |
+  o |  30:68330ac625b8@default(draft) add unstableifparentisfolded
+  |/
+  | o  20:e02107f98737@default(draft) add gh
+  |/
+  o  18:edc3c9de504e@default(draft) a3
+  |
+  ~
+  $ hg evolve --rev "18::"
+  move:[33] add uu
+  atop:[35] _pp
+  working directory is now at 43c3f5ef149f
+
+
+Check that dirstate changes are kept at failure for conflicts (issue4966)
+----------------------------------------
+
+  $ echo "will be amended" > newfile
+  $ hg commit -m "will be amended"
+  $ hg parents
+  37	: will be amended - test
+
+  $ echo "will be evolved safely" >> a
+  $ hg commit -m "will be evolved safely"
+
+  $ echo "will cause conflict at evolve" > newfile
+  $ echo "newly added" > newlyadded
+  $ hg add newlyadded
+  $ hg commit -m "will cause conflict at evolve"
+
+  $ hg update -q 37
+  $ echo "amended" > newfile
+  $ hg amend -m "amended"
+  2 new unstable changesets
+
+  $ hg evolve --rev "37::"
+  move:[38] will be evolved safely
+  atop:[41] amended
+  move:[39] will cause conflict at evolve
+  atop:[42] will be evolved safely
+  merging newfile
+  warning: conflicts while merging newfile! (edit, then use 'hg resolve --mark')
+  evolve failed!
+  fix conflict and run 'hg evolve --continue' or use 'hg update -C .' to abort
+  abort: unresolved merge conflicts (see hg help resolve)
+  [255]
+
+  $ glog -r "36::" --hidden
+  @  42:c904da5245b0@default(draft) will be evolved safely
+  |
+  o  41:34ae045ec400@default(draft) amended
+  |
+  | x  40:e88bee38ffc2@default(draft) temporary amend commit for 36030b147271
+  | |
+  | | o  39:02e943732647@default(draft) will cause conflict at evolve
+  | | |
+  | | x  38:f8e30e9317aa@default(draft) will be evolved safely
+  | |/
+  | x  37:36030b147271@default(draft) will be amended
+  |/
+  o  36:43c3f5ef149f@default(draft) add uu
+  |
+  ~
+
+  $ hg status newlyadded
+  A newlyadded
+
+hg metaedit
+-----------
+
+  $ hg update --clean .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ rm newlyadded
+  $ hg metaedit -r 0
+  abort: cannot edit commit information for public revisions
+  [255]
+  $ hg metaedit --fold
+  abort: revisions must be specified with --fold
+  [255]
+  $ hg metaedit -r 0 --fold
+  abort: cannot fold public revisions
+  [255]
+  $ hg metaedit '36 + 42' --fold
+  abort: cannot fold non-linear revisions (multiple roots given)
+  [255]
+  $ hg metaedit '36::39 + 41' --fold
+  abort: cannot fold non-linear revisions (multiple heads given)
+  [255]
+check that metaedit respects allowunstable
+  $ hg metaedit '.^' --config 'experimental.evolution=createmarkers, allnewcommands'
+  abort: cannot edit commit information in the middle of a stack
+  (c904da5245b0 will become unstable and new unstable changes are not allowed)
+  [255]
+  $ hg metaedit '18::20' --fold --config 'experimental.evolution=createmarkers, allnewcommands'
+  abort: cannot fold chain not ending with a head or with branching
+  (new unstable changesets are not allowed)
+  [255]
+  $ hg metaedit --user foobar
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log --template '{rev}: {author}\n' -r '42:' --hidden
+  42: test
+  43: foobar
+  $ hg log --template '{rev}: {author}\n' -r .
+  43: foobar
+
+TODO: support this
+  $ hg metaedit '.^::.'
+  abort: editing multiple revisions without --fold is not currently supported
+  [255]
+
+  $ HGEDITOR=cat hg metaedit '.^::.' --fold
+  HG: This is a fold of 2 changesets.
+  HG: Commit message of changeset 41.
+  
+  amended
+  
+  HG: Commit message of changeset 43.
+  
+  will be evolved safely
+  
+  
+  
+  HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+  HG: Leave message empty to abort commit.
+  HG: --
+  HG: user: test
+  HG: branch 'default'
+  HG: changed a
+  HG: changed newfile
+  2 changesets folded
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ glog -r .
+  @  44:41bf1183869c@default(draft) amended
+  |
+  ~
+
+no new commit is created here because the date is the same
+  $ HGEDITOR=cat hg metaedit
+  amended
+  
+  
+  will be evolved safely
+  
+  
+  HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+  HG: Leave message empty to abort commit.
+  HG: --
+  HG: user: test
+  HG: branch 'default'
+  HG: changed a
+  HG: changed newfile
+  nothing changed
+
+  $ glog -r '.^::.'
+  @  44:41bf1183869c@default(draft) amended
+  |
+  o  36:43c3f5ef149f@default(draft) add uu
+  |
+  ~
+
+TODO: don't create a new commit in this case
+  $ hg metaedit --config defaults.metaedit=
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -r '.^::.' --template '{rev}: {desc|firstline}\n'
+  36: add uu
+  45: amended
+
+  $ hg up .^
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg metaedit --user foobar2 45
+  $ hg log --template '{rev}: {author}\n' -r '42:' --hidden
+  42: test
+  43: foobar
+  44: test
+  45: test
+  46: foobar2
+  $ hg diff -r 45 -r 46 --hidden
+
+'fold' one commit
+  $ hg metaedit 39 --fold --user foobar3
+  1 changesets folded
+  $ hg log -r 47 --template '{rev}: {author}\n'
+  47: foobar3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A1.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,285 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+==== A.1.1 pushing a single head ====
+..
+.. {{{
+..     ⇠◔ A
+..      |
+..      ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * A
+..
+.. Command run:
+..
+..  * hg push -r A
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * chain from A
+
+Setup
+---------------
+
+initial
+
+  $ setuprepos A.1.1
+  creating test repo for test case A.1.1
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A)'`
+  $ hg log -G
+  @  f5bc6836db60 (draft): A
+  |
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+setup both variants
+
+  $ cp -r A.1.1 A.1.1.a
+  $ cp -r A.1.1 A.1.1.b
+
+
+Variant a: push -r A
+--------------------
+
+  $ dotest A.1.1.a A
+  ## Running testcase A.1.1.a
+  # testing echange of "A" (f5bc6836db60)
+  ## initial state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "f5bc6836db60" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+
+
+
+Variant b: push
+---------------
+
+  $ dotest A.1.1.b
+  ## Running testcase A.1.1.b
+  ## initial state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+
+
+
+
+
+==== A.1.2 pushing a multiple changeset into a single head  ====
+
+.. {{{
+..      ◔ B
+..      |
+..     ⇠◔ A
+..      |
+..      ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * A
+..
+.. Command run:
+..
+..  * hg push -r B
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * chain from A
+
+Setup
+---------------
+
+initial
+
+  $ setuprepos A.1.2
+  creating test repo for test case A.1.2
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ mkcommit B
+  $ hg log -G
+  @  f6fbb35d8ac9 (draft): B
+  |
+  o  f5bc6836db60 (draft): A
+  |
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A)'`
+  $ hg debugobsolete
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+setup both variants
+
+  $ cp -r A.1.2 A.1.2.a
+  $ cp -r A.1.2 A.1.2.b
+
+
+Variant a: push -r A
+--------------------
+
+  $ dotest A.1.2.a B
+  ## Running testcase A.1.2.a
+  # testing echange of "B" (f6fbb35d8ac9)
+  ## initial state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "B" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "f6fbb35d8ac9" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Variant b: push
+---------------
+
+  $ dotest A.1.2.b
+  ## Running testcase A.1.2.b
+  ## initial state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A2.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,110 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== A.2 Two heads ===
+
+.. {{{
+..     ⇠○ B
+..   ⇠◔ | A
+..    |/
+..    ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * A
+..  * B
+..
+..
+.. Command run:
+..
+..  * hg push -r A
+..
+.. Expected exchange:
+..
+..  * chain from A
+..
+.. Expected Exclude:
+..
+..  * chain from B
+
+initial
+
+  $ setuprepos A.2
+  creating test repo for test case A.2
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A)'`
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit B
+  created new head
+  $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb `getid 'desc(B)'`
+  $ hg log -G
+  @  35b183996678 (draft): B
+  |
+  | o  f5bc6836db60 (draft): A
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+
+Actual Test
+---------------
+
+  $ dotest A.2 A
+  ## Running testcase A.2
+  # testing echange of "A" (f5bc6836db60)
+  ## initial state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "f5bc6836db60" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+
+  $ cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A3.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,218 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== A.3 new branch created ===
+
+.. {{{
+..   B' ○⇢ø B
+..      | |
+..      \Aø⇠◔ A'
+..       \|/
+..        ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `Aø⇠○ A'`
+..  * `Bø⇠○ B'`
+..
+.. Command run:
+..
+..  * hg push -r A
+..
+.. Expected exchange:
+..
+..  * chain from A
+..
+.. Expected Exclude:
+..
+..  * chain from B
+..
+.. Extra note:
+..
+.. If A and B are remontly known, we should expect:
+..
+..  * `hg push` will complain about the new head
+..  * `hg push` should complain about unstable history creation
+
+initial
+
+  $ setuprepos A.3.a
+  creating test repo for test case A.3.a
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B0
+  $ hg update -q 0
+  $ mkcommit A1
+  created new head
+  $ hg update -q 0
+  $ mkcommit B1
+  created new head
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+  $ hg log -G --hidden
+  @  f6298a8ac3a4 (draft): B1
+  |
+  | o  e5ea8f9c7314 (draft): A1
+  |/
+  | x  6e72f0a95b5e (draft): B0
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test for first version (changeset unknown in remote)
+-----------------------------------------------------------
+
+  $ dotest A.3.a A1
+  ## Running testcase A.3.a
+  # testing echange of "A1" (e5ea8f9c7314)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "e5ea8f9c7314" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+
+other variant: changeset known in remote
+----------------------------------------
+
+  $ setuprepos A.3.b
+  creating test repo for test case A.3.b
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B0
+  $ hg push -q ../pushdest
+  $ hg push -q ../pulldest
+  $ hg update -q 0
+  $ mkcommit A1
+  created new head
+  $ hg update -q 0
+  $ mkcommit B1
+  created new head
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+  $ hg log -G --hidden
+  @  f6298a8ac3a4 (draft): B1
+  |
+  | o  e5ea8f9c7314 (draft): A1
+  |/
+  | x  6e72f0a95b5e (draft): B0
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test for first version (changeset unknown in remote)
+-----------------------------------------------------------
+
+check it complains about multiple heads
+
+  $ cd A.3.b
+  $ hg push -R main -r e5ea8f9c7314 pushdest
+  pushing to pushdest
+  searching for changes
+  abort: push creates new remote head e5ea8f9c7314!
+  (merge or see 'hg help push' for details about pushing new heads)
+  [255]
+  $ cd ..
+
+test obsmarkers exchange.
+
+  $ dotest A.3.b A1 -f
+  ## Running testcase A.3.b
+  # testing echange of "A1" (e5ea8f9c7314)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "e5ea8f9c7314" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  1 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  1 new unstable changesets
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A4.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,112 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+
+=== A.4 Push in the middle of the obsolescence chain ===
+
+.. (Where we show that we should not push the marker without the successors)
+..
+.. {{{
+..   B ◔
+..     |
+..   A⇠ø⇠○ A'
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `Aø⇠○ A'`
+..  * chain from A
+..
+.. Command run:
+..
+..  * hg push -r B
+..
+.. Expected exchange:
+..
+..  * Chain from A
+..
+.. Expected Exclude:
+..
+..  * `Aø⇠○ A'`
+
+
+initial
+
+  $ setuprepos A.4
+  creating test repo for test case A.4
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B
+  $ hg update 0
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit A1
+  created new head
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A0)'`
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg log -G --hidden
+  @  e5ea8f9c7314 (draft): A1
+  |
+  | o  06055a7959d4 (draft): B
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test for first version (changeset unknown in remote)
+-----------------------------------------------------------
+
+  $ dotest A.4 B -f
+  ## Running testcase A.4
+  # testing echange of "B" (06055a7959d4)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "B" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "06055a7959d4" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A5.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,121 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+
+=== A.5 partial reordering ===
+..
+.. {{{
+..   B ø⇠⇠
+..     | ⇡
+..   A ø⇠⇠⇠○ A'
+..     | ⇡/
+..     | ○ B'
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `Aø⇠○ A'`
+..  * `Bø⇠○ B'`
+..
+.. Command run:
+..
+..  * hg push -r B
+..
+.. Expected exchange:
+..
+..  * `Bø⇠○ B'`
+..
+.. Expected Exclude:
+..
+..  * `Aø⇠○ A'`
+
+
+initial
+
+  $ setuprepos A.5
+  creating test repo for test case A.5
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B0
+  $ hg update 0
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit B1
+  created new head
+  $ mkcommit A1
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A0)'`
+  $ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg log -G --hidden
+  @  8c0a98c83722 (draft): A1
+  |
+  o  f6298a8ac3a4 (draft): B1
+  |
+  | x  6e72f0a95b5e (draft): B0
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 8c0a98c8372212c6efde4bfdcef006f27ff759d3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-----------
+
+  $ dotest A.5 B1
+  ## Running testcase A.5
+  # testing echange of "B1" (f6298a8ac3a4)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 8c0a98c8372212c6efde4bfdcef006f27ff759d3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "B1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 8c0a98c8372212c6efde4bfdcef006f27ff759d3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "f6298a8ac3a4" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 8c0a98c8372212c6efde4bfdcef006f27ff759d3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28b51eb45704506b5c603decd6bf7ac5e0f6a52f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A6.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,134 @@
+
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+
+=== A.6 between existing changeset ===
+
+.. {{{
+..   A ◕⇠● B
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `A◕⇠● B`
+..
+.. Command run:
+..
+..  * hg push -r B
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * `A◕⇠● B`
+
+
+initial
+
+  $ setuprepos A.6
+  creating test repo for test case A.6
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ hg update -q 0
+  $ mkcommit A1
+  created new head
+
+make both changeset known in remote
+
+  $ hg push -qf ../pushdest
+  $ hg push -qf ../pulldest
+
+create a marker after this
+
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg log -G --hidden
+  @  e5ea8f9c7314 (draft): A1
+  |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+  $ cp -r A.6 A.6.a
+  $ cp -r A.6 A.6.b
+
+Actual Test (explicit push version)
+-----------------------------------
+
+  $ dotest A.6.a A1
+  ## Running testcase A.6.a
+  # testing echange of "A1" (e5ea8f9c7314)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "e5ea8f9c7314" from main into pulldest
+  pulling from main
+  no changes found
+  1 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push version)
+-------------------------------
+
+  $ dotest A.6.b
+  ## Running testcase A.6.b
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  no changes found
+  1 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-A7.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,75 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== A.7 Non targeted common changeset ===
+
+.. {{{
+..    ⇠◕ A
+..     |
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * Chain from A
+..
+.. Command run:
+..
+..  * hg push -r O
+..
+.. Expected exchange:
+..
+..  * ø
+
+
+  $ setuprepos A.7
+  creating test repo for test case A.7
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg push -q ../pushdest
+  $ hg push -q ../pulldest
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A)'`
+  $ hg log -G --hidden
+  @  f5bc6836db60 (draft): A
+  |
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-----------------------------------
+
+  $ dotest A.7 O
+  ## Running testcase A.7
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  ## post push state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  ## post pull state
+  # obstore: main
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B1.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,137 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== B.1 Prune on non-targeted common changeset ===
+
+.. {{{
+..     ⊗ B
+..     |
+..     ◕ A
+..     |
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * B (prune)
+..
+.. Command run:
+..
+..  * hg push -r O
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * B (prune)
+
+
+  $ setuprepos B.1
+  creating test repo for test case B.1
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ mkcommit B
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  f6fbb35d8ac9 (draft): B
+  |
+  @  f5bc6836db60 (draft): A
+  |
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+
+  $ cp -r B.1 B.1.a
+  $ cp -r B.1 B.1.b
+
+Actual Test (explicit push version)
+-----------------------------------
+
+  $ dotest B.1.a A
+  ## Running testcase B.1.a
+  # testing echange of "A" (f5bc6836db60)
+  ## initial state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "f5bc6836db60" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push version)
+-----------------------------------
+
+  $ dotest B.1.b
+  ## Running testcase B.1.b
+  ## initial state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B2.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,117 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== B.2 Pruned changeset on head: nothing pushed ===
+
+.. {{{
+..     ⊗ A
+..     |
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * A (prune)
+..
+.. Command run:
+..
+..  * hg push -r O
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * prune marker for A
+
+
+  $ setuprepos B.2
+  creating test repo for test case B.2
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  f5bc6836db60 (draft): A
+  |
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+
+  $ cp -r B.2 B.2.a
+  $ cp -r B.2 B.2.b
+
+Actual Test (explicit push version)
+-----------------------------------
+
+  $ dotest B.2.a O
+  ## Running testcase B.2.a
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  1 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push version)
+-----------------------------------
+
+  $ dotest B.2.b
+  ## Running testcase B.2.b
+  ## initial state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  no changes found
+  1 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B3.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,100 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== B.3 Pruned changeset on non-pushed part of the history ===
+
+.. {{{
+..   ⊗ C
+..   |
+..   ○ B
+..   | ◔ A
+..   |/
+..   ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * C (prune)
+..
+.. Command run:
+..
+..  * hg push -r A
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * ø
+..
+.. Expected Exclude:
+..
+..  * chain from B
+
+
+  $ setuprepos B.3
+  creating test repo for test case B.3
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg up --quiet 0
+  $ mkcommit B
+  created new head
+  $ mkcommit C
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  e56289ab6378 (draft): C
+  |
+  @  35b183996678 (draft): B
+  |
+  | o  f5bc6836db60 (draft): A
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  e56289ab6378dc752fd7965f8bf66b58bda740bd 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+
+Actual Test
+-----------------------------------
+
+  $ dotest B.3 A
+  ## Running testcase B.3
+  # testing echange of "A" (f5bc6836db60)
+  ## initial state
+  # obstore: main
+  e56289ab6378dc752fd7965f8bf66b58bda740bd 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  ## post push state
+  # obstore: main
+  e56289ab6378dc752fd7965f8bf66b58bda740bd 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pulling "f5bc6836db60" from main into pulldest
+  pulling from main
+  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)
+  ## post pull state
+  # obstore: main
+  e56289ab6378dc752fd7965f8bf66b58bda740bd 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B4.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,143 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== B.4 Pruned changeset on common part of history ===
+
+.. {{{
+..   ⊗ C
+..   | ● B
+..   | |
+..   | ● A
+..   |/
+..   ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * C (prune)
+..
+.. Command run:
+..
+..  * hg push -r B
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * prune for C
+
+
+  $ setuprepos B.4
+  creating test repo for test case B.4
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ mkcommit B
+  $ hg phase --public .
+  $ hg push ../pushdest
+  pushing to ../pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  $ hg push ../pulldest
+  pushing to ../pulldest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  $ hg update -q 0
+  $ mkcommit C
+  created new head
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  7f7f229b13a6 (draft): C
+  |
+  | o  f6fbb35d8ac9 (public): B
+  | |
+  | o  f5bc6836db60 (public): A
+  |/
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+
+  $ cp -r B.4 B.4.a
+  $ cp -r B.4 B.4.b
+
+Actual Test (explicit push version)
+-----------------------------------
+
+  $ dotest B.4.a O
+  ## Running testcase B.4.a
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  1 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push version)
+-----------------------------------
+
+  $ dotest B.4.b
+  ## Running testcase B.4.b
+  ## initial state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 1 new obsolescence markers
+  ## post push state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  no changes found
+  1 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B5.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,171 @@
+
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+
+=== B.5 Push of a children of changeset which successors is pruned ===
+
+.. This case Mirror A.4, with pruned changeset successors.
+..
+.. {{{
+..   B ◔
+..     |
+..   A⇠ø⇠⊗ A'
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `Aø⇠○ A'`
+..  * chain from A
+..  * `A'`
+..
+.. Command run:
+..
+..  * hg push -r B
+..
+.. Expected exchange:
+..
+..  * `Aø⇠○ A'`
+..  * chain from A
+..  * `A'`
+..
+.. Extra Note:
+..
+..   I'm not totally happy about this case and I believe some more complicated
+..   graph can result in behavior wuite confusing for the user (if some tool create
+..   prune maker in a the middle of a valid chain)
+
+  $ setuprepos B.5
+  creating test repo for test case B.5
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B
+  $ hg up --quiet 0
+  $ mkcommit A1
+  created new head
+  $ hg debugobsolete --hidden `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  e5ea8f9c7314 (draft): A1
+  |
+  | o  06055a7959d4 (draft): B
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+  $ cp -r B.5 B.5.a
+  $ cp -r B.5 B.5.b
+
+Actual Test (explicit push version)
+-----------------------------------
+
+  $ dotest B.5.a B -f
+  ## Running testcase B.5.a
+  # testing echange of "B" (06055a7959d4)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "B" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "06055a7959d4" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  1 new unstable changesets
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push version)
+-------------------------------------
+
+  $ dotest B.5.b B -f
+  ## Running testcase B.5.b
+  # testing echange of "B" (06055a7959d4)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "B" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "06055a7959d4" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  1 new unstable changesets
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B6.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,101 @@
+
+
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+== B.6 Pruned changeset with ancestors not in pushed set ===
+
+.. {{{
+..   B ø⇠⊗ B'
+..     | |
+..   A ○ |
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `Bø⇠⊗ B'`
+..  * B' prune
+..
+.. Command run:
+..
+..  * hg push -r O
+..
+.. Expected exchange:
+..
+..  * `Bø⇠⊗ B'`
+..  * B' prune
+
+  $ setuprepos B.6
+  creating test repo for test case B.6
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ mkcommit B0
+  $ hg up --quiet 0
+  $ mkcommit B1
+  created new head
+  $ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  f6298a8ac3a4 (draft): B1
+  |
+  | x  962ecf6b1afc (draft): B0
+  | |
+  | o  f5bc6836db60 (draft): A
+  |/
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-------------------------------------
+
+  $ dotest B.6 O
+  ## Running testcase B.6
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  2 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  962ecf6b1afc94e15c7e48fdfb76ef8abd11372b f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6298a8ac3a4b78bbeae5f1d3dc5bc3c3812f0f3 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-B7.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,83 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+
+=== B.7 Prune on non-targeted common changeset ===
+..
+.. {{{
+..     ⊗ B
+..     |
+..     ◕ A
+..     |
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * B (prune)
+..
+.. Command run:
+..
+..  * hg push -r O
+........  * hg push
+..
+.. Expected exchange:
+..
+..  * ø
+.......  * B (prune)
+
+  $ setuprepos B.7
+  creating test repo for test case B.7
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg push -q ../pushdest
+  $ hg push -q ../pulldest
+  $ mkcommit B
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  f6fbb35d8ac9 (draft): B
+  |
+  @  f5bc6836db60 (draft): A
+  |
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-------------------------------------
+
+  $ dotest B.7 O
+  ## Running testcase B.7
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  ## post push state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  ## post pull state
+  # obstore: main
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-C1.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,135 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== C.1 Multiple pruned changeset atop each other ===
+.. 
+.. {{{
+..   ⊗ B
+..   |
+..   ⊗ A
+..   |
+..   ● O
+.. }}}
+.. 
+.. Marker exist from:
+.. 
+..  * A (prune)
+..  * B (prune)
+.. 
+.. Command run:
+.. 
+..  * hg push -r O
+..  * hg push
+.. 
+.. Expected exchange:
+.. 
+..  * A (prune)
+..  * B (prune)
+
+  $ setuprepos C.1
+  creating test repo for test case C.1
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ mkcommit B
+  $ hg prune -qd '0 0' .^::.
+  $ hg log -G --hidden
+  x  f6fbb35d8ac9 (draft): B
+  |
+  x  f5bc6836db60 (draft): A
+  |
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+  $ cp -r C.1 C.1.a
+  $ cp -r C.1 C.1.b
+
+Actual Test (explicit push)
+---------------------------
+
+  $ dotest C.1.a O
+  ## Running testcase C.1.a
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  2 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push)
+-------------------------------------
+
+  $ dotest C.1.b
+  ## Running testcase C.1.b
+  ## initial state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  no changes found
+  2 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f6fbb35d8ac958bbe70035e4c789c18471cdc0af 0 {f5bc6836db60e308a17ba08bf050154ba9c4fad7} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-C2.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,157 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== C.2 Pruned changeset on precursors ===
+
+.. {{{
+..   B ⊗
+..     |
+..   A ø⇠◔ A'
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * A' succeed to A
+..  * B (prune)
+..
+.. Command run:
+..
+..  * hg push -r A'
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * `A ø⇠o A'`
+..  * B (prune)
+
+  $ setuprepos C.2
+  creating test repo for test case C.2
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B
+  $ hg prune -qd '0 0' .
+  $ hg update -q 0
+  $ mkcommit A1
+  created new head
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg log -G --hidden
+  @  e5ea8f9c7314 (draft): A1
+  |
+  | x  06055a7959d4 (draft): B
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+  $ cp -r C.2 C.2.a
+  $ cp -r C.2 C.2.b
+
+Actual Test (explicit push)
+---------------------------
+
+  $ dotest C.2.a A1
+  ## Running testcase C.2.a
+  # testing echange of "A1" (e5ea8f9c7314)
+  ## initial state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "e5ea8f9c7314" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push)
+-------------------------------------
+
+  $ dotest C.2.b
+  ## Running testcase C.2.b
+  ## initial state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-C3.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,159 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+
+=== C.3 Pruned changeset on precursors of another pruned one ===
+
+.. {{{
+..   B ⊗
+..     |
+..   A ø⇠⊗ A'
+..     |/
+..     ● O
+.. }}}
+.. 
+.. Marker exist from:
+.. 
+..  * A' succeed to A
+..  * A' (prune
+..  * B (prune)
+.. 
+.. Command run:
+.. 
+..  * hg push -r A'
+..  * hg push
+.. 
+.. Expected exchange:
+.. 
+..  * `A ø⇠⊗ A'`
+..  * A (prune)
+..  * B (prune)
+
+  $ setuprepos C.3
+  creating test repo for test case C.3
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B
+  $ hg prune -qd '0 0' .
+  $ hg update -q 0
+  $ mkcommit A1
+  created new head
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  e5ea8f9c7314 (draft): A1
+  |
+  | x  06055a7959d4 (draft): B
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+  $ cp -r C.3 C.3.a
+  $ cp -r C.3 C.3.b
+
+Actual Test (explicit push)
+---------------------------
+
+  $ dotest C.3.a O
+  ## Running testcase C.3.a
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 3 new obsolescence markers
+  ## post push state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  3 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+Actual Test (bare push)
+-------------------------------------
+
+  $ dotest C.3.b
+  ## Running testcase C.3.b
+  ## initial state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 3 new obsolescence markers
+  ## post push state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  no changes found
+  3 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-C4.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,118 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== C.4 multiple successors, one is pruned ===
+
+.. Another case were prune are confusing? (A is killed without its successors being
+.. pushed)
+..
+.. (could split of divergence, if split see the Z section)
+..
+.. {{{
+..        A
+..    B ○⇢ø⇠⊗ C
+..       \|/
+..        ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * `A ø⇠○ B`
+..  * `A ø⇠○ C`
+..  * C (prune)
+..
+..
+.. Command run:
+..
+..  * hg push -r O
+..
+.. Expected exchange:
+..
+..  * `A ø⇠○ C`
+..  * C (prune)
+..
+.. Expected exclude:
+..
+..  * `A ø⇠○ B`
+
+Implemented as the non-split version
+
+  $ setuprepos C.4
+  creating test repo for test case C.4
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A
+  $ hg update -q 0
+  $ mkcommit B
+  created new head
+  $ hg update -q 0
+  $ mkcommit C
+  created new head
+  $ hg debugobsolete --hidden `getid 'desc(A)'` `getid 'desc(B)'`
+  $ hg debugobsolete --hidden `getid 'desc(A)'` `getid 'desc(C)'`
+  $ hg prune -qd '0 0' .
+  $ hg log -G --hidden
+  x  7f7f229b13a6 (draft): C
+  |
+  | o  35b183996678 (draft): B
+  |/
+  | x  f5bc6836db60 (draft): A
+  |/
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-------------------------------------
+
+  $ dotest C.4 O
+  ## Running testcase C.4
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  2 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 35b1839966785d5703a01607229eea932db42f87 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  f5bc6836db60e308a17ba08bf050154ba9c4fad7 7f7f229b13a629a5b20581c6cb723f4e2ca54bed 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-D1.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,105 @@
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== D.1 Pruned changeset based on missing precursor of something not present ===
+
+.. {{{
+..   B ⊗
+..     |
+..   A ◌⇠◔ A'
+..     |/
+..     ● O
+.. }}}
+..
+.. Marker exist from:
+..
+..  * A' succeed to A
+..  * B (prune)
+..
+.. Command run:
+..
+..  * hg push -r A'
+..  * hg push
+..
+.. Expected exchange:
+..
+..  * `A ø⇠o A'`
+..  * B (prune)
+
+  $ setuprepos D.1
+  creating test repo for test case D.1
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B
+  $ hg up -q 0
+  $ mkcommit A1
+  created new head
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg prune -d '0 0' 'desc(B)'
+  1 changesets pruned
+  $ hg strip --hidden -q 'desc(A0)'
+  $ hg log -G --hidden
+  @  e5ea8f9c7314 (draft): A1
+  |
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-------------------------------------
+
+  $ dotest D.1 A1
+  ## Running testcase D.1
+  # testing echange of "A1" (e5ea8f9c7314)
+  ## initial state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "e5ea8f9c7314" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  06055a7959d4128e6e3bccfd01482e83a2db8a3a 0 {28b51eb45704506b5c603decd6bf7ac5e0f6a52f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-D2.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,94 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== D.2 missing prune target (prune in "pushed set") ===
+
+{{{
+}}}
+
+Marker exist from:
+
+ * A' succeed to A
+ * A' (prune)
+
+Command run:
+
+ * hg push
+
+Expected exchange:
+
+ * `A ø⇠o A'`
+ * A' (prune)
+
+
+  $ setuprepos D.2
+  creating test repo for test case D.2
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ hg up -q 0
+  $ mkcommit A1
+  created new head
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg prune --date '0 0' .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at a9bdc8b26820
+  1 changesets pruned
+  $ hg strip --hidden -q 'desc(A1)'
+  $ hg log -G --hidden
+  x  28b51eb45704 (draft): A0
+  |
+  @  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-------------------------------------
+
+  $ dotest D.2
+  ## Running testcase D.2
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling from main into pulldest
+  pulling from main
+  searching for changes
+  no changes found
+  2 new obsolescence markers
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 {a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-D3.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,90 @@
+
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== D.2 missing prune target (prune in "pushed set") ===
+
+{{{
+}}}
+
+Marker exist from:
+
+ * A' succeed to A
+ * A' (prune)
+
+Command run:
+
+ * hg push
+
+Expected exchange:
+
+ * `A ø⇠o A'`
+ * A' (prune)
+
+
+  $ setuprepos D.2
+  creating test repo for test case D.2
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ hg up -q 0
+  $ mkcommit B
+  created new head
+  $ mkcommit A1
+  $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+  $ hg prune -d '0 0' .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at 35b183996678
+  1 changesets pruned
+  $ hg strip --hidden -q 'desc(A1)'
+  $ hg log -G --hidden
+  @  35b183996678 (draft): B
+  |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test
+-------------------------------------
+
+  $ dotest D.2 O
+  ## Running testcase D.2
+  # testing echange of "O" (a9bdc8b26820)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "O" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  no changes found
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pulling "a9bdc8b26820" from main into pulldest
+  pulling from main
+  no changes found
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f 6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6aa67a7b4baa6fb41b06aed38d5b1201436546e2 0 {35b1839966785d5703a01607229eea932db42f87} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-exchange-D4.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,125 @@
+
+
+Initial setup
+
+  $ . $TESTDIR/_exc-util.sh
+
+=== D.4 Unknown changeset in between known one ===
+
+.. Mostly a clarification case
+..
+.. {{{
+..     ø⇠◌⇠○
+..     | |/
+..     | ◔
+..     |/
+..     ● O
+..
+.. }}}
+..
+.. Should be treated as A.3 case:
+..
+.. {{{
+..
+..     ø⇠○
+..     | |
+..     | ◔
+..     |/
+..     ● O
+..
+.. }}}
+
+
+initial
+
+  $ setuprepos A.3.a
+  creating test repo for test case A.3.a
+  - pulldest
+  - main
+  - pushdest
+  cd into `main` and proceed with env setup
+  $ cd main
+  $ mkcommit A0
+  $ mkcommit B0
+  $ hg update -q 0
+  $ mkcommit A1
+  created new head
+  $ mkcommit B1
+  $ hg debugobsolete `getid 'desc(A0)'` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A1)'`
+  $ hg debugobsolete `getid 'desc(B0)'` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+  $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb `getid 'desc(B1)'`
+  $ hg log -G --hidden
+  @  069b05c3876d (draft): B1
+  |
+  o  e5ea8f9c7314 (draft): A1
+  |
+  | x  6e72f0a95b5e (draft): B0
+  | |
+  | x  28b51eb45704 (draft): A0
+  |/
+  o  a9bdc8b26820 (public): O
+  
+  $ hg debugobsolete
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 069b05c3876d56f62895e853a501ea58ea85f68d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  $ cd ..
+  $ cd ..
+
+Actual Test for first version (changeset unknown in remote)
+-----------------------------------------------------------
+
+  $ dotest A.3.a A1
+  ## Running testcase A.3.a
+  # testing echange of "A1" (e5ea8f9c7314)
+  ## initial state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 069b05c3876d56f62895e853a501ea58ea85f68d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  # obstore: pulldest
+  ## pushing "A1" from main to pushdest
+  pushing to pushdest
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: 2 new obsolescence markers
+  ## post push state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 069b05c3876d56f62895e853a501ea58ea85f68d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  ## pulling "e5ea8f9c7314" from main into pulldest
+  pulling from main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  ## post pull state
+  # obstore: main
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  6e72f0a95b5e01a7504743aa941f69cb1fbef8b0 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 069b05c3876d56f62895e853a501ea58ea85f68d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pushdest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  # obstore: pulldest
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-import.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,91 @@
+
+This feature requires mercurial 3.0
+(and the `only()` revset is 3.0 specific)
+
+  $ (hg help revset | grep '"only(' > /dev/null) || exit 80
+
+Test creation of obsolescence marker by path import
+
+  $ hg init auto-obsolete
+  $ cd auto-obsolete
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ echo A > a
+  $ hg commit -Am A
+  adding a
+  $ echo B > b
+  $ hg commit -Am B
+  adding b
+  $ hg up '.^'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo C > c
+  $ hg commit -Am C
+  adding c
+  created new head
+  $ hg log -G
+  @  changeset:   2:eb8dd0f31b51
+  |  tag:         tip
+  |  parent:      0:f2bbf19cf96d
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     C
+  |
+  | o  changeset:   1:95b760afef3c
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     B
+  |
+  o  changeset:   0:f2bbf19cf96d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     A
+  
+
+(actual test)
+
+  $ hg export 'desc(B)' | hg import - --obsolete
+  applying patch from stdin
+  $ hg log -G
+  @  changeset:   3:00c49133f17e
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     B
+  |
+  o  changeset:   2:eb8dd0f31b51
+  |  parent:      0:f2bbf19cf96d
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     C
+  |
+  o  changeset:   0:f2bbf19cf96d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     A
+  
+  $ hg debugobsolete
+  95b760afef3c234ffb3f9fd391edcb36e60921a4 00c49133f17e5e5a52b6ef1b6d516c0e90b56d8a 0 (*) {'user': 'test'} (glob)
+
+  $ hg rollback
+  repository tip rolled back to revision 2 (undo import)
+  working directory now based on revision 2
+  $ hg log -G
+  @  changeset:   2:eb8dd0f31b51
+  |  tag:         tip
+  |  parent:      0:f2bbf19cf96d
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     C
+  |
+  | o  changeset:   1:95b760afef3c
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     B
+  |
+  o  changeset:   0:f2bbf19cf96d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     A
+  
+  $ hg debugobsolete
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-inhibit.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,930 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > logtemplate = {rev}:{node|short} {desc}\n
+  > [experimental]
+  > prunestrip=True
+  > evolution=createmarkers
+  > [extensions]
+  > rebase=
+  > strip=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ echo "directaccess=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/hack/directaccess.py" >> $HGRCPATH
+  $ echo "inhibit=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/hack/inhibit.py" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ hg init inhibit
+  $ cd inhibit
+  $ mkcommit cA
+  $ mkcommit cB
+  $ mkcommit cC
+  $ mkcommit cD
+  $ hg up 'desc(cA)'
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ mkcommit cE
+  created new head
+  $ mkcommit cG
+  $ mkcommit cH
+  $ mkcommit cJ
+  $ hg log -G
+  @  7:18214586bf78 add cJ
+  |
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  | o  3:2db36d8066ff add cD
+  | |
+  | o  2:7df62a38b9bf add cC
+  | |
+  | o  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+
+plain prune
+
+  $ hg strip 1::
+  3 changesets pruned
+  $ hg log -G
+  @  7:18214586bf78 add cJ
+  |
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg debugobsinhibit --hidden 1::
+  $ hg log -G
+  @  7:18214586bf78 add cJ
+  |
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  | o  3:2db36d8066ff add cD
+  | |
+  | o  2:7df62a38b9bf add cC
+  | |
+  | o  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg strip --hidden 1::
+  3 changesets pruned
+  $ hg log -G
+  @  7:18214586bf78 add cJ
+  |
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+
+after amend
+
+  $ echo babar > cJ
+  $ hg commit --amend
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg debugobsinhibit --hidden 18214586bf78
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+
+and no divergence
+
+  $ hg summary
+  parent: 9:55c73a90e4b4 tip
+   add cJ
+  branch: default
+  commit: (clean)
+  update: 1 new changesets, 2 branch heads (merge)
+  phases: 6 draft
+
+check public revision got cleared
+(when adding the second inhibitor, the first one is removed because it is public)
+
+  $ wc -m .hg/store/obsinhibit | sed -e 's/^[ \t]*//'
+  20 .hg/store/obsinhibit
+  $ hg strip 7
+  1 changesets pruned
+  $ hg debugobsinhibit --hidden 18214586bf78
+  $ wc -m .hg/store/obsinhibit | sed -e 's/^[ \t]*//'
+  20 .hg/store/obsinhibit
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg phase --public 7
+  $ hg strip 9
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at cf5c4f4554ce
+  1 changesets pruned
+  $ hg log -G
+  o  7:18214586bf78 add cJ
+  |
+  @  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg debugobsinhibit --hidden 55c73a90e4b4
+  $ wc -m .hg/store/obsinhibit | sed -e 's/^[ \t]*//'
+  20 .hg/store/obsinhibit
+  $ hg log -G
+  o  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  @  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+Update should inhibit all related unstable commits
+
+  $ hg update 2 --hidden
+  2 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg log -G
+  o  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  | @  2:7df62a38b9bf add cC
+  | |
+  | o  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+
+  $ hg update 9
+  4 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  | o  2:7df62a38b9bf add cC
+  | |
+  | o  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg strip --hidden 1::
+  3 changesets pruned
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+
+Bookmark should inhibit all related unstable commits
+  $ hg bookmark -r 2 book1  --hidden
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  | o  2:7df62a38b9bf add cC
+  | |
+  | o  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+
+Removing a bookmark with bookmark -D should prune the changes underneath
+that are not reachable from another bookmark or head
+
+  $ hg bookmark -r 1 book2
+  $ hg bookmark -D book1  --config experimental.evolution=createmarkers #--config to make sure prune is not registered as a command.
+  bookmark 'book1' deleted
+  1 changesets pruned
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  | o  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg bookmark -D book2
+  bookmark 'book2' deleted
+  1 changesets pruned
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+Test edge cases of bookmark -D
+  $ hg book -D book2 -m hello
+  abort: Cannot use both -m and -D
+  [255]
+
+  $ hg book -Draster-fix
+  abort: Error, please check your command
+  (make sure to put a space between -D and your bookmark name)
+  [255]
+
+Test that direct access make changesets visible
+
+  $ hg export 2db36d8066ff 02bcbc3f6e56
+  # HG changeset patch
+  # User test
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID 2db36d8066ff50e8be3d3e6c2da1ebc0a8381d82
+  # Parent  7df62a38b9bf9daf968de235043ba88a8ef43393
+  add cD
+  
+  diff -r 7df62a38b9bf -r 2db36d8066ff cD
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/cD	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +cD
+  # HG changeset patch
+  # User test
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID 02bcbc3f6e56fb2928efec2c6e24472720bf5511
+  # Parent  54ccbc537fc2d6845a5d61337c1cfb80d1d2815e
+  add cB
+  
+  diff -r 54ccbc537fc2 -r 02bcbc3f6e56 cB
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/cB	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +cB
+
+But only with hash
+
+  $ hg export 2db36d8066ff::
+  # HG changeset patch
+  # User test
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID 2db36d8066ff50e8be3d3e6c2da1ebc0a8381d82
+  # Parent  7df62a38b9bf9daf968de235043ba88a8ef43393
+  add cD
+  
+  diff -r 7df62a38b9bf -r 2db36d8066ff cD
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/cD	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +cD
+
+  $ hg export 1 3
+  abort: hidden revision '1'!
+  (use --hidden to access hidden revisions)
+  [255]
+
+
+Test directaccess in a larger revset
+
+  $ hg log -r '. + .^ + 2db36d8066ff' -T '{node|short}\n'
+  55c73a90e4b4
+  cf5c4f4554ce
+  2db36d8066ff
+
+Test directaccess only takes hashes
+
+  $ HOOKPATH=$TESTTMP/printexplicitaccess.py
+  $ cat >> $HOOKPATH <<EOF
+  > def hook(ui, repo, **kwds):
+  >     for i in sorted(repo._explicitaccess):
+  >         ui.write('directaccess: %s\n' % i)
+  > EOF
+
+  $ hg log -r 1 -r 2 -r 2db36d8066f -T '{rev}\n' --config hooks.post-log=python:$HOOKPATH:hook
+  1
+  2
+  3
+  directaccess: 3
+
+With severals hidden sha, rebase of one hidden stack onto another one:
+  $ hg update -C 0
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ mkcommit cK
+  created new head
+  $ mkcommit cL
+  $ hg update -C 9
+  4 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg log -G
+  o  11:53a94305e133 add cL
+  |
+  o  10:ad78ff7d621f add cK
+  |
+  | @  9:55c73a90e4b4 add cJ
+  | |
+  | | o  7:18214586bf78 add cJ
+  | |/
+  | o  6:cf5c4f4554ce add cH
+  | |
+  | o  5:5419eb264a33 add cG
+  | |
+  | o  4:98065434e5c6 add cE
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg strip --hidden 10:
+  2 changesets pruned
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg rebase -s 10 -d 3 
+  abort: hidden revision '3'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg rebase -r ad78ff7d621f -r 53a94305e133 -d  2db36d8066ff --config experimental.rebaseskipobsolete=0
+  Warning: accessing hidden changesets 2db36d8066ff for write operation
+  Warning: accessing hidden changesets ad78ff7d621f,53a94305e133 for write operation
+  rebasing 10:ad78ff7d621f "add cK"
+  rebasing 11:53a94305e133 "add cL"
+  $ hg log -G
+  o  13:2f7b7704d714 add cL
+  |
+  o  12:fe1634cbe235 add cK
+  |
+  | @  9:55c73a90e4b4 add cJ
+  | |
+  | | o  7:18214586bf78 add cJ
+  | |/
+  | o  6:cf5c4f4554ce add cH
+  | |
+  | o  5:5419eb264a33 add cG
+  | |
+  | o  4:98065434e5c6 add cE
+  | |
+  o |  3:2db36d8066ff add cD
+  | |
+  o |  2:7df62a38b9bf add cC
+  | |
+  o |  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+
+Check that amending in the middle of a stack does not show obsolete revs
+Since we are doing operation in the middle of the stack we cannot just
+have createmarkers as we are creating instability
+
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=all
+  > EOF
+
+  $ hg strip --hidden 1::
+  5 changesets pruned
+  $ hg log -G
+  @  9:55c73a90e4b4 add cJ
+  |
+  | o  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg up 7
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ mkcommit cL
+  $ mkcommit cM
+  $ mkcommit cN
+  $ hg log -G
+  @  16:a438c045eb37 add cN
+  |
+  o  15:2d66e189f5b5 add cM
+  |
+  o  14:d66ccb8c5871 add cL
+  |
+  | o  9:55c73a90e4b4 add cJ
+  | |
+  o |  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg up 15
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "mmm" >> cM
+  $ hg amend
+  $ hg log -G
+  @  18:210589181b14 add cM
+  |
+  | o  16:a438c045eb37 add cN
+  | |
+  | o  15:2d66e189f5b5 add cM
+  |/
+  o  14:d66ccb8c5871 add cL
+  |
+  | o  9:55c73a90e4b4 add cJ
+  | |
+  o |  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+Check that rebasing a commit twice makes the commit visible again
+
+  $ hg rebase -d 18 -r 16 --keep
+  rebasing 16:a438c045eb37 "add cN"
+  $ hg log -r 14:: -G
+  o  19:104eed5354c7 add cN
+  |
+  @  18:210589181b14 add cM
+  |
+  | o  16:a438c045eb37 add cN
+  | |
+  | o  15:2d66e189f5b5 add cM
+  |/
+  o  14:d66ccb8c5871 add cL
+  |
+  ~
+  $ hg strip -r 210589181b14
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at d66ccb8c5871
+  2 changesets pruned
+
+Using a hash prefix solely made of digits should work
+  $ hg update 210589181
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg rebase -d 18 -r 16 --keep
+  rebasing 16:a438c045eb37 "add cN"
+  $ hg log -r 14:: -G
+  o  19:104eed5354c7 add cN
+  |
+  @  18:210589181b14 add cM
+  |
+  | o  16:a438c045eb37 add cN
+  | |
+  | o  15:2d66e189f5b5 add cM
+  |/
+  o  14:d66ccb8c5871 add cL
+  |
+  ~
+
+Test prunestrip
+
+  $ hg book foo -r 104eed5354c7
+  $ hg strip -r 210589181b14
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at d66ccb8c5871
+  2 changesets pruned
+  $ hg log -r 14:: -G -T '{rev}:{node|short} {desc|firstline} {bookmarks}\n'
+  o  16:a438c045eb37 add cN
+  |
+  o  15:2d66e189f5b5 add cM
+  |
+  @  14:d66ccb8c5871 add cL foo
+  |
+  ~
+
+Check that --hidden used with inhibit does not hide every obsolete commit
+We show the log before and after a log -G --hidden, they should be the same
+  $ hg log -G
+  o  16:a438c045eb37 add cN
+  |
+  o  15:2d66e189f5b5 add cM
+  |
+  @  14:d66ccb8c5871 add cL
+  |
+  | o  9:55c73a90e4b4 add cJ
+  | |
+  o |  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ hg log -G --hidden
+  x  19:104eed5354c7 add cN
+  |
+  x  18:210589181b14 add cM
+  |
+  | x  17:b3c3274523f9 temporary amend commit for 2d66e189f5b5
+  | |
+  | | o  16:a438c045eb37 add cN
+  | |/
+  | o  15:2d66e189f5b5 add cM
+  |/
+  @  14:d66ccb8c5871 add cL
+  |
+  | x  13:2f7b7704d714 add cL
+  | |
+  | x  12:fe1634cbe235 add cK
+  | |
+  | | x  11:53a94305e133 add cL
+  | | |
+  | | x  10:ad78ff7d621f add cK
+  | | |
+  | | | o  9:55c73a90e4b4 add cJ
+  | | | |
+  +-------x  8:e84f73d9ad36 temporary amend commit for 18214586bf78
+  | | | |
+  o-----+  7:18214586bf78 add cJ
+   / / /
+  | | o  6:cf5c4f4554ce add cH
+  | | |
+  | | o  5:5419eb264a33 add cG
+  | | |
+  | | o  4:98065434e5c6 add cE
+  | |/
+  x |  3:2db36d8066ff add cD
+  | |
+  x |  2:7df62a38b9bf add cC
+  | |
+  x |  1:02bcbc3f6e56 add cB
+  |/
+  o  0:54ccbc537fc2 add cA
+  
+
+  $ hg log -G
+  o  16:a438c045eb37 add cN
+  |
+  o  15:2d66e189f5b5 add cM
+  |
+  @  14:d66ccb8c5871 add cL
+  |
+  | o  9:55c73a90e4b4 add cJ
+  | |
+  o |  7:18214586bf78 add cJ
+  |/
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+ 
+check that pruning and inhibited node does not confuse anything
+
+  $ hg up --hidden 210589181b14
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg strip --bundle 210589181b14
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  saved backup bundle to $TESTTMP/inhibit/.hg/strip-backup/210589181b14-e09c7b88-backup.hg (glob)
+  $ hg unbundle .hg/strip-backup/210589181b14-e09c7b88-backup.hg # restore state
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to 2 files (+1 heads)
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
+
+ Only allow direct access and check that evolve works like before
+(also disable evolve commands to avoid hint about using evolve)
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > inhibit=!
+  > [experimental]
+  > evolution=createmarkers
+  > EOF
+
+  $ hg up 15
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory parent is obsolete!
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=all
+  > EOF
+  $ echo "CM" > cM
+  $ hg amend
+  $ hg log -G
+  @  21:721c3c279519 add cM
+  |
+  | o  16:a438c045eb37 add cN
+  | |
+  | x  15:2d66e189f5b5 add cM
+  |/
+  o  14:d66ccb8c5871 add cL
+  |
+  o  7:18214586bf78 add cJ
+  |
+  o  6:cf5c4f4554ce add cH
+  |
+  o  5:5419eb264a33 add cG
+  |
+  o  4:98065434e5c6 add cE
+  |
+  o  0:54ccbc537fc2 add cA
+  
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > EOF
+  $ echo "inhibit=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/hack/inhibit.py" >> $HGRCPATH
+
+Empty commit
+  $ hg amend
+  nothing changed
+  [1]
+
+Check that the behavior of rebase with obsolescence markers is maintained
+despite inhibit
+
+  $ hg up a438c045eb37
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg rebase -r 15:: -d 21 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 15:2d66e189f5b5 "add cM", already in destination as 21:721c3c279519 "add cM"
+  rebasing 16:a438c045eb37 "add cN"
+  $ hg up -q 2d66e189f5b5 # To inhibit it as the rest of test depends on it
+  $ hg up -q 21
+
+Directaccess should load after some extensions precised in the conf
+With no extension specified:
+
+  $ cat >$TESTTMP/test_extension.py  << EOF
+  > from mercurial import extensions
+  > def uisetup(ui):
+  >   print extensions._order
+  > EOF
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > testextension=$TESTTMP/test_extension.py
+  > EOF
+  $ hg id
+  ['rebase', 'strip', 'evolve', 'directaccess', 'inhibit', 'testextension']
+  721c3c279519
+
+With test_extension specified:
+  $ cat >> $HGRCPATH << EOF
+  > [directaccess]
+  > loadsafter=testextension
+  > EOF
+  $ hg id
+  ['rebase', 'strip', 'evolve', 'inhibit', 'testextension', 'directaccess']
+  721c3c279519
+
+Inhibit should not work without directaccess
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > directaccess=!
+  > testextension=!
+  > EOF
+  $ hg up .
+  cannot use inhibit without the direct access extension
+  (please enable it or inhibit won't work)
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "directaccess=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/hack/directaccess.py" >> $HGRCPATH
+  $ cd ..
+
+hg push should not allow directaccess unless forced with --hidden
+We copy the inhibhit repo to inhibit2 and make some changes to push to inhibit
+
+  $ cp -r inhibit inhibit2
+  $ pwd=$(pwd)
+  $ cd inhibit
+  $ mkcommit pk
+  created new head
+  $ hg id
+  003a4735afde tip
+  $ echo "OO" > pk
+  $ hg amend
+  $ hg id
+  71eb4f100663 tip
+
+Hidden commits cannot be pushed without --hidden
+  $ hg push -r 003a4735afde $pwd/inhibit2
+  pushing to $TESTTMP/inhibit2
+  abort: hidden revision '003a4735afde'!
+  (use --hidden to access hidden revisions)
+  [255]
+
+Visible commits can still be pushed
+  $ hg push -r 71eb4f100663 $pwd/inhibit2
+  pushing to $TESTTMP/inhibit2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  2 new obsolescence markers
+
+Create a stack (obsolete with successor in dest) -> (not obsolete) and rebase
+it. We expect to not see the stack at the end of the rebase.
+  $ hg log -G  -r "25::"
+  @  25:71eb4f100663 add pk
+  |
+  ~
+  $ hg up -C 22
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit Dk
+  $ hg prune 22 -s 25
+  1 changesets pruned
+  $ hg rebase -s 22 -d 25 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 22:46cb6daad392 "add cN", already in destination as 25:71eb4f100663 "add pk"
+  rebasing 26:7ad60e760c7b "add Dk" (tip)
+  $ hg log -G  -r "25::"
+  @  27:1192fa9fbc68 add Dk
+  |
+  o  25:71eb4f100663 add pk
+  |
+  ~
+
+Create a stack (obsolete with succ in dest) -> (not obsolete) -> (not obsolete).
+Rebase the first two revs of the stack onto dest, we expect to see one new
+revision on the destination and everything visible.
+  $ hg up 25
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit Dl
+  created new head
+  $ mkcommit Dp
+  $ mkcommit Do
+  $ hg log -G -r "25::"
+  @  30:b517facce1ef add Do
+  |
+  o  29:c5a47ab27c2e add Dp
+  |
+  o  28:8c1c2edbaf1b add Dl
+  |
+  | o  27:1192fa9fbc68 add Dk
+  |/
+  o  25:71eb4f100663 add pk
+  |
+  ~
+  $ hg prune 28 -s 27
+  1 changesets pruned
+  $ hg up 25
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg rebase -r "28 + 29" --keep -d 27 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 28:8c1c2edbaf1b "add Dl", already in destination as 27:1192fa9fbc68 "add Dk"
+  rebasing 29:c5a47ab27c2e "add Dp"
+  $ hg log -G  -r "25::"
+  o  31:7d8affb1f604 add Dp
+  |
+  | o  30:b517facce1ef add Do
+  | |
+  | o  29:c5a47ab27c2e add Dp
+  | |
+  | o  28:8c1c2edbaf1b add Dl
+  | |
+  o |  27:1192fa9fbc68 add Dk
+  |/
+  @  25:71eb4f100663 add pk
+  |
+  ~
+
+Rebase the same stack in full on the destination, we expect it to disappear
+and only see the top revision added to destination. We don\'t expect 29 to be
+skipped as we used --keep before.
+  $ hg rebase -s 28 -d 27 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 28:8c1c2edbaf1b "add Dl", already in destination as 27:1192fa9fbc68 "add Dk"
+  rebasing 29:c5a47ab27c2e "add Dp"
+  rebasing 30:b517facce1ef "add Do"
+  $ hg log -G  -r "25::"
+  o  32:1d43fff9e26f add Do
+  |
+  o  31:7d8affb1f604 add Dp
+  |
+  o  27:1192fa9fbc68 add Dk
+  |
+  @  25:71eb4f100663 add pk
+  |
+  ~
+
+Pulling from a inhibit repo to a non-inhibit repo should work
+
+  $ cd ..
+  $ hg clone -q inhibit not-inhibit
+  $ cat >> not-inhibit/.hg/hgrc <<EOF
+  > [extensions]
+  > inhibit=!
+  > directaccess=!
+  > evolve=!
+  > EOF
+  $ cd not-inhibit
+  $ hg book -d foo
+  $ hg pull
+  pulling from $TESTTMP/inhibit
+  searching for changes
+  no changes found
+  adding remote bookmark foo
+
+Test that bookmark -D can take multiple branch names
+  $ cd ../inhibit
+  $ hg bookmark book2 book1 book3
+  $ touch foo && hg add foo && hg ci -m "add foo"
+  created new head
+  $ hg up book1
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (activating bookmark book1)
+  $ hg bookmark -D book2 book3
+  bookmark 'book2' deleted
+  bookmark 'book3' deleted
+  1 changesets pruned
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-obsconvert.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,78 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ hg init alpha
+  $ cd alpha
+  $ echo foo > foo
+  $ hg addremove
+  adding foo
+  $ hg ci -m 'foo'
+  $ for x in 1 2 3 4 ; do
+  >   echo foo $x > foo
+  >   hg amend
+  > done
+
+Test conversion between obsolete marker formats
+  $ hg debugobsolete
+  e63c23eaa88ae77967edcf4ea194d31167c478b0 b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 0 (*) {'user': 'test'} (glob)
+  a5b276878fa564da042b4b9efef3713ceea20350 0 {e63c23eaa88ae77967edcf4ea194d31167c478b0} (*) {'user': 'test'} (glob)
+  b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 384fc811182687231962e486f23ea8c5bab7a2d3 0 (*) {'user': 'test'} (glob)
+  2291082406feb57d0f83b9b0a6777b6074f3fde6 0 {b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34} (*) {'user': 'test'} (glob)
+  384fc811182687231962e486f23ea8c5bab7a2d3 949d379b3c3bf051906bc3528c049cb536e2ec86 0 (*) {'user': 'test'} (glob)
+  1616bdbe82d3fd1fb7c4e068aee277835672ffdc 0 {384fc811182687231962e486f23ea8c5bab7a2d3} (*) {'user': 'test'} (glob)
+  949d379b3c3bf051906bc3528c049cb536e2ec86 f2e4c45b2a4a58ccf7ef6825b8fa5685873cd2f7 0 (*) {'user': 'test'} (glob)
+  8668d55aac650158bb510be6d47d21e3db9e5c75 0 {949d379b3c3bf051906bc3528c049cb536e2ec86} (*) {'user': 'test'} (glob)
+  $ hg debugobsconvert --new-format 0
+  Old store is version 1, will rewrite in version 0
+  Done!
+  $ hg debugobsolete
+  e63c23eaa88ae77967edcf4ea194d31167c478b0 b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 0 (*) {'user': 'test'} (glob)
+  a5b276878fa564da042b4b9efef3713ceea20350 0 {e63c23eaa88ae77967edcf4ea194d31167c478b0} (*) {'user': 'test'} (glob)
+  b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 384fc811182687231962e486f23ea8c5bab7a2d3 0 (*) {'user': 'test'} (glob)
+  2291082406feb57d0f83b9b0a6777b6074f3fde6 0 {b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34} (*) {'user': 'test'} (glob)
+  384fc811182687231962e486f23ea8c5bab7a2d3 949d379b3c3bf051906bc3528c049cb536e2ec86 0 (*) {'user': 'test'} (glob)
+  1616bdbe82d3fd1fb7c4e068aee277835672ffdc 0 {384fc811182687231962e486f23ea8c5bab7a2d3} (*) {'user': 'test'} (glob)
+  949d379b3c3bf051906bc3528c049cb536e2ec86 f2e4c45b2a4a58ccf7ef6825b8fa5685873cd2f7 0 (*) {'user': 'test'} (glob)
+  8668d55aac650158bb510be6d47d21e3db9e5c75 0 {949d379b3c3bf051906bc3528c049cb536e2ec86} (*) {'user': 'test'} (glob)
+  $ hg debugobsconvert --new-format 0
+  abort: New format is the same as the old format, not upgrading!
+  [255]
+  $ hg debugobsolete
+  e63c23eaa88ae77967edcf4ea194d31167c478b0 b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 0 (*) {'user': 'test'} (glob)
+  a5b276878fa564da042b4b9efef3713ceea20350 0 {e63c23eaa88ae77967edcf4ea194d31167c478b0} (*) {'user': 'test'} (glob)
+  b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 384fc811182687231962e486f23ea8c5bab7a2d3 0 (*) {'user': 'test'} (glob)
+  2291082406feb57d0f83b9b0a6777b6074f3fde6 0 {b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34} (*) {'user': 'test'} (glob)
+  384fc811182687231962e486f23ea8c5bab7a2d3 949d379b3c3bf051906bc3528c049cb536e2ec86 0 (*) {'user': 'test'} (glob)
+  1616bdbe82d3fd1fb7c4e068aee277835672ffdc 0 {384fc811182687231962e486f23ea8c5bab7a2d3} (*) {'user': 'test'} (glob)
+  949d379b3c3bf051906bc3528c049cb536e2ec86 f2e4c45b2a4a58ccf7ef6825b8fa5685873cd2f7 0 (*) {'user': 'test'} (glob)
+  8668d55aac650158bb510be6d47d21e3db9e5c75 0 {949d379b3c3bf051906bc3528c049cb536e2ec86} (*) {'user': 'test'} (glob)
+  $ hg debugobsconvert --new-format 1
+  Old store is version 0, will rewrite in version 1
+  Done!
+  $ hg debugobsolete
+  e63c23eaa88ae77967edcf4ea194d31167c478b0 b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 0 (*) {'user': 'test'} (glob)
+  a5b276878fa564da042b4b9efef3713ceea20350 0 {e63c23eaa88ae77967edcf4ea194d31167c478b0} (*) {'user': 'test'} (glob)
+  b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 384fc811182687231962e486f23ea8c5bab7a2d3 0 (*) {'user': 'test'} (glob)
+  2291082406feb57d0f83b9b0a6777b6074f3fde6 0 {b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34} (*) {'user': 'test'} (glob)
+  384fc811182687231962e486f23ea8c5bab7a2d3 949d379b3c3bf051906bc3528c049cb536e2ec86 0 (*) {'user': 'test'} (glob)
+  1616bdbe82d3fd1fb7c4e068aee277835672ffdc 0 {384fc811182687231962e486f23ea8c5bab7a2d3} (*) {'user': 'test'} (glob)
+  949d379b3c3bf051906bc3528c049cb536e2ec86 f2e4c45b2a4a58ccf7ef6825b8fa5685873cd2f7 0 (*) {'user': 'test'} (glob)
+  8668d55aac650158bb510be6d47d21e3db9e5c75 0 {949d379b3c3bf051906bc3528c049cb536e2ec86} (*) {'user': 'test'} (glob)
+
+Test that the default is some reasonably modern format (first downgrade)
+  $ hg debugobsconvert --new-format 0
+  Old store is version 1, will rewrite in version 0
+  Done!
+  $ hg debugobsconvert
+  Old store is version 0, will rewrite in version 1
+  Done!
+  $ hg debugobsolete
+  e63c23eaa88ae77967edcf4ea194d31167c478b0 b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 0 (*) {'user': 'test'} (glob)
+  a5b276878fa564da042b4b9efef3713ceea20350 0 {e63c23eaa88ae77967edcf4ea194d31167c478b0} (*) {'user': 'test'} (glob)
+  b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34 384fc811182687231962e486f23ea8c5bab7a2d3 0 (*) {'user': 'test'} (glob)
+  2291082406feb57d0f83b9b0a6777b6074f3fde6 0 {b81ac6b9d2a55f9a7a6b90a006b1aab0568d6d34} (*) {'user': 'test'} (glob)
+  384fc811182687231962e486f23ea8c5bab7a2d3 949d379b3c3bf051906bc3528c049cb536e2ec86 0 (*) {'user': 'test'} (glob)
+  1616bdbe82d3fd1fb7c4e068aee277835672ffdc 0 {384fc811182687231962e486f23ea8c5bab7a2d3} (*) {'user': 'test'} (glob)
+  949d379b3c3bf051906bc3528c049cb536e2ec86 f2e4c45b2a4a58ccf7ef6825b8fa5685873cd2f7 0 (*) {'user': 'test'} (glob)
+  8668d55aac650158bb510be6d47d21e3db9e5c75 0 {949d379b3c3bf051906bc3528c049cb536e2ec86} (*) {'user': 'test'} (glob)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-obsolete-push.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,46 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ template='{rev}:{node|short}@{branch}({separate("/", obsolete, phase)}) {desc|firstline}\n'
+  $ glog() {
+  >   hg glog --template "$template" "$@"
+  > }
+
+Test outgoing, common A is suspended, B unstable and C secret, remote
+has A and B, neither A or C should be in outgoing.
+
+  $ hg init source
+  $ cd source
+  $ echo a > a
+  $ hg ci -qAm A a
+  $ echo b > b
+  $ hg ci -qAm B b
+  $ hg up 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo c > c
+  $ hg ci -qAm C c
+  $ hg phase --secret --force .
+  $ hg prune 0 1
+  2 changesets pruned
+  1 new unstable changesets
+  $ glog --hidden
+  @  2:244232c2222a@default(secret) C
+  |
+  | x  1:6c81ed0049f8@default(obsolete/draft) B
+  |/
+  x  0:1994f17a630e@default(obsolete/draft) A
+  
+  $ hg init ../clone
+  $ cat >  ../clone/.hg/hgrc <<EOF
+  > [phases]
+  > publish = false
+  > EOF
+  $ hg outgoing ../clone --template "$template"
+  comparing with ../clone
+  searching for changes
+  0:1994f17a630e@default(obsolete/draft) A
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-obsolete.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,843 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish=False
+  > [alias]
+  > debugobsolete=debugobsolete -d '0 0'
+  > [extensions]
+  > hgext.rebase=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+  $ getid() {
+  >    hg id --hidden --debug -ir "$1"
+  > }
+
+  $ alias qlog="hg log --template='{rev}\n- {node|short}\n'"
+  $ hg init local
+  $ cd local
+  $ mkcommit a # 0
+  $ hg phase -p .
+  $ mkcommit b # 1
+  $ mkcommit c # 2
+  $ hg up 1
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit obsol_c # 3
+  created new head
+  $ getid 2
+  4538525df7e2b9f09423636c61ef63a4cb872a2d
+  $ getid 3
+  0d3f46688ccc6e756c7e96cf64c391c411309597
+  $ hg debugobsolete 4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597
+  $ hg debugobsolete
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+
+Test hidden() revset
+
+  $ qlog -r 'hidden()' --hidden
+  2
+  - 4538525df7e2
+
+Test that obsolete changeset are hidden
+
+  $ qlog
+  3
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ qlog --hidden
+  3
+  - 0d3f46688ccc
+  2
+  - 4538525df7e2
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ qlog -r 'obsolete()' --hidden
+  2
+  - 4538525df7e2
+
+Test that obsolete precursors are properly computed
+
+  $ qlog -r 'precursors(.)' --hidden
+  2
+  - 4538525df7e2
+  $ qlog -r .
+  3
+  - 0d3f46688ccc
+  $ hg odiff
+  diff -r 4538525df7e2 -r 0d3f46688ccc c
+  --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +0,0 @@
+  -c
+  diff -r 4538525df7e2 -r 0d3f46688ccc obsol_c
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/obsol_c	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +obsol_c
+
+Test that obsolete successors are properly computed
+
+  $ qlog -r 'successors(2)' --hidden
+  3
+  - 0d3f46688ccc
+
+test obsolete changeset with non-obsolete descendant
+  $ hg up 1 -q
+  $ mkcommit "obsol_c'" # 4 (on 1)
+  created new head
+  $ hg debugobsolete `getid 3` `getid 4`
+  $ qlog
+  4
+  - 725c380fe99b
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ qlog -r 'obsolete()' --hidden
+  2
+  - 4538525df7e2
+  3
+  - 0d3f46688ccc
+  $ qlog -r 'allprecursors(4)' --hidden
+  2
+  - 4538525df7e2
+  3
+  - 0d3f46688ccc
+  $ qlog -r 'allsuccessors(2)' --hidden
+  3
+  - 0d3f46688ccc
+  4
+  - 725c380fe99b
+  $ hg up --hidden 3 -q
+  working directory parent is obsolete!
+(reported by parents too)
+  $ hg parents
+  changeset:   3:0d3f46688ccc
+  parent:      1:7c3bad9141dc
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     add obsol_c
+  
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ mkcommit d # 5 (on 3)
+  1 new unstable changesets
+  $ qlog -r 'obsolete()'
+  3
+  - 0d3f46688ccc
+
+  $ qlog -r 'extinct()' --hidden
+  2
+  - 4538525df7e2
+  $ qlog -r 'suspended()'
+  3
+  - 0d3f46688ccc
+  $ qlog -r 'unstable()'
+  5
+  - a7a6f2b5d8a5
+
+Test obsolete keyword
+
+  $ hg --hidden log -G \
+  >  --template '{rev}:{node|short}@{branch}({separate("/", obsolete, phase)}) {desc|firstline}\n'
+  @  5:a7a6f2b5d8a5@default(draft) add d
+  |
+  | o  4:725c380fe99b@default(draft) add obsol_c'
+  | |
+  x |  3:0d3f46688ccc@default(obsolete/draft) add obsol_c
+  |/
+  | x  2:4538525df7e2@default(obsolete/draft) add c
+  |/
+  o  1:7c3bad9141dc@default(draft) add b
+  |
+  o  0:1f0dee641bb7@default(public) add a
+  
+
+Test communication of obsolete relation with a compatible client
+
+  $ hg init ../other-new
+  $ hg phase --draft 'secret() - extinct()' # until we fix exclusion
+  abort: empty revision set
+  [255]
+  $ hg push ../other-new
+  pushing to ../other-new
+  searching for changes
+  abort: push includes unstable changeset: a7a6f2b5d8a5!
+  (use 'hg evolve' to get a stable history or --force to ignore warnings)
+  [255]
+  $ hg push -f ../other-new
+  pushing to ../other-new
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 5 changesets with 5 changes to 5 files (+1 heads)
+  2 new obsolescence markers
+  $ hg -R ../other-new verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  5 files, 5 changesets, 5 total revisions
+  $ qlog -R ../other-new -r 'obsolete()'
+  2
+  - 0d3f46688ccc
+  $ qlog -R ../other-new
+  4
+  - a7a6f2b5d8a5
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ hg up --hidden 3 -q
+  working directory parent is obsolete!
+  $ mkcommit obsol_d # 6
+  created new head
+  1 new unstable changesets
+  $ hg debugobsolete `getid 5` `getid 6`
+  $ qlog
+  6
+  - 95de7fc6918d
+  4
+  - 725c380fe99b
+  3
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ qlog -r 'obsolete()'
+  3
+  - 0d3f46688ccc
+  $ hg push ../other-new
+  pushing to ../other-new
+  searching for changes
+  abort: push includes unstable changeset: 95de7fc6918d!
+  (use 'hg evolve' to get a stable history or --force to ignore warnings)
+  [255]
+  $ hg push ../other-new -f # use f because there is unstability
+  pushing to ../other-new
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  1 new obsolescence markers
+  $ qlog -R ../other-new
+  5
+  - 95de7fc6918d
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ qlog -R ../other-new -r 'obsolete()'
+  2
+  - 0d3f46688ccc
+
+Pushing again does not advertise extinct changesets
+
+  $ hg push ../other-new
+  pushing to ../other-new
+  searching for changes
+  no changes found
+  [1]
+
+  $ hg up --hidden -q .^ # 3
+  working directory parent is obsolete!
+  $ mkcommit "obsol_d'" # 7
+  created new head
+  1 new unstable changesets
+  $ hg debugobsolete `getid 6` `getid 7`
+  $ hg pull -R ../other-new .
+  pulling from .
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  1 new obsolescence markers
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
+  $ qlog -R ../other-new
+  6
+  - 909a0fb57e5d
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+
+pushing to stuff that doesn't support obsolescence
+
+DISABLED. the _enable switch is global :-/
+
+..  $ hg init ../other-old
+..  > # XXX I don't like this but changeset get published otherwise
+..  > # remove it when we will get a --keep-state flag for push
+..  $ echo '[extensions]'  > ../other-old/.hg/hgrc
+..  $ echo "obsolete=!$(echo $(dirname $TESTDIR))/obsolete.py" >> ../other-old/.hg/hgrc
+..  $ hg push ../other-old
+..  pushing to ../other-old
+..  searching for changes
+..  abort: push includes an unstable changeset: 909a0fb57e5d!
+..  (use 'hg evolve' to get a stable history or --force to ignore warnings)
+..  [255]
+..  $ hg push -f ../other-old
+..  pushing to ../other-old
+..  searching for changes
+..  adding changesets
+..  adding manifests
+..  adding file changes
+..  added 5 changesets with 5 changes to 5 files (+1 heads)
+..  $ qlog -R ../other-ol
+..  4
+..  - 909a0fb57e5d
+..  3
+..  - 725c380fe99b
+..  2
+..  - 0d3f46688ccc
+..  1
+..  - 7c3bad9141dc
+..  0
+..  - 1f0dee641bb7
+
+clone support
+
+  $ hg clone . ../cloned
+  > # The warning should go away once we have default value to set ready before we pull
+  updating to branch default
+  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ qlog -R ../cloned --hidden
+  7
+  - 909a0fb57e5d
+  6
+  - 95de7fc6918d
+  5
+  - a7a6f2b5d8a5
+  4
+  - 725c380fe99b
+  3
+  - 0d3f46688ccc
+  2
+  - 4538525df7e2
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+
+Test rollback support
+
+  $ hg up --hidden .^ -q # 3
+  working directory parent is obsolete!
+  $ mkcommit "obsol_d''"
+  created new head
+  1 new unstable changesets
+  $ hg debugobsolete `getid 7` `getid 8`
+  $ cd ../other-new
+  $ hg up -q 3
+  $ hg pull ../local/
+  pulling from ../local/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  1 new obsolescence markers
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
+
+  $ hg up -q 7 # to check rollback update behavior
+  $ qlog
+  7
+  - 159dfc9fa5d3
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ hg rollback
+  repository tip rolled back to revision 6 (undo pull)
+  working directory now based on revision 3
+  $ hg summary
+  parent: 3:725c380fe99b 
+   add obsol_c'
+  branch: default
+  commit: 1 deleted, 2 unknown (clean)
+  update: 2 new changesets, 2 branch heads (merge)
+  phases: 4 draft
+  unstable: 1 changesets
+  $ qlog
+  6
+  - 909a0fb57e5d
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ cd ../local
+
+obsolete public changeset
+
+# move draft boundary from 0 to 1
+  $ sed -e 's/1f0dee641bb7258c56bd60e93edfa2405381c41e/7c3bad9141dcb46ff89abf5f61856facd56e476c/' -i'.back' .hg/store/phaseroots
+
+  $ hg up null
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ mkcommit toto # 9
+  created new head
+  $ hg id -n
+  9
+  $ hg debugobsolete `getid 0` `getid 9`
+83b5778897ad try to obsolete immutable changeset 1f0dee641bb7
+# at core level the warning is not issued
+# this is now a big issue now that we have bumped warning
+  $ qlog -r 'obsolete()'
+  3
+  - 0d3f46688ccc
+allow to just kill changeset
+
+  $ qlog
+  9
+  - 83b5778897ad
+  8
+  - 159dfc9fa5d3
+  4
+  - 725c380fe99b
+  3
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+
+  $ hg debugobsolete `getid 9` #kill
+  $ hg up null -q # to be not based on 9 anymore
+  $ qlog
+  8
+  - 159dfc9fa5d3
+  4
+  - 725c380fe99b
+  3
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+
+Check that auto update ignores hidden changeset
+  $ hg up 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg up 
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
+  $ hg id -n
+  8
+
+Check that named update does too
+
+  $ hg update default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg id -n
+  8
+
+  $ hg up null -q # to be not based on 9 anymore
+
+check rebase compat
+
+  $ hg log -G  --template='{rev} - {node|short} {desc}\n'
+  o  8 - 159dfc9fa5d3 add obsol_d''
+  |
+  | o  4 - 725c380fe99b add obsol_c'
+  | |
+  x |  3 - 0d3f46688ccc add obsol_c
+  |/
+  o  1 - 7c3bad9141dc add b
+  |
+  o  0 - 1f0dee641bb7 add a
+  
+
+  $ hg log -G  --template='{rev} - {node|short} {desc}\n' --hidden
+  x  9 - 83b5778897ad add toto
+  
+  o  8 - 159dfc9fa5d3 add obsol_d''
+  |
+  | x  7 - 909a0fb57e5d add obsol_d'
+  |/
+  | x  6 - 95de7fc6918d add obsol_d
+  |/
+  | x  5 - a7a6f2b5d8a5 add d
+  |/
+  | o  4 - 725c380fe99b add obsol_c'
+  | |
+  x |  3 - 0d3f46688ccc add obsol_c
+  |/
+  | x  2 - 4538525df7e2 add c
+  |/
+  o  1 - 7c3bad9141dc add b
+  |
+  o  0 - 1f0dee641bb7 add a
+  
+
+should not rebase extinct changesets
+
+#excluded 'whole rebase set is extinct and ignored.' message not in core
+  $ hg rebase -b '3' -d 4 --traceback --config experimental.rebaseskipobsolete=0
+  rebasing 3:0d3f46688ccc "add obsol_c"
+  rebasing 8:159dfc9fa5d3 "add obsol_d''" (tip)
+  2 new divergent changesets
+  $ hg --hidden log -q -r 'successors(3)'
+  4:725c380fe99b
+  10:2033b4e49474
+  $ hg up tip
+  ? files updated, 0 files merged, 0 files removed, 0 files unresolved (glob)
+  $ hg log -G --template='{rev} - {node|short} {desc}\n'
+  @  11 - 9468a5f5d8b2 add obsol_d''
+  |
+  o  10 - 2033b4e49474 add obsol_c
+  |
+  o  4 - 725c380fe99b add obsol_c'
+  |
+  o  1 - 7c3bad9141dc add b
+  |
+  o  0 - 1f0dee641bb7 add a
+  
+
+Does not complain about new head if you obsolete the old one
+(re necessary when we start running discovery on unfiltered repo in core)
+
+  $ hg push ../other-new --traceback
+  pushing to ../other-new
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to [12] files (re)
+  3 new obsolescence markers
+  $ hg up -q 10
+  $ mkcommit "obsol_d'''"
+  created new head
+  $ hg debugobsolete `getid 11` `getid 12`
+  $ hg push ../other-new --traceback
+  pushing to ../other-new
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  1 new obsolescence markers
+  $ cd ..
+
+check bumped detection
+(make an obsolete changeset public)
+
+  $ cd local
+  $ hg phase --hidden --public 11
+  1 new bumped changesets
+  $ hg log -G --template='{rev} - ({phase}) {node|short} {desc}\n'
+  @  12 - (draft) 6db5e282cb91 add obsol_d'''
+  |
+  | o  11 - (public) 9468a5f5d8b2 add obsol_d''
+  |/
+  o  10 - (public) 2033b4e49474 add obsol_c
+  |
+  o  4 - (public) 725c380fe99b add obsol_c'
+  |
+  o  1 - (public) 7c3bad9141dc add b
+  |
+  o  0 - (public) 1f0dee641bb7 add a
+  
+  $ hg log -r 'bumped()'
+  changeset:   12:6db5e282cb91
+  tag:         tip
+  parent:      10:2033b4e49474
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  trouble:     bumped
+  summary:     add obsol_d'''
+  
+  $ hg push ../other-new/
+  pushing to ../other-new/
+  searching for changes
+  abort: push includes bumped changeset: 6db5e282cb91!
+  (use 'hg evolve' to get a stable history or --force to ignore warnings)
+  [255]
+
+Check hg commit --amend compat
+
+  $ hg up 'desc(obsol_c)'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit f
+  created new head
+  $ echo 42 >> f
+  $ hg commit --amend --traceback --quiet
+  $ hg log -G
+  @  changeset:   15:705ab2a6b72e
+  |  tag:         tip
+  |  parent:      10:2033b4e49474
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add f
+  |
+  | o  changeset:   12:6db5e282cb91
+  |/   parent:      10:2033b4e49474
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    trouble:     bumped
+  |    summary:     add obsol_d'''
+  |
+  | o  changeset:   11:9468a5f5d8b2
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     add obsol_d''
+  |
+  o  changeset:   10:2033b4e49474
+  |  parent:      4:725c380fe99b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add obsol_c
+  |
+  o  changeset:   4:725c380fe99b
+  |  parent:      1:7c3bad9141dc
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add obsol_c'
+  |
+  o  changeset:   1:7c3bad9141dc
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add b
+  |
+  o  changeset:   0:1f0dee641bb7
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add a
+  
+  $ hg debugobsolete | grep -v 33d458d86621f3186c40bfccd77652f4a122743e
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  0d3f46688ccc6e756c7e96cf64c391c411309597 725c380fe99b5e76613493f0903e8d11ddc70d54 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 95de7fc6918dea4c9c8d5382f50649794b474c4a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  95de7fc6918dea4c9c8d5382f50649794b474c4a 909a0fb57e5d909f353d89e394ffd7e0890fec88 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  909a0fb57e5d909f353d89e394ffd7e0890fec88 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  1f0dee641bb7258c56bd60e93edfa2405381c41e 83b5778897adafb967ef2f75be3aaa4fce49a4cc 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  83b5778897adafb967ef2f75be3aaa4fce49a4cc 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  0d3f46688ccc6e756c7e96cf64c391c411309597 2033b4e494742365851fac84d276640cbf52833e 0 (*) {'user': 'test'} (glob)
+  159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 9468a5f5d8b2c5d91e17474e95ae4791e9718fdf 0 (*) {'user': 'test'} (glob)
+  9468a5f5d8b2c5d91e17474e95ae4791e9718fdf 6db5e282cb91df5c43ff1f1287c119ff83230d42 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  0b1b6dd009c037985363e2290a0b579819f659db 705ab2a6b72e2cd86edb799ebe15f2695f86143e 0 (*) {'user': 'test'} (glob)
+#no produced by 2.3
+33d458d86621f3186c40bfccd77652f4a122743e 3734a65252e69ddcced85901647a4f335d40de1e 0 {'date': '* *', 'user': 'test'} (glob)
+
+Check divergence detection (note: multiple successors is sorted by changeset hash)
+
+  $ hg up 9468a5f5d8b2 #  add obsol_d''
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit "obsolet_conflicting_d"
+  $ hg summary
+  parent: 1[46]:50f11e5e3a63 tip (re)
+   add obsolet_conflicting_d
+  branch: default
+  commit: (clean)
+  update: (2|9|11) new changesets, (3|9|10) branch heads \(merge\) (re)
+  phases: 3 draft
+  bumped: 1 changesets
+  $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63`
+  $ hg log -r 'divergent()'
+  changeset:   12:6db5e282cb91
+  parent:      10:2033b4e49474
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  trouble:     bumped, divergent
+  summary:     add obsol_d'''
+  
+  changeset:   16:50f11e5e3a63
+  tag:         tip
+  parent:      11:9468a5f5d8b2
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  trouble:     divergent
+  summary:     add obsolet_conflicting_d
+  
+
+  $ hg up --hidden 3 -q
+  working directory parent is obsolete!
+  $ hg evolve
+  parent is obsolete with multiple successors:
+  [4] add obsol_c'
+  [10] add obsol_c
+  [2]
+  $ hg olog
+  changeset:   2:4538525df7e2
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     add c
+  
+
+Check import reports new unstable changeset:
+
+  $ hg up --hidden 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ hg export 9468a5f5d8b2 | hg import -
+  applying patch from stdin
+  1 new unstable changesets
+
+
+Relevant marker computation
+==============================
+
+  $ hg log -G --hidden
+  @  changeset:   17:a5f7a21fe7bc
+  |  tag:         tip
+  |  parent:      2:4538525df7e2
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  trouble:     unstable
+  |  summary:     add obsol_d''
+  |
+  | o  changeset:   16:50f11e5e3a63
+  | |  parent:      11:9468a5f5d8b2
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  trouble:     divergent
+  | |  summary:     add obsolet_conflicting_d
+  | |
+  | | o  changeset:   15:705ab2a6b72e
+  | | |  parent:      10:2033b4e49474
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |  summary:     add f
+  | | |
+  | | | x  changeset:   14:33d458d86621
+  | | | |  user:        test
+  | | | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | | | |  summary:     temporary amend commit for 0b1b6dd009c0
+  | | | |
+  | | | x  changeset:   13:0b1b6dd009c0
+  | | |/   parent:      10:2033b4e49474
+  | | |    user:        test
+  | | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |    summary:     add f
+  | | |
+  | | | o  changeset:   12:6db5e282cb91
+  | | |/   parent:      10:2033b4e49474
+  | | |    user:        test
+  | | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |    trouble:     bumped, divergent
+  | | |    summary:     add obsol_d'''
+  | | |
+  | o |  changeset:   11:9468a5f5d8b2
+  | |/   user:        test
+  | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | |    summary:     add obsol_d''
+  | |
+  | o  changeset:   10:2033b4e49474
+  | |  parent:      4:725c380fe99b
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     add obsol_c
+  | |
+  | | x  changeset:   9:83b5778897ad
+  | |    parent:      -1:000000000000
+  | |    user:        test
+  | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | |    summary:     add toto
+  | |
+  | | x  changeset:   8:159dfc9fa5d3
+  | | |  parent:      3:0d3f46688ccc
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |  summary:     add obsol_d''
+  | | |
+  | | | x  changeset:   7:909a0fb57e5d
+  | | |/   parent:      3:0d3f46688ccc
+  | | |    user:        test
+  | | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |    summary:     add obsol_d'
+  | | |
+  | | | x  changeset:   6:95de7fc6918d
+  | | |/   parent:      3:0d3f46688ccc
+  | | |    user:        test
+  | | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |    summary:     add obsol_d
+  | | |
+  | | | x  changeset:   5:a7a6f2b5d8a5
+  | | |/   parent:      3:0d3f46688ccc
+  | | |    user:        test
+  | | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |    summary:     add d
+  | | |
+  | o |  changeset:   4:725c380fe99b
+  | | |  parent:      1:7c3bad9141dc
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | | |  summary:     add obsol_c'
+  | | |
+  | | x  changeset:   3:0d3f46688ccc
+  | |/   parent:      1:7c3bad9141dc
+  | |    user:        test
+  | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | |    summary:     add obsol_c
+  | |
+  x |  changeset:   2:4538525df7e2
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     add c
+  |
+  o  changeset:   1:7c3bad9141dc
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add b
+  |
+  o  changeset:   0:1f0dee641bb7
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add a
+  
+
+Simple rewrite
+
+  $ hg  --hidden debugobsolete --rev 3
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+simple rewrite with a prune attached to it
+
+  $ hg debugobsolete --rev 15
+  0b1b6dd009c037985363e2290a0b579819f659db 705ab2a6b72e2cd86edb799ebe15f2695f86143e 0 (*) {'user': 'test'} (glob)
+  33d458d86621f3186c40bfccd77652f4a122743e 0 {0b1b6dd009c037985363e2290a0b579819f659db} (*) {'user': 'test'} (glob)
+
+Transitive rewrite
+
+  $ hg --hidden debugobsolete --rev 8
+  909a0fb57e5d909f353d89e394ffd7e0890fec88 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  95de7fc6918dea4c9c8d5382f50649794b474c4a 909a0fb57e5d909f353d89e394ffd7e0890fec88 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 95de7fc6918dea4c9c8d5382f50649794b474c4a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-oldconvert.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,114 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish=False
+  > [alias]
+  > odiff=diff --rev 'limit(obsparents(.),1)' --rev .
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+create commit
+
+  $ hg init repo
+  $ cd repo
+  $ mkcommit a
+  $ mkcommit b
+  $ hg up -q 0
+  $ mkcommit c
+  created new head
+
+forge old style relation files
+
+  $ hg log -r 2 --template='{node} ' > .hg/obsolete-relations
+  $ hg log -r 1 --template='{node}' >> .hg/obsolete-relations
+
+enable the extensions
+
+  $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/legacy.py" >> $HGRCPATH
+
+  $ hg glog
+  abort: old format of obsolete marker detected!
+  run `hg debugconvertobsolete` once.
+  [255]
+  $ hg debugconvertobsolete --traceback
+  1 obsolete marker converted
+  $ hg glog
+  @  changeset:   2:d67cd0334eee
+  |  tag:         tip
+  |  parent:      0:1f0dee641bb7
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add c
+  |
+  o  changeset:   0:1f0dee641bb7
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add a
+  
+  $ hg debugobsolete
+  7c3bad9141dcb46ff89abf5f61856facd56e476c d67cd0334eeecfded222fed9009f0db4beb57585 0 (*) {'user': 'test'} (glob)
+  $ hg debugconvertobsolete
+  nothing to do
+  0 obsolete marker converted
+
+Convert json
+
+  $ cat > .hg/store/obsoletemarkers << EOF
+  > [
+  >     {
+  >         "reason": "import from older format.", 
+  >         "subjects": [
+  >             "3218406b50ed13480765e7c260669620f37fba6e"
+  >         ], 
+  >         "user": "Pierre-Yves David <pierre-yves.david@ens-lyon.org>", 
+  >         "date": [
+  >             1336503323.9768269, 
+  >             -7200
+  >         ], 
+  >         "object": "3e03d82708d4da97a92158558dd13386d8f09ad5", 
+  >         "id": "4743f676eaf3923cb98c921ee06b2e91052c365b"
+  >     }, 
+  >     {
+  >         "reason": "import from older format.", 
+  >         "user": "Pierre-Yves David <pierre-yves.david@logilab.fr>", 
+  >         "date": [
+  >             1336557472.7875929, 
+  >             -7200
+  >         ], 
+  >         "object": "5c722672795c3a2cb94d0cc9a821c394c1475f87", 
+  >         "id": "1fd90a84b7225d2e3062b7e1b3100aa2e060fc72"
+  >     }, 
+  >     {
+  >         "reason": "import from older format.", 
+  >         "subjects": [
+  >             "0000000000000000000000000000000000000000"
+  >         ], 
+  >         "user": "Pierre-Yves David <pierre-yves.david@logilab.fr>", 
+  >         "date": [
+  >             1336557472.784307, 
+  >             -7200
+  >         ], 
+  >         "object": "2c3784e102bb34ccc93862af5bd6d609ee30c577", 
+  >         "id": "7d940c5ee1f886c8a6c0d805b43e522cb3ef7a15"
+  >     }
+  > ]
+  > EOF
+  $ hg glog
+  abort: old format of obsolete marker detected!
+  run `hg debugconvertobsolete` once.
+  [255]
+  $ hg debugconvertobsolete --traceback
+  3 obsolete marker converted
+  $ hg debugobsolete
+  7c3bad9141dcb46ff89abf5f61856facd56e476c d67cd0334eeecfded222fed9009f0db4beb57585 0 (*) {'user': 'test'} (glob)
+  3e03d82708d4da97a92158558dd13386d8f09ad5 3218406b50ed13480765e7c260669620f37fba6e 0 (Tue May 08 20:55:23 2012 +0200) {'user': 'Pierre-Yves David <pierre-yves.david@ens-lyon.org>'}
+  5c722672795c3a2cb94d0cc9a821c394c1475f87 0 (Wed May 09 11:57:52 2012 +0200) {'user': 'Pierre-Yves David <pierre-yves.david@logilab.fr>'}
+  2c3784e102bb34ccc93862af5bd6d609ee30c577 0 (Wed May 09 11:57:52 2012 +0200) {'user': 'Pierre-Yves David <pierre-yves.david@logilab.fr>'}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-options.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,30 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > logtemplate={rev}:{node|short}[{bookmarks}] ({obsolete}/{phase}) {desc|firstline}\n
+  > [extensions]
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ hg init repo
+  $ cd repo
+  $ mkcommit a
+  $ mkcommit b
+
+test disabling commands
+
+  $ cat >> .hg/hgrc <<EOF
+  > [experimental]
+  > evolution=createmarkers
+  >   allowunstable
+  >   exchange
+  > EOF
+  $ hg prune | head -n 2
+  hg: unknown command 'prune'
+  Mercurial Distributed SCM
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-prev-next.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,239 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+hg prev -B should move active bookmark
+  $ hg init
+  $ touch a
+  $ hg add a
+  $ hg commit -m 'added a'
+  $ touch b
+  $ hg add b
+  $ hg commit -m 'added b'
+  $ hg bookmark mark
+  $ hg bookmarks
+   * mark                      1:6e742c9127b3
+  $ hg prev -B
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [0] added a
+  $ hg bookmarks
+   * mark                      0:a154386e50d1
+
+hg next -B should move active bookmark
+  $ hg next -B --dry-run
+  hg update 1;
+  hg bookmark mark -r 1;
+  [1] added b
+  $ hg next -B
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+   * mark                      1:6e742c9127b3
+
+hg prev should unset active bookmark
+  $ hg prev --dry-run
+  hg update 0;
+  [0] added a
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [0] added a
+  $ hg bookmarks
+     mark                      1:6e742c9127b3
+
+hg next should move active bookmark
+  $ hg bookmark mark2
+  $ hg bookmarks
+     mark                      1:6e742c9127b3
+   * mark2                     0:a154386e50d1
+  $ hg next
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+     mark                      1:6e742c9127b3
+     mark2                     0:a154386e50d1
+
+  $ hg bookmark -d mark2
+  $ hg bookmark mark
+
+hg next/prev should not interfere with inactive bookmarks
+  $ touch c
+  $ hg add c
+  $ hg commit -m 'added c'
+  $ hg bookmark -r2 no-move
+  $ hg prev -B
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+   * mark                      1:6e742c9127b3
+     no-move                   2:4e26ef31f919
+  $ hg next -B
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [2] added c
+  $ hg bookmarks
+   * mark                      2:4e26ef31f919
+     no-move                   2:4e26ef31f919
+  $ hg up 1
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (leaving bookmark mark)
+  $ hg next -B
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [2] added c
+  $ hg bookmarks
+     mark                      2:4e26ef31f919
+     no-move                   2:4e26ef31f919
+  $ hg prev -B
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+     mark                      2:4e26ef31f919
+     no-move                   2:4e26ef31f919
+
+
+Behavior with local modification
+--------------------------------
+
+  $ echo foo > modified-bar
+  $ hg add modified-bar
+  $ hg prev
+  abort: uncommitted changes
+  (do you want --merge?)
+  [255]
+  $ hg prev --merge
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [0] added a
+  $ hg next
+  abort: uncommitted changes
+  (do you want --merge?)
+  [255]
+  $ hg next --merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [1] added b
+
+Behavior with aspiring children
+-------------------------------
+
+  $ hg revert --all
+  forgetting modified-bar
+  $ hg log -G
+  o  changeset:   2:4e26ef31f919
+  |  bookmark:    mark
+  |  bookmark:    no-move
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     added c
+  |
+  @  changeset:   1:6e742c9127b3
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     added b
+  |
+  o  changeset:   0:a154386e50d1
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     added a
+  
+
+no children of any kind
+
+  $ hg next
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [2] added c
+  $ hg next
+  no children
+  [1]
+  $ hg next --evolve
+  no children
+  [1]
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] added b
+
+some aspiring children
+
+  $ hg amend -m 'added b (2)'
+  1 new unstable changesets
+  $ hg next
+  no children
+  (1 unstable changesets to be evolved here, do you want --evolve?)
+  [1]
+  $ hg next --evolve --dry-run
+  move:[2] added c
+  atop:[3] added b (2)
+  hg rebase -r 4e26ef31f919 -d 9ad178109a19
+  working directory now at 9ad178109a19
+  $ hg next --evolve
+  move:[2] added c
+  atop:[3] added b (2)
+  working directory now at e3b6d5df389b
+
+next with ambiguity
+
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [3] added b (2)
+  $ echo d > d
+  $ hg add d
+  $ hg commit -m 'added d'
+  created new head
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [3] added b (2)
+  $ hg next
+  ambigious next changeset:
+  [4] added c
+  [5] added d
+  explicitly update to one of them
+  [1]
+
+next with ambiguity in aspiring children
+
+  $ hg am -m 'added b (3)'
+  2 new unstable changesets
+  $ hg next
+  no children
+  (2 unstable changesets to be evolved here, do you want --evolve?)
+  [1]
+  $ hg next --evolve
+  ambigious next (unstable) changeset:
+  [4] added c
+  [5] added d
+  (run 'hg evolve --rev REV' on one of them)
+  [1]
+  $ hg evolve -r 5
+  move:[5] added d
+  atop:[6] added b (3)
+  working directory is now at 47ea25be8aea
+
+prev and next should lock properly against other commands
+
+  $ hg init repo
+  $ cd repo
+  $ HGEDITOR=${TESTDIR}/fake-editor.sh
+  $ echo hi > foo
+  $ hg ci -Am 'one'
+  adding foo
+  $ echo bye > foo
+  $ hg ci -Am 'two'
+
+  $ hg amend --edit &
+  $ sleep 1
+  $ hg prev
+  waiting for lock on working directory of $TESTTMP/repo held by process '*' on host '*' (glob)
+  got lock after [4-6] seconds (re)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [0] one
+  $ wait
+
+  $ hg amend --edit &
+  $ sleep 1
+  $ hg next --evolve
+  waiting for lock on working directory of $TESTTMP/repo held by process '*' on host '*' (glob)
+  1 new unstable changesets
+  got lock after [4-6] seconds (re)
+  move:[2] two
+  atop:[3] one
+  working directory now at a7d885c75614
+  $ wait
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-prune.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,435 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > logtemplate={rev}:{node|short}[{bookmarks}] ({separate('/', obsolete ,phase)}) {desc|firstline}\n
+  > [extensions]
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ hg init repo
+  $ cd repo
+  $ mkcommit a
+  $ hg phase --public .
+  $ mkcommit b
+  $ mkcommit c
+  $ mkcommit d
+  $ mkcommit e
+  $ hg bookmarks BABAR
+  $ hg log -G
+  @  4:9d206ffc875e[BABAR] (draft) add e
+  |
+  o  3:47d2a3944de8[] (draft) add d
+  |
+  o  2:4538525df7e2[] (draft) add c
+  |
+  o  1:7c3bad9141dc[] (draft) add b
+  |
+  o  0:1f0dee641bb7[] (public) add a
+  
+
+Check arguments exclusive to each other
+---------------------------------------
+
+  $ hg prune --fold --biject
+  abort: can only specify one of biject, fold
+  [255]
+  $ hg prune --split --fold
+  abort: can only specify one of fold, split
+  [255]
+  $ hg prune --split --fold --biject
+  abort: can only specify one of biject, fold, split
+  [255]
+
+Check simple case
+----------------------------
+
+prune current and tip changeset
+
+  $ hg prune --user blah --date '1979-12-15' .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at 47d2a3944de8
+  1 changesets pruned
+  $ hg bookmark
+   * BABAR                     3:47d2a3944de8
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+
+prune leaving instability behind
+
+  $ hg prune 1
+  1 changesets pruned
+  2 new unstable changesets
+  $ hg book -i BABAR
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+
+pruning multiple changeset at once
+
+  $ hg prune 2:
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  working directory now at 1f0dee641bb7
+  2 changesets pruned
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+
+cannot prune public changesets
+
+  $ hg prune 0
+  abort: cannot prune immutable changeset: 1f0dee641bb7
+  (see 'hg help phases' for details)
+  [255]
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+
+Check successors addition
+----------------------------
+
+  $ mkcommit bb
+  $ mkcommit cc
+  $ mkcommit dd
+  $ mkcommit ee
+  $ hg up 0
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ mkcommit nB
+  created new head
+  $ mkcommit nC
+  $ mkcommit nD
+  $ mkcommit nE
+
+  $ hg log -G
+  @  12:6e8148413dd5[] (draft) add nE
+  |
+  o  11:8ee176ff1d4b[] (draft) add nD
+  |
+  o  10:aa96dc3f04c2[] (draft) add nC
+  |
+  o  9:6f6f25e4f748[] (draft) add nB
+  |
+  | o  8:bb5e90a7ea1f[] (draft) add ee
+  | |
+  | o  7:00ded550b1e2[] (draft) add dd
+  | |
+  | o  6:354011cd103f[] (draft) add cc
+  | |
+  | o  5:814c38b95e72[] (draft) add bb
+  |/
+  o  0:1f0dee641bb7[BABAR] (public) add a
+  
+
+one old, one new
+
+  $ hg up 'desc("add ee")'
+  4 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ hg prune 'desc("add ee")' -s 'desc("add nE")'
+  4 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  working directory now at 6e8148413dd5
+  1 changesets pruned
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+  bb5e90a7ea1f3b4b38b23150a4a597b6146d70ef 6e8148413dd541855b72a920a90c06fca127c7e7 0 (*) {'user': 'test'} (glob)
+  $ hg log -G
+  @  12:6e8148413dd5[] (draft) add nE
+  |
+  o  11:8ee176ff1d4b[] (draft) add nD
+  |
+  o  10:aa96dc3f04c2[] (draft) add nC
+  |
+  o  9:6f6f25e4f748[] (draft) add nB
+  |
+  | o  7:00ded550b1e2[] (draft) add dd
+  | |
+  | o  6:354011cd103f[] (draft) add cc
+  | |
+  | o  5:814c38b95e72[] (draft) add bb
+  |/
+  o  0:1f0dee641bb7[BABAR] (public) add a
+  
+
+one old, two new
+
+  $ hg prune 'desc("add dd")' -s 'desc("add nD")' -s 'desc("add nC")'
+  abort: please add --split if you want to do a split
+  [255]
+  $ hg prune 'desc("add dd")' -s 'desc("add nD")' -s 'desc("add nC")' --split
+  1 changesets pruned
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+  bb5e90a7ea1f3b4b38b23150a4a597b6146d70ef 6e8148413dd541855b72a920a90c06fca127c7e7 0 (*) {'user': 'test'} (glob)
+  00ded550b1e28bba454bd34cec1269d22cf3ef25 aa96dc3f04c2c2341fe6880aeb6dc9fbffff9ef9 8ee176ff1d4b2034ce51e3efc579c2de346b631d 0 (*) {'user': 'test'} (glob)
+  $ hg log -G
+  @  12:6e8148413dd5[] (draft) add nE
+  |
+  o  11:8ee176ff1d4b[] (draft) add nD
+  |
+  o  10:aa96dc3f04c2[] (draft) add nC
+  |
+  o  9:6f6f25e4f748[] (draft) add nB
+  |
+  | o  6:354011cd103f[] (draft) add cc
+  | |
+  | o  5:814c38b95e72[] (draft) add bb
+  |/
+  o  0:1f0dee641bb7[BABAR] (public) add a
+  
+
+two old, two new (should be denied)
+
+  $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nD")' -s 'desc("add nC")'
+  abort: Can't use multiple successors for multiple precursors
+  (use --biject to mark a series as a replacement for another)
+  [255]
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+  bb5e90a7ea1f3b4b38b23150a4a597b6146d70ef 6e8148413dd541855b72a920a90c06fca127c7e7 0 (*) {'user': 'test'} (glob)
+  00ded550b1e28bba454bd34cec1269d22cf3ef25 aa96dc3f04c2c2341fe6880aeb6dc9fbffff9ef9 8ee176ff1d4b2034ce51e3efc579c2de346b631d 0 (*) {'user': 'test'} (glob)
+
+two old, one new:
+
+  $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nB")'
+  abort: please add --fold if you want to do a fold
+  [255]
+  $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nB")' --fold
+  2 changesets pruned
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+  bb5e90a7ea1f3b4b38b23150a4a597b6146d70ef 6e8148413dd541855b72a920a90c06fca127c7e7 0 (*) {'user': 'test'} (glob)
+  00ded550b1e28bba454bd34cec1269d22cf3ef25 aa96dc3f04c2c2341fe6880aeb6dc9fbffff9ef9 8ee176ff1d4b2034ce51e3efc579c2de346b631d 0 (*) {'user': 'test'} (glob)
+  814c38b95e72dfe2cbf675b1649ea9d780c89a80 6f6f25e4f748d8f7571777e6e168aedf50350ce8 0 (*) {'user': 'test'} (glob)
+  354011cd103f58bbbd9091a3cee6d6a6bd0dddf7 6f6f25e4f748d8f7571777e6e168aedf50350ce8 0 (*) {'user': 'test'} (glob)
+
+two old, two new with --biject
+
+  $ hg up 0
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ mkcommit n1
+  created new head
+  $ mkcommit n2
+
+  $ hg prune 'desc("add n1")::desc("add n2")' -s 'desc("add nD")::desc("add nE")' --biject
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  working directory now at 1f0dee641bb7
+  2 changesets pruned
+  $ hg debugobsolete
+  9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
+  7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)
+  4538525df7e2b9f09423636c61ef63a4cb872a2d 0 {7c3bad9141dcb46ff89abf5f61856facd56e476c} (*) {'user': 'test'} (glob)
+  47d2a3944de8b013de3be9578e8e344ea2e6c097 0 {4538525df7e2b9f09423636c61ef63a4cb872a2d} (*) {'user': 'test'} (glob)
+  bb5e90a7ea1f3b4b38b23150a4a597b6146d70ef 6e8148413dd541855b72a920a90c06fca127c7e7 0 (*) {'user': 'test'} (glob)
+  00ded550b1e28bba454bd34cec1269d22cf3ef25 aa96dc3f04c2c2341fe6880aeb6dc9fbffff9ef9 8ee176ff1d4b2034ce51e3efc579c2de346b631d 0 (*) {'user': 'test'} (glob)
+  814c38b95e72dfe2cbf675b1649ea9d780c89a80 6f6f25e4f748d8f7571777e6e168aedf50350ce8 0 (*) {'user': 'test'} (glob)
+  354011cd103f58bbbd9091a3cee6d6a6bd0dddf7 6f6f25e4f748d8f7571777e6e168aedf50350ce8 0 (*) {'user': 'test'} (glob)
+  cb7f8f706a6532967b98cf8583a81baab79a0fa7 8ee176ff1d4b2034ce51e3efc579c2de346b631d 0 (*) {'user': 'test'} (glob)
+  21b6f2f1cece8c10326e575dd38239189d467190 6e8148413dd541855b72a920a90c06fca127c7e7 0 (*) {'user': 'test'} (glob)
+
+test hg strip replacement
+
+  $ hg up 10
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ mkcommit n1
+  created new head
+  $ mkcommit n2
+  $ hg --config extensions.strip= --config experimental.prunestrip=True strip -r .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory now at c7e58696a948
+  1 changesets pruned
+  $ hg --config extensions.strip= --config experimental.prunestrip=True strip -r . --bundle
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/c7e58696a948-69ca36d3-backup.hg (glob)
+
+test hg prune --keep
+  $ mkcommit n1
+  created new head
+  $ hg diff -r .^
+  diff -r aa96dc3f04c2 n1
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/n1	* +0000 (glob)
+  @@ -0,0 +1,1 @@
+  +n1
+  $ hg prune -r . --keep
+  1 changesets pruned
+  $ hg status
+  ? n1
+
+test hg prune -B bookmark
+yoinked from test-mq-strip.t
+
+  $ cd ..
+  $ hg init bookmarks
+  $ cd bookmarks
+  $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
+  $ hg bookmark -r 'a' 'todelete'
+  $ hg bookmark -r 'b' 'B'
+  $ hg bookmark -r 'b' 'nostrip'
+  $ hg bookmark -r 'c' 'delete'
+  $ hg bookmark -r 'd' 'multipledelete1'
+  $ hg bookmark -r 'e' 'multipledelete2'
+  $ hg bookmark -r 'f' 'singlenode1'
+  $ hg bookmark -r 'f' 'singlenode2'
+  $ hg up -C todelete
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark todelete)
+  $ hg prune -B nostrip
+  bookmark 'nostrip' deleted
+  abort: nothing to prune
+  [255]
+  $ hg tag --remove --local a
+  $ hg prune -B todelete
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark todelete)
+  working directory now at d62d843c9a01
+  bookmark 'todelete' deleted
+  1 changesets pruned
+  $ hg id -ir dcbb326fdec2
+  abort: hidden revision 'dcbb326fdec2'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg id -ir d62d843c9a01
+  d62d843c9a01
+  $ hg bookmarks
+     B                         10:ff43616e5d0f
+     delete                    6:2702dd0c91e7
+     multipledelete1           12:e46a4836065c
+     multipledelete2           13:b4594d867745
+     singlenode1               14:43227190fef8
+     singlenode2               14:43227190fef8
+  $ hg prune -B multipledelete1 -B multipledelete2
+  bookmark 'multipledelete1' deleted
+  bookmark 'multipledelete2' deleted
+  2 changesets pruned
+  $ hg prune -B singlenode1 -B singlenode2
+  bookmark 'singlenode1' deleted
+  bookmark 'singlenode2' deleted
+  1 changesets pruned
+  $ hg prune -B unknownbookmark
+  abort: bookmark 'unknownbookmark' not found
+  [255]
+  $ hg prune -B unknownbookmark1 -B unknownbookmark2
+  abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
+  [255]
+  $ hg prune -B delete -B unknownbookmark
+  abort: bookmark 'unknownbookmark' not found
+  [255]
+  $ hg prune -B delete
+  bookmark 'delete' deleted
+  3 changesets pruned
+  $ hg tag --remove --local c
+  $ hg id -ir 6:2702dd0c91e7
+  abort: hidden revision '6'!
+  (use --hidden to access hidden revisions)
+  [255]
+
+  $ hg debugobsstorestat
+  markers total:                      7
+      for known precursors:           7
+      with parents data:              [04] (re)
+  markers with no successors:         7
+                1 successors:         0
+                2 successors:         0
+      more than 2 successors:         0
+      available  keys:
+                 user:                7
+  disconnected clusters:              7
+          any known node:             7
+          smallest length:            1
+          longer length:              1
+          median length:              1
+          mean length:                1
+      using parents data:             7
+          any known node:             7
+          smallest length:            1
+          longer length:              1
+          median length:              1
+          mean length:                1
+
+  $ mkcommit rg
+  created new head
+  $ hg bookmark rg
+  $ hg up 10
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (leaving bookmark rg)
+  $ hg bookmark r10
+  $ hg log -G
+  o  15:cd0038e05e1b[rg] (draft) add rg
+  |
+  | x  14:43227190fef8[] (obsolete/draft) r14
+  | |
+  | | x  13:b4594d867745[] (obsolete/draft) r13
+  | | |
+  | | | x  12:e46a4836065c[] (obsolete/draft) r12
+  | | |/
+  | | o  11:bab5d5bf48bd[] (draft) r11
+  | |/
+  +---@  10:ff43616e5d0f[B r10] (draft) r10
+  | |
+  o |  8:d62d843c9a01[] (draft) r8
+  | |
+  o |  7:e7d9710d9fc6[] (draft) r7
+  |/
+  o    3:2b6d669947cd[] (draft) r3
+  |\
+  | o  2:fa942426a6fd[] (draft) r2
+  | |
+  o |  1:66f7d451a68b[] (draft) r1
+  |/
+  o  0:1ea73414a91b[] (draft) r0
+  
+  $ hg prune 11
+  1 changesets pruned
+  $ hg log -G
+  o  15:cd0038e05e1b[rg] (draft) add rg
+  |
+  | x  14:43227190fef8[] (obsolete/draft) r14
+  | |
+  | | x  13:b4594d867745[] (obsolete/draft) r13
+  | | |
+  | | | x  12:e46a4836065c[] (obsolete/draft) r12
+  | | |/
+  | | x  11:bab5d5bf48bd[] (obsolete/draft) r11
+  | |/
+  +---@  10:ff43616e5d0f[B r10] (draft) r10
+  | |
+  o |  8:d62d843c9a01[] (draft) r8
+  | |
+  o |  7:e7d9710d9fc6[] (draft) r7
+  |/
+  o    3:2b6d669947cd[] (draft) r3
+  |\
+  | o  2:fa942426a6fd[] (draft) r2
+  | |
+  o |  1:66f7d451a68b[] (draft) r1
+  |/
+  o  0:1ea73414a91b[] (draft) r0
+  
+  $ hg book CELESTE
+  $ hg prune -r . --keep
+  1 changesets pruned
+  $ hg book
+     B                         8:d62d843c9a01
+   * CELESTE                   8:d62d843c9a01
+     r10                       8:d62d843c9a01
+     rg                        15:cd0038e05e1b
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-sharing.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,540 @@
+Test script based on sharing.rst: ensure that all scenarios in that
+document work as advertised.
+
+Setting things up
+
+  $ cat >> $HGRCPATH <<EOF
+  > [alias]
+  > shortlog = log --template '{rev}:{node|short}  {phase}  {desc|firstline}\n'
+  > [extensions]
+  > rebase =
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ hg init public
+  $ hg clone public test-repo
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone test-repo dev-repo
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat >> test-repo/.hg/hgrc <<EOF
+  > [phases]
+  > publish = false
+  > EOF
+
+To start things off, let's make one public, immutable changeset::
+
+  $ cd test-repo
+  $ echo 'my new project' > file1
+  $ hg add file1
+  $ hg commit -m'create new project'
+  $ hg push
+  pushing to $TESTTMP/public (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+
+and pull that into the development repository::
+
+  $ cd ../dev-repo
+  $ hg pull -u
+  pulling from $TESTTMP/test-repo (glob)
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Let's commit a preliminary change and push it to ``test-repo`` for
+testing. ::
+
+  $ echo 'fix fix fix' > file1
+  $ hg commit -m'prelim change'
+  $ hg push -q ../test-repo
+
+Figure SG01 (roughly)
+  $ hg shortlog -G
+  @  1:f6490818a721  draft  prelim change
+  |
+  o  0:0dc9c9f6ab91  public  create new project
+  
+Now let's switch to test-repo to test our change and amend::
+  $ cd ../test-repo
+  $ hg update -q
+  $ echo 'Fix fix fix.' > file1
+  $ hg amend -m'fix bug 37'
+
+Figure SG02
+  $ hg shortlog --hidden -G
+  @  3:60ffde5765c5  draft  fix bug 37
+  |
+  | x  2:2a039763c0f4  draft  temporary amend commit for f6490818a721
+  | |
+  | x  1:f6490818a721  draft  prelim change
+  |/
+  o  0:0dc9c9f6ab91  public  create new project
+  
+Pull into dev-repo: obsolescence markers are transferred, but not
+the new obsolete changeset.
+  $ cd ../dev-repo
+  $ hg pull -u
+  pulling from $TESTTMP/test-repo (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  2 new obsolescence markers
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
+
+Figure SG03
+  $ hg shortlog --hidden -G
+  @  2:60ffde5765c5  draft  fix bug 37
+  |
+  | x  1:f6490818a721  draft  prelim change
+  |/
+  o  0:0dc9c9f6ab91  public  create new project
+  
+Amend again in dev-repo
+  $ echo 'Fix, fix, and fix.' > file1
+  $ hg amend
+  $ hg push -q
+
+Figure SG04 (dev-repo)
+  $ hg shortlog --hidden -G
+  @  4:de6151c48e1c  draft  fix bug 37
+  |
+  | x  3:ad19d3570adb  draft  temporary amend commit for 60ffde5765c5
+  | |
+  | x  2:60ffde5765c5  draft  fix bug 37
+  |/
+  | x  1:f6490818a721  draft  prelim change
+  |/
+  o  0:0dc9c9f6ab91  public  create new project
+  
+Figure SG04 (test-repo)
+  $ cd ../test-repo
+  $ hg update
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
+  $ hg shortlog --hidden -G
+  @  4:de6151c48e1c  draft  fix bug 37
+  |
+  | x  3:60ffde5765c5  draft  fix bug 37
+  |/
+  | x  2:2a039763c0f4  draft  temporary amend commit for f6490818a721
+  | |
+  | x  1:f6490818a721  draft  prelim change
+  |/
+  o  0:0dc9c9f6ab91  public  create new project
+  
+This bug fix is finished. We can push it to the public repository.
+  $ hg push
+  pushing to $TESTTMP/public (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  4 new obsolescence markers
+
+Now that the fix is public, we cannot amend it any more.
+  $ hg amend -m 'fix bug 37'
+  abort: cannot amend public changesets
+  [255]
+
+Figure SG05
+  $ hg -R ../public shortlog -G
+  o  1:de6151c48e1c  public  fix bug 37
+  |
+  o  0:0dc9c9f6ab91  public  create new project
+  
+Oops, still have draft changesets in dev-repo: push the phase change there.
+  $ hg -R ../dev-repo shortlog -r 'draft()'
+  4:de6151c48e1c  draft  fix bug 37
+  $ hg push ../dev-repo
+  pushing to ../dev-repo
+  searching for changes
+  no changes found
+  [1]
+  $ hg -R ../dev-repo shortlog -r 'draft()'
+
+Sharing with multiple developers: code review
+
+  $ cd ..
+  $ hg clone public review
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone review alice
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone review bob
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat >> review/.hg/hgrc <<EOF
+  > [phases]
+  > publish = false
+  > EOF
+
+Alice commits a draft bug fix, pushes to review repo.
+  $ cd alice
+  $ hg bookmark bug15
+  $ echo 'fix' > file2
+  $ hg commit -A -u alice -m 'fix bug 15 (v1)'
+  adding file2
+  $ hg push -B bug15
+  pushing to $TESTTMP/review (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  exporting bookmark bug15
+  $ hg -R ../review bookmarks
+     bug15                     2:f91e97234c2b
+
+Alice receives code review, amends her fix, and goes out to lunch to
+await second review.
+  $ echo 'Fix.' > file2
+  $ hg amend -m 'fix bug 15 (v2)'
+  $ hg push
+  pushing to $TESTTMP/review (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  2 new obsolescence markers
+  updating bookmark bug15
+  $ hg -R ../review bookmarks
+     bug15                     3:cbdfbd5a5db2
+
+Figure SG06: review repository after Alice pushes her amended changeset.
+  $ hg --hidden -R ../review shortlog -G -r 1::
+  o  3:cbdfbd5a5db2  draft  fix bug 15 (v2)
+  |
+  | x  2:f91e97234c2b  draft  fix bug 15 (v1)
+  |/
+  @  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+
+Bob commits a draft changeset, pushes to review repo.
+  $ cd ../bob
+  $ echo 'stuff' > file1
+  $ hg bookmark featureX
+  $ hg commit -u bob -m 'implement feature X (v1)'
+  $ hg push -B featureX
+  pushing to $TESTTMP/review (glob)
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: cbdfbd5a5db2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark featureX
+  $ hg -R ../review bookmarks
+     bug15                     3:cbdfbd5a5db2
+     featureX                  4:193657d1e852
+
+Bob receives first review, amends and pushes.
+  $ echo 'do stuff' > file1
+  $ hg amend -m 'implement feature X (v2)'
+  $ hg push
+  pushing to $TESTTMP/review (glob)
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: cbdfbd5a5db2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  2 new obsolescence markers
+  updating bookmark featureX
+
+Bob receives second review, amends, and pushes to public:
+this time, he's sure he got it right!
+  $ echo 'Do stuff.' > file1
+  $ hg amend -m 'implement feature X (v3)'
+  $ hg push ../public
+  pushing to ../public
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  4 new obsolescence markers
+  $ hg -R ../public bookmarks
+  no bookmarks set
+  $ hg push ../review
+  pushing to ../review
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: cbdfbd5a5db2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  2 new obsolescence markers
+  updating bookmark featureX
+  $ hg -R ../review bookmarks
+     bug15                     3:cbdfbd5a5db2
+     featureX                  6:540ba8f317e6
+
+Figure SG07: review and public repos after Bob implements feature X.
+  $ hg --hidden -R ../review shortlog -G -r 1::
+  o  6:540ba8f317e6  public  implement feature X (v3)
+  |
+  | x  5:0eb74a7b6698  draft  implement feature X (v2)
+  |/
+  | x  4:193657d1e852  draft  implement feature X (v1)
+  |/
+  | o  3:cbdfbd5a5db2  draft  fix bug 15 (v2)
+  |/
+  | x  2:f91e97234c2b  draft  fix bug 15 (v1)
+  |/
+  @  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+  $ hg --hidden -R ../public shortlog -G -r 1::
+  o  2:540ba8f317e6  public  implement feature X (v3)
+  |
+  o  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+
+How do things look in the review repo?
+  $ cd ../review
+  $ hg --hidden shortlog -G -r 1::
+  o  6:540ba8f317e6  public  implement feature X (v3)
+  |
+  | x  5:0eb74a7b6698  draft  implement feature X (v2)
+  |/
+  | x  4:193657d1e852  draft  implement feature X (v1)
+  |/
+  | o  3:cbdfbd5a5db2  draft  fix bug 15 (v2)
+  |/
+  | x  2:f91e97234c2b  draft  fix bug 15 (v1)
+  |/
+  @  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+
+Meantime, Alice is back from lunch. While she was away, Bob approved
+her change, so now she can publish it.
+  $ cd ../alice
+  $ hg --hidden shortlog -G -r 1::
+  @  4:cbdfbd5a5db2  draft  fix bug 15 (v2)
+  |
+  | x  3:55dd95168a35  draft  temporary amend commit for f91e97234c2b
+  | |
+  | x  2:f91e97234c2b  draft  fix bug 15 (v1)
+  |/
+  o  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+  $ hg outgoing -q ../public
+  4:cbdfbd5a5db2
+  $ hg push ../public
+  pushing to ../public
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: 540ba8f317e6
+  abort: push creates new remote head cbdfbd5a5db2 with bookmark 'bug15'!
+  (pull and merge or see 'hg help push' for details about pushing new heads)
+  [255]
+  $ hg pull ../public
+  pulling from ../public
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  4 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg log -G -q -r 'head()'
+  o  5:540ba8f317e6
+  |
+  ~
+  @  4:cbdfbd5a5db2
+  |
+  ~
+  $ hg --hidden shortlog -G -r 1::
+  o  5:540ba8f317e6  public  implement feature X (v3)
+  |
+  | @  4:cbdfbd5a5db2  draft  fix bug 15 (v2)
+  |/
+  | x  3:55dd95168a35  draft  temporary amend commit for f91e97234c2b
+  | |
+  | x  2:f91e97234c2b  draft  fix bug 15 (v1)
+  |/
+  o  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+
+Alice rebases her draft changeset on top of Bob's public changeset and
+publishes the result.
+  $ hg rebase -d 5
+  rebasing 4:cbdfbd5a5db2 "fix bug 15 (v2)" (bug15)
+  $ hg push ../public
+  pushing to ../public
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  3 new obsolescence markers
+  $ hg push ../review
+  pushing to ../review
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 0 changes to 1 files
+  1 new obsolescence markers
+  updating bookmark bug15
+
+Figure SG08: review and public changesets after Alice pushes.
+  $ hg --hidden -R ../review shortlog -G -r 1::
+  o  7:a06ec1bf97bd  public  fix bug 15 (v2)
+  |
+  o  6:540ba8f317e6  public  implement feature X (v3)
+  |
+  | x  5:0eb74a7b6698  draft  implement feature X (v2)
+  |/
+  | x  4:193657d1e852  draft  implement feature X (v1)
+  |/
+  | x  3:cbdfbd5a5db2  draft  fix bug 15 (v2)
+  |/
+  | x  2:f91e97234c2b  draft  fix bug 15 (v1)
+  |/
+  @  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+  $ hg --hidden -R ../public shortlog -G -r 1::
+  o  3:a06ec1bf97bd  public  fix bug 15 (v2)
+  |
+  o  2:540ba8f317e6  public  implement feature X (v3)
+  |
+  o  1:de6151c48e1c  public  fix bug 37
+  |
+  ~
+  $ cd ..
+
+Setup for "cowboy mode" shared mutable history (to illustrate divergent
+and bumped changesets).
+  $ rm -rf review alice bob
+  $ hg clone public alice
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg clone public bob
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat >> alice/.hg/hgrc <<EOF
+  > [phases]
+  > publish = false
+  > EOF
+  $ cp alice/.hg/hgrc bob/.hg/hgrc
+
+Now we'll have Bob commit a bug fix that could still be improved::
+
+  $ cd bob
+  $ echo 'pretty good fix' >> file1
+  $ hg commit -u bob -m 'fix bug 24 (v1)'
+  $ hg shortlog -r .
+  4:2fe6c4bd32d0  draft  fix bug 24 (v1)
+
+Since Alice and Bob are now in cowboy mode, Alice pulls Bob's draft
+changeset and amends it herself. ::
+
+  $ cd ../alice
+  $ hg pull -u ../bob
+  pulling from ../bob
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 'better fix (alice)' >> file1
+  $ hg amend -u alice -m 'fix bug 24 (v2 by alice)'
+
+Bob implements a better fix of his own::
+
+  $ cd ../bob
+  $ echo 'better fix (bob)' >> file1
+  $ hg amend -u bob -m 'fix bug 24 (v2 by bob)'
+  $ hg --hidden shortlog -G -r 3::
+  @  6:a360947f6faf  draft  fix bug 24 (v2 by bob)
+  |
+  | x  5:3466c7f5a149  draft  temporary amend commit for 2fe6c4bd32d0
+  | |
+  | x  4:2fe6c4bd32d0  draft  fix bug 24 (v1)
+  |/
+  o  3:a06ec1bf97bd  public  fix bug 15 (v2)
+  |
+  ~
+
+Bob discovers the divergence.
+  $ hg pull ../alice
+  pulling from ../alice
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  2 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  2 new divergent changesets
+
+Figure SG09: multiple heads! divergence! oh my!
+  $ hg --hidden shortlog -G -r 3::
+  o  7:e3f99ce9d9cd  draft  fix bug 24 (v2 by alice)
+  |
+  | @  6:a360947f6faf  draft  fix bug 24 (v2 by bob)
+  |/
+  | x  5:3466c7f5a149  draft  temporary amend commit for 2fe6c4bd32d0
+  | |
+  | x  4:2fe6c4bd32d0  draft  fix bug 24 (v1)
+  |/
+  o  3:a06ec1bf97bd  public  fix bug 15 (v2)
+  |
+  ~
+  $ hg --hidden shortlog -r 'successors(2fe6)'
+  6:a360947f6faf  draft  fix bug 24 (v2 by bob)
+  7:e3f99ce9d9cd  draft  fix bug 24 (v2 by alice)
+
+Use evolve to fix the divergence.
+  $ HGMERGE=internal:other hg evolve --divergent
+  merge:[6] fix bug 24 (v2 by bob)
+  with: [7] fix bug 24 (v2 by alice)
+  base: [4] fix bug 24 (v1)
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  working directory is now at 5ad6037c046c
+  $ hg log -q -r 'divergent()'
+
+Figure SG10: Bob's repository after fixing divergence.
+  $ hg --hidden shortlog -G -r 3::
+  @  9:5ad6037c046c  draft  fix bug 24 (v2 by bob)
+  |
+  | x  8:bcfc9a755ac3  draft  temporary amend commit for a360947f6faf
+  | |
+  +---x  7:e3f99ce9d9cd  draft  fix bug 24 (v2 by alice)
+  | |
+  | x  6:a360947f6faf  draft  fix bug 24 (v2 by bob)
+  |/
+  | x  5:3466c7f5a149  draft  temporary amend commit for 2fe6c4bd32d0
+  | |
+  | x  4:2fe6c4bd32d0  draft  fix bug 24 (v1)
+  |/
+  o  3:a06ec1bf97bd  public  fix bug 15 (v2)
+  |
+  ~
+  $ hg --hidden shortlog -r 'precursors(9)'
+  6:a360947f6faf  draft  fix bug 24 (v2 by bob)
+  7:e3f99ce9d9cd  draft  fix bug 24 (v2 by alice)
+  $ cat file1
+  Do stuff.
+  pretty good fix
+  better fix (alice)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-simple4server-bundle2.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,166 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [experimental]
+  > bundle2-exp=True
+  > EOF
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+setup repo
+
+  $ hg init server
+  $ echo "[extensions]" >> ./server/.hg/hgrc
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/serveronly.py" >> ./server/.hg/hgrc
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ hg clone http://localhost:$HGPORT/ client
+  no changes found
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat ./errors.log
+  $ echo "[extensions]" >> ./client/.hg/hgrc
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> ./client/.hg/hgrc
+  $ cp -r client other
+
+Smoke testing
+===============
+
+  $ cd client
+  $ mkcommit 0
+  $ mkcommit a
+  $ hg push
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  $ hg pull
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ cat ../errors.log
+  $ hg pull -R ../other
+  pulling from http://localhost:$HGPORT/
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ cat ../errors.log
+  $ hg push -R ../other
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cat ../errors.log
+
+Capacity testing
+===================
+
+  $ curl -s http://localhost:$HGPORT/?cmd=hello
+  capabilities: * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (glob)
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities
+  * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (no-eol) (glob)
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  obsolete	
+  phases	
+
+Push
+=============
+
+  $ echo 'A' > a
+  $ hg amend
+  $ hg push
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  remote: 2 new obsolescence markers
+  $ cat ../errors.log
+  $ hg push
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cat ../errors.log
+
+Pull
+=============
+
+  $ hg -R ../other pull
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  2 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ cat ../errors.log
+  $ hg -R ../other pull
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ cat ../errors.log
+
+  $ cd ..
+
+Test disabling obsolete advertisement
+===========================================
+(used by bitbucket to select which repo use evolve)
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  obsolete	
+  phases	
+  $ curl -s http://localhost:$HGPORT/?cmd=hello
+  capabilities: * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (glob)
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities
+  * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (no-eol) (glob)
+
+  $ echo '[__temporary__]' >> server/.hg/hgrc
+  $ echo 'advertiseobsolete=False' >> server/.hg/hgrc
+  $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  phases	
+
+  $ echo 'advertiseobsolete=True' >> server/.hg/hgrc
+  $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  obsolete	
+  phases	
+
+  $ curl -s http://localhost:$HGPORT/?cmd=hello
+  capabilities: * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (glob)
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities
+  * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (no-eol) (glob)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-simple4server.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,175 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [experimental]
+  > bundle2-exp=False # < Mercurial-4.0
+  > [devel]
+  > legacy.exchange=bundle1
+  > [extensions]
+  > EOF
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+setup repo
+
+  $ hg init server
+  $ echo "[extensions]" >> ./server/.hg/hgrc
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/serveronly.py" >> ./server/.hg/hgrc
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ hg clone http://localhost:$HGPORT/ client
+  no changes found
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat ./errors.log
+  $ echo "[extensions]" >> ./client/.hg/hgrc
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> ./client/.hg/hgrc
+  $ cp -r client other
+
+Smoke testing
+===============
+
+  $ cd client
+  $ mkcommit 0
+  $ mkcommit a
+  $ hg push
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  $ hg pull
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ cat ../errors.log
+  $ hg pull -R ../other
+  pulling from http://localhost:$HGPORT/
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  pull obsolescence markers
+  (run 'hg update' to get a working copy)
+  $ cat ../errors.log
+  $ hg push -R ../other
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cat ../errors.log
+
+Capacity testing
+===================
+
+  $ curl -s http://localhost:$HGPORT/?cmd=hello
+  capabilities: * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (glob)
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities
+  * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (no-eol) (glob)
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  obsolete	
+  phases	
+
+Push
+=============
+
+  $ echo 'A' > a
+  $ hg amend
+  $ hg push
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  pushing 2 obsolescence markers (* bytes) (glob)
+  remote: 2 obsolescence markers added
+  $ cat ../errors.log
+  $ hg push
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cat ../errors.log
+
+Pull
+=============
+
+  $ hg -R ../other pull
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  pull obsolescence markers
+  2 obsolescence markers added
+  (run 'hg heads' to see heads)
+  $ cat ../errors.log
+  $ hg -R ../other pull
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ cat ../errors.log
+
+  $ cd ..
+
+Test disabling obsolete advertisement
+===========================================
+(used by bitbucket to select which repo use evolve)
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  obsolete	
+  phases	
+  $ curl -s http://localhost:$HGPORT/?cmd=hello
+  capabilities: * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (glob)
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities
+  * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (no-eol) (glob)
+
+  $ echo '[__temporary__]' >> server/.hg/hgrc
+  $ echo 'advertiseobsolete=False' >> server/.hg/hgrc
+  $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  phases	
+  $ curl -s http://localhost:$HGPORT/?cmd=hello | grep _evoext_pushobsmarkers_0
+  [1]
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities | grep _evoext_pushobsmarkers_0
+  [1]
+
+  $ echo 'advertiseobsolete=True' >> server/.hg/hgrc
+  $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort
+  bookmarks	
+  namespaces	
+  obsolete	
+  phases	
+  $ curl -s http://localhost:$HGPORT/?cmd=hello
+  capabilities: * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (glob)
+  $ curl -s http://localhost:$HGPORT/?cmd=capabilities
+  * _evoext_pushobsmarkers_0 _evoext_pullobsmarkers_0 _evoext_obshash_0 _evoext_obshash_1 _evoext_getbundle_obscommon (no-eol) (glob)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-split.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,387 @@
+test of the split command
+-----------------------
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > split=-d "0 0"
+  > amend=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > interactive = true
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+
+Basic case, split a head
+  $ hg init testsplit
+  $ cd testsplit
+  $ mkcommit _a
+  $ mkcommit _b
+  $ mkcommit _c
+  $ mkcommit _d
+  $ echo "change to a" >> _a
+  $ hg amend
+  $ hg debugobsolete
+  9e84a109b8eb081ad754681ee4b1380d17a3741f aa8f656bb307022172d2648be6fb65322f801225 0 (*) {'user': 'test'} (glob)
+  f002b57772d7f09b180c407213ae16d92996a988 0 {9e84a109b8eb081ad754681ee4b1380d17a3741f} (*) {'user': 'test'} (glob)
+
+To create commits with the number of split
+  $ echo 0 > num
+  $ cat > editor.sh << '__EOF__'
+  > NUM=$(cat num)
+  > NUM=`expr "$NUM" + 1`
+  > echo "$NUM" > num
+  > echo "split$NUM" > "$1"
+  > __EOF__
+  $ export HGEDITOR="\"sh\" \"editor.sh\""
+  $ hg split << EOF
+  > y
+  > y
+  > y
+  > n
+  > N
+  > y
+  > y
+  > EOF
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  reverting _a
+  adding _d
+  diff --git a/_a b/_a
+  1 hunks, 1 lines changed
+  examine changes to '_a'? [Ynesfdaq?] y
+  
+  @@ -1,0 +2,1 @@
+  +change to a
+  record change 1/2 to '_a'? [Ynesfdaq?] y
+  
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +_d
+  record change 2/2 to '_d'? [Ynesfdaq?] n
+  
+  created new head
+  Done splitting? [yN] N
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +_d
+  record this change to '_d'? [Ynesfdaq?] y
+  
+  no more change to split
+
+  $ hg debugobsolete
+  9e84a109b8eb081ad754681ee4b1380d17a3741f aa8f656bb307022172d2648be6fb65322f801225 0 (*) {'user': 'test'} (glob)
+  f002b57772d7f09b180c407213ae16d92996a988 0 {9e84a109b8eb081ad754681ee4b1380d17a3741f} (*) {'user': 'test'} (glob)
+  aa8f656bb307022172d2648be6fb65322f801225 a98b35e86cae589b61892127c5ec1c868e41d910 5410a2352fa3114883327beee89e3085eefac25c 0 (*) {'user': 'test'} (glob)
+  $ hg glog
+  @  changeset:   7:5410a2352fa3
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split2
+  |
+  o  changeset:   6:a98b35e86cae
+  |  parent:      2:102002290587
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split1
+  |
+  o  changeset:   2:102002290587
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add _c
+  |
+  o  changeset:   1:37445b16603b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add _b
+  |
+  o  changeset:   0:135f39f4bd78
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add _a
+  
+
+Cannot split a commit with uncommitted changes
+  $ hg up "desc(_c)"
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "_cd" > _c
+  $ hg split 
+  abort: uncommitted changes
+  [255]
+
+Split a revision specified with -r
+  $ hg up "desc(_c)" -C
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "change to b" >> _b
+  $ hg amend -m "_cprim"
+  2 new unstable changesets
+  $ hg evolve --all
+  move:[6] split1
+  atop:[9] _cprim
+  move:[7] split2
+  atop:[10] split1
+  working directory is now at * (glob)
+  $ hg log -r "desc(_cprim)" -v -p
+  changeset:   9:719157b217ac
+  parent:      1:37445b16603b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files:       _b _c
+  description:
+  _cprim
+  
+  
+  diff --git a/_b b/_b
+  --- a/_b
+  +++ b/_b
+  @@ -1,0 +2,1 @@
+  +change to b
+  diff --git a/_c b/_c
+  new file mode 100644
+  --- /dev/null
+  +++ b/_c
+  @@ -0,0 +1,1 @@
+  +_c
+  
+  $ hg split -r "desc(_cprim)" <<EOF
+  > y
+  > y
+  > y
+  > n
+  > y
+  > EOF
+  2 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  reverting _b
+  adding _c
+  diff --git a/_b b/_b
+  1 hunks, 1 lines changed
+  examine changes to '_b'? [Ynesfdaq?] y
+  
+  @@ -1,0 +2,1 @@
+  +change to b
+  record change 1/2 to '_b'? [Ynesfdaq?] y
+  
+  diff --git a/_c b/_c
+  new file mode 100644
+  examine changes to '_c'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +_c
+  record change 2/2 to '_c'? [Ynesfdaq?] n
+  
+  created new head
+  Done splitting? [yN] y
+
+Stop before splitting the commit completely creates a commit with all the
+remaining changes
+
+  $ hg debugobsolete
+  9e84a109b8eb081ad754681ee4b1380d17a3741f aa8f656bb307022172d2648be6fb65322f801225 0 (*) {'user': 'test'} (glob)
+  f002b57772d7f09b180c407213ae16d92996a988 0 {9e84a109b8eb081ad754681ee4b1380d17a3741f} (*) {'user': 'test'} (glob)
+  aa8f656bb307022172d2648be6fb65322f801225 a98b35e86cae589b61892127c5ec1c868e41d910 5410a2352fa3114883327beee89e3085eefac25c 0 (*) {'user': 'test'} (glob)
+  10200229058723ce8d67f6612c1f6b4f73b1fe73 719157b217acc43d397369a448824ed4c7a302f2 0 (*) {'user': 'test'} (glob)
+  5d0c8b0f2d3e5e1ff95f93d7da2ba06650605ab5 0 {10200229058723ce8d67f6612c1f6b4f73b1fe73} (*) {'user': 'test'} (glob)
+  a98b35e86cae589b61892127c5ec1c868e41d910 286887947725085e03455d79649197feaef1eb9d 0 (*) {'user': 'test'} (glob)
+  5410a2352fa3114883327beee89e3085eefac25c 0b67cee46a7f2ad664f994027e7af95b36ae25fe 0 (*) {'user': 'test'} (glob)
+  719157b217acc43d397369a448824ed4c7a302f2 ced8fbcce3a7cd33f0e454d2cd63882ce1b6006b 73309fb98db840ba4ec5ad528346dc6ee0b39dcb 0 (*) {'user': 'test'} (glob)
+  $ hg evolve --all
+  move:[10] split1
+  atop:[13] split4
+  move:[11] split2
+  atop:[14] split1
+  working directory is now at f200e612ac86
+  $ hg glog
+  @  changeset:   15:f200e612ac86
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split2
+  |
+  o  changeset:   14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split1
+  |
+  o  changeset:   13:73309fb98db8
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split4
+  |
+  o  changeset:   12:ced8fbcce3a7
+  |  parent:      1:37445b16603b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split3
+  |
+  o  changeset:   1:37445b16603b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add _b
+  |
+  o  changeset:   0:135f39f4bd78
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add _a
+  
+
+Split should move bookmarks on the last split successor and preserve the
+active bookmark as active
+  $ hg book bookA
+  $ hg book bookB
+  $ echo "changetofilea" > _a
+  $ hg amend
+  $ hg book
+     bookA                     17:39d16b69c75d
+   * bookB                     17:39d16b69c75d
+  $ hg glog -r "14::"
+  @  changeset:   17:39d16b69c75d
+  |  bookmark:    bookA
+  |  bookmark:    bookB
+  |  tag:         tip
+  |  parent:      14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split2
+  |
+  o  changeset:   14:aec57822a8ff
+  |  user:        test
+  ~  date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     split1
+  
+  $ hg split <<EOF
+  > y
+  > y
+  > n
+  > y
+  > EOF
+  (leaving bookmark bookB)
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  reverting _a
+  adding _d
+  diff --git a/_a b/_a
+  1 hunks, 2 lines changed
+  examine changes to '_a'? [Ynesfdaq?] y
+  
+  @@ -1,2 +1,1 @@
+  -_a
+  -change to a
+  +changetofilea
+  record change 1/2 to '_a'? [Ynesfdaq?] y
+  
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] n
+  
+  created new head
+  Done splitting? [yN] y
+  $ hg glog -r "14::"
+  @  changeset:   19:a2b5c9d9b362
+  |  bookmark:    bookA
+  |  bookmark:    bookB
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split6
+  |
+  o  changeset:   18:bf3402785e72
+  |  parent:      14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split5
+  |
+  o  changeset:   14:aec57822a8ff
+  |  user:        test
+  ~  date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     split1
+  
+  $ hg book
+     bookA                     19:a2b5c9d9b362
+   * bookB                     19:a2b5c9d9b362
+ 
+Lastest revision is selected if multiple are given to -r
+  $ hg split -r "desc(_a)::"
+  (leaving bookmark bookB)
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  adding _d
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] abort: response expected
+  [255]
+
+Cannot split a commit that is not a head if instability is not allowed
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=createmarkers
+  > evolutioncommands=split
+  > EOF
+  $ hg split -r "desc(split3)"
+  abort: cannot split commit: ced8fbcce3a7 not a head
+  [255]
+
+Changing evolution level to createmarkers
+  $ echo "[experimental]" >> $HGRCPATH
+  $ echo "evolution=createmarkers" >> $HGRCPATH
+
+Running split without any revision operates on the parent of the working copy
+  $ hg split << EOF
+  > q
+  > EOF
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  adding _d
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] q
+  
+  abort: user quit
+  [255]
+
+Running split with tip revision, specified as unnamed argument
+  $ hg split . << EOF
+  > q
+  > EOF
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  adding _d
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] q
+  
+  abort: user quit
+  [255]
+
+Running split with both unnamed and named revision arguments shows an error msg
+  $ hg split . --rev .^ << EOF
+  > q
+  > EOF
+  abort: more than one revset is given
+  (use either `hg split <rs>` or `hg split --rev <rs>`, not both)
+  [255]
+
+Split empty commit (issue5191)
+  $ hg branch new-branch
+  marked working directory as branch new-branch
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg commit -m "empty"
+  $ hg split
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-stabilize-conflict.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,263 @@
+=========================================================
+Test the proper behavior of evolve during merge conflict.
+=========================================================
+
+Initial setup
+
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > interactive=false
+  > merge=internal:merge
+  > promptecho = True
+  > [defaults]
+  > amend=-d "0 0"
+  > [merge-tools]
+  > touch.checkchanged=true
+  > touch.gui=true
+  > touch.args=babar
+  > [extensions]
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ safesed() {
+  >   sed "$1" "$2" > `pwd`/sed.temp
+  >   mv `pwd`/sed.temp "$2"
+  > }
+
+create a simple repo
+
+  $ hg init repo
+  $ cd repo
+  $ cat << EOF > babar
+  > un
+  > deux
+  > trois
+  > quatre
+  > cinq
+  > EOF
+  $ hg add babar
+  $ hg commit -m "babar count up to five"
+  $ cat << EOF >> babar
+  > six
+  > sept
+  > huit
+  > neuf
+  > dix
+  > EOF
+  $ hg commit -m "babar count up to ten"
+  $ cat << EOF >> babar
+  > onze
+  > douze
+  > treize
+  > quatorze
+  > quinze
+  > EOF
+  $ hg commit -m "babar count up to fifteen"
+
+
+proper behavior without conflict
+----------------------------------
+
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [1] babar count up to ten
+  $ safesed 's/huit/eight/' babar
+  $ hg diff
+  diff -r 9d5daf8bd956 babar
+  --- a/babar	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/babar	* (glob)
+  @@ -5,6 +5,6 @@
+   cinq
+   six
+   sept
+  -huit
+  +eight
+   neuf
+   dix
+  $ hg amend
+  1 new unstable changesets
+  $ hg evolve
+  move:[2] babar count up to fifteen
+  atop:[4] babar count up to ten
+  merging babar
+  working directory is now at 71c18f70c34f
+  $ hg resolve -l
+  $ hg log -G
+  @  changeset:   5:71c18f70c34f
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     babar count up to fifteen
+  |
+  o  changeset:   4:5977072d13c5
+  |  parent:      0:29ec1554cfaf
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     babar count up to ten
+  |
+  o  changeset:   0:29ec1554cfaf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     babar count up to five
+  
+
+
+proper behavior with conflict using internal:merge
+--------------------------------------------------
+
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [4] babar count up to ten
+  $ safesed 's/dix/ten/' babar
+  $ hg diff
+  diff -r 5977072d13c5 babar
+  --- a/babar	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/babar	* (glob)
+  @@ -7,4 +7,4 @@
+   sept
+   eight
+   neuf
+  -dix
+  +ten
+  $ hg amend
+  1 new unstable changesets
+  $ hg evolve
+  move:[5] babar count up to fifteen
+  atop:[7] babar count up to ten
+  merging babar
+  warning: conflicts while merging babar! (edit, then use 'hg resolve --mark')
+  evolve failed!
+  fix conflict and run 'hg evolve --continue' or use 'hg update -C .' to abort
+  abort: unresolved merge conflicts (see hg help resolve)
+  [255]
+  $ hg resolve -l
+  U babar
+  $ hg log -G
+  @  changeset:   7:e04690b09bc6
+  |  tag:         tip
+  |  parent:      0:29ec1554cfaf
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     babar count up to ten
+  |
+  | o  changeset:   5:71c18f70c34f
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  trouble:     unstable
+  | |  summary:     babar count up to fifteen
+  | |
+  | x  changeset:   4:5977072d13c5
+  |/   parent:      0:29ec1554cfaf
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     babar count up to ten
+  |
+  o  changeset:   0:29ec1554cfaf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     babar count up to five
+  
+(fix the conflict and continue)
+
+  $ hg revert -r 5 --all
+  reverting babar
+  $ safesed 's/dix/ten/' babar
+  $ hg resolve --all -m
+  (no more unresolved files)
+  $ hg evolve --continue
+  grafting 5:71c18f70c34f "babar count up to fifteen"
+  $ hg resolve -l
+  $ hg log -G
+  @  changeset:   8:1836b91c6c1d
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     babar count up to fifteen
+  |
+  o  changeset:   7:e04690b09bc6
+  |  parent:      0:29ec1554cfaf
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     babar count up to ten
+  |
+  o  changeset:   0:29ec1554cfaf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     babar count up to five
+  
+proper behavior with conflict using an external merge tool
+----------------------------------------------------------
+
+  $ safesed 's/merge=.*/merge=touch/' $HGRCPATH
+  $ safesed 's/touch.gui=.*/touch.gui=false/' $HGRCPATH
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [7] babar count up to ten
+  $ safesed 's/ten/zehn/' babar
+  $ hg diff
+  diff -r e04690b09bc6 babar
+  --- a/babar	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/babar	* (glob)
+  @@ -7,4 +7,4 @@
+   sept
+   eight
+   neuf
+  -ten
+  +zehn
+  $ hg amend
+  1 new unstable changesets
+  $ safesed 's/interactive=.*/interactive=true/' $HGRCPATH
+  $ hg evolve --tool touch <<EOF
+  > n
+  > EOF
+  move:[8] babar count up to fifteen
+  atop:[10] babar count up to ten
+  merging babar
+   output file babar appears unchanged
+  was merge successful (yn)? n
+  merging babar failed!
+  evolve failed!
+  fix conflict and run 'hg evolve --continue' or use 'hg update -C .' to abort
+  abort: unresolved merge conflicts (see hg help resolve)
+  [255]
+  $ hg resolve -l
+  U babar
+  $ hg log -G
+  @  changeset:   10:b20d08eea373
+  |  tag:         tip
+  |  parent:      0:29ec1554cfaf
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     babar count up to ten
+  |
+  | o  changeset:   8:1836b91c6c1d
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  trouble:     unstable
+  | |  summary:     babar count up to fifteen
+  | |
+  | x  changeset:   7:e04690b09bc6
+  |/   parent:      0:29ec1554cfaf
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     babar count up to ten
+  |
+  o  changeset:   0:29ec1554cfaf
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     babar count up to five
+  
+  $ cat babar
+  un
+  deux
+  trois
+  quatre
+  cinq
+  six
+  sept
+  eight
+  neuf
+  zehn
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-stabilize-order.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,249 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ glog() {
+  >   hg glog --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
+  > }
+
+  $ hg init repo
+  $ cd repo
+  $ echo root > root
+  $ hg ci -Am addroot
+  adding root
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+  $ echo b > b
+  $ hg ci -Am addb
+  adding b
+  $ echo c > c
+  $ hg ci -Am addc
+  adding c
+  $ glog
+  @  3:7a7552255fb5@default(draft) addc
+  |
+  o  2:ef23d6ef94d6@default(draft) addb
+  |
+  o  1:93418d2c0979@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [2] addb
+  $ echo b >> b
+  $ hg amend
+  1 new unstable changesets
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] adda
+  $ echo a >> a
+  $ hg amend
+  1 new unstable changesets
+  $ glog
+  @  7:005fe5914f78@default(draft) adda
+  |
+  | o  5:22619daeed78@default(draft) addb
+  | |
+  | | o  3:7a7552255fb5@default(draft) addc
+  | | |
+  | | x  2:ef23d6ef94d6@default(draft) addb
+  | |/
+  | x  1:93418d2c0979@default(draft) adda
+  |/
+  o  0:c471ef929e6a@default(draft) addroot
+  
+
+Test stabilizing a predecessor child
+
+  $ hg evolve -v
+  move:[5] addb
+  atop:[7] adda
+  hg rebase -r 22619daeed78 -d 005fe5914f78
+  resolving manifests
+  getting b
+  committing files:
+  b
+  committing manifest
+  committing changelog
+  working directory is now at 81b8bbcd5892
+  $ glog
+  @  8:81b8bbcd5892@default(draft) addb
+  |
+  o  7:005fe5914f78@default(draft) adda
+  |
+  | o  3:7a7552255fb5@default(draft) addc
+  | |
+  | x  2:ef23d6ef94d6@default(draft) addb
+  | |
+  | x  1:93418d2c0979@default(draft) adda
+  |/
+  o  0:c471ef929e6a@default(draft) addroot
+  
+
+Test stabilizing a descendant predecessor's child
+
+  $ hg up 7
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg debugobsolete > successors.old
+  $ hg evolve -v
+  move:[3] addc
+  atop:[8] addb
+  hg rebase -r 7a7552255fb5 -d 81b8bbcd5892
+  resolving manifests
+  getting b
+  resolving manifests
+  getting c
+  committing files:
+  c
+  committing manifest
+  committing changelog
+  working directory is now at 0f691739f917
+  $ hg debugobsolete > successors.new
+  $ diff -u successors.old successors.new
+  --- successors.old* (glob)
+  +++ successors.new* (glob)
+  @@ -3,3 +3,4 @@
+   93418d2c0979643ad446f621195e78720edb05b4 005fe5914f78e8bc64c7eba28117b0b1fa210d0d 0 (*) {'user': 'test'} (glob)
+   7a7d76dc97c57751de9e80f61ed2a639bd03cd24 0 {93418d2c0979643ad446f621195e78720edb05b4} (*) {'user': 'test'} (glob)
+   22619daeed78036f80fbd326b6852519c4f0c25e 81b8bbcd5892841efed41433d7a5e9df922396cb 0 (*) {'user': 'test'} (glob)
+  +7a7552255fb5f8bd745e46fba6f0ca633a4dd716 0f691739f91762462bf8ba21f35fdf71fe64310e 0 (*) {'user': 'test'} (glob)
+  [1]
+
+
+
+  $ glog
+  @  9:0f691739f917@default(draft) addc
+  |
+  o  8:81b8bbcd5892@default(draft) addb
+  |
+  o  7:005fe5914f78@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg evolve -v
+  no troubled changesets
+  [1]
+
+Test behavior with --any
+
+  $ hg up 8
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo b >> b
+  $ hg amend
+  1 new unstable changesets
+  $ glog
+  @  11:7a68bc4596ea@default(draft) addb
+  |
+  | o  9:0f691739f917@default(draft) addc
+  | |
+  | x  8:81b8bbcd5892@default(draft) addb
+  |/
+  o  7:005fe5914f78@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg up 9
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg evolve -v
+  nothing to evolve on current working copy parent
+  (1 other unstable in the repository, do you want --any or --rev)
+  [2]
+  $ hg evolve --any -v
+  move:[9] addc
+  atop:[11] addb
+  hg rebase -r 0f691739f917 -d 7a68bc4596ea
+  resolving manifests
+  removing c
+  getting b
+  resolving manifests
+  getting c
+  committing files:
+  c
+  committing manifest
+  committing changelog
+  working directory is now at 2256dae6521f
+  $ glog
+  @  12:2256dae6521f@default(draft) addc
+  |
+  o  11:7a68bc4596ea@default(draft) addb
+  |
+  o  7:005fe5914f78@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg evolve --any -v
+  no unstable changesets to evolve
+  [1]
+
+Ambiguous evolution
+  $ echo a > k
+  $ hg add k
+  $ hg ci -m firstambiguous
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo a > l
+  $ hg add l
+  $ hg ci -m secondambiguous
+  created new head
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg commit --amend -m "newmessage"
+  2 new unstable changesets
+  $ hg log -G
+  @  changeset:   15:f83a0bce03e4
+  |  tag:         tip
+  |  parent:      11:7a68bc4596ea
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     newmessage
+  |
+  | o  changeset:   14:fa68011f392e
+  | |  parent:      12:2256dae6521f
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  trouble:     unstable
+  | |  summary:     secondambiguous
+  | |
+  | | o  changeset:   13:bdc003b6eec2
+  | |/   user:        test
+  | |    date:        Thu Jan 01 00:00:00 1970 +0000
+  | |    trouble:     unstable
+  | |    summary:     firstambiguous
+  | |
+  | x  changeset:   12:2256dae6521f
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     addc
+  |
+  o  changeset:   11:7a68bc4596ea
+  |  parent:      7:005fe5914f78
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     addb
+  |
+  o  changeset:   7:005fe5914f78
+  |  parent:      0:c471ef929e6a
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     adda
+  |
+  o  changeset:   0:c471ef929e6a
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     addroot
+  
+  $ hg evolve
+  abort: multiple evolve candidates
+  (select one of *, * with --rev) (glob)
+  [255]
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-stabilize-result.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,371 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [extensions]
+  > hgext.rebase=
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ glog() {
+  >   hg glog --template \
+  >     '{rev}:{node|short}@{branch}({phase}) bk:[{bookmarks}] {desc|firstline}\n' "$@"
+  > }
+
+Test evolve removing the changeset being evolved
+
+  $ hg init empty
+  $ cd empty
+  $ echo a > a
+  $ hg ci -Am adda a
+  $ echo b > b
+  $ hg ci -Am addb b
+  $ echo a >> a
+  $ hg ci -m changea
+  $ hg bookmark changea
+  $ hg up 1
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark changea)
+  $ echo a >> a
+  $ hg amend -m changea
+  1 new unstable changesets
+  $ hg evolve -v --confirm
+  move:[2] changea
+  atop:[4] changea
+  perform evolve? [Ny] n
+  abort: evolve aborted by user
+  [255]
+  $ echo y | hg evolve -v --confirm --config ui.interactive=True
+  move:[2] changea
+  atop:[4] changea
+  perform evolve? [Ny] y
+  hg rebase -r cce2c55b8965 -d fb9d051ec0a4
+  resolving manifests
+  $ glog --hidden
+  @  4:fb9d051ec0a4@default(draft) bk:[changea] changea
+  |
+  | x  3:c5727dbded3c@default(draft) bk:[] temporary amend commit for 102a90ea7b4a
+  | |
+  | | x  2:cce2c55b8965@default(draft) bk:[] changea
+  | |/
+  | x  1:102a90ea7b4a@default(draft) bk:[] addb
+  |/
+  o  0:07f494440405@default(draft) bk:[] adda
+  
+  $ hg debugobsolete
+  102a90ea7b4a3361e4082ed620918c261189a36a fb9d051ec0a450a4aa2ffc8c324979832ef88065 0 (*) {'user': 'test'} (glob)
+  c5727dbded3c3a6877cf60d6bb552a76812cb844 0 {102a90ea7b4a3361e4082ed620918c261189a36a} (*) {'user': 'test'} (glob)
+  cce2c55b896511e0b6e04173c9450ba822ebc740 0 {102a90ea7b4a3361e4082ed620918c261189a36a} (*) {'user': 'test'} (glob)
+
+Test evolve with conflict
+
+  $ ls
+  a
+  b
+  $ hg pdiff a
+  diff -r 07f494440405 a
+  --- a/a	* (glob)
+  +++ b/a	* (glob)
+  @@ -1,1 +1,2 @@
+   a
+  +a
+  $ echo 'newer a' >> a
+  $ hg ci -m 'newer a'
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [4] changea
+  $ echo 'a' > a
+  $ hg amend
+  1 new unstable changesets
+  $ hg evolve
+  move:[5] newer a
+  atop:[7] changea
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  evolve failed!
+  fix conflict and run 'hg evolve --continue' or use 'hg update -C .' to abort
+  abort: unresolved merge conflicts (see hg help resolve)
+  [255]
+  $ hg revert -r 'unstable()' a
+  $ hg diff
+  diff -r 66719795a494 a
+  --- a/a	* (glob)
+  +++ b/a	* (glob)
+  @@ -1,1 +1,3 @@
+   a
+  +a
+  +newer a
+  $ hg evolve --continue
+  grafting 5:3655f0f50885 "newer a"
+  abort: unresolved merge conflicts (see 'hg help resolve')
+  [255]
+  $ hg resolve -m a
+  (no more unresolved files)
+  $ hg evolve --continue
+  grafting 5:3655f0f50885 "newer a"
+
+Stabilize latecomer with different parent
+=========================================
+
+(the same-parent case is handled in test-evolve.t)
+
+  $ glog
+  @  8:1cf0aacfd363@default(draft) bk:[] newer a
+  |
+  o  7:66719795a494@default(draft) bk:[changea] changea
+  |
+  o  0:07f494440405@default(draft) bk:[] adda
+  
+Add another commit
+
+  $ hg gdown
+  gdown have been deprecated in favor of previous
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [7] changea
+  $ echo 'c' > c
+  $ hg add c
+  $ hg commit -m 'add c'
+  created new head
+
+Get a successors of 8 on it
+
+  $ hg grab 8
+  rebasing 8:1cf0aacfd363 "newer a"
+  ? files updated, 0 files merged, 0 files removed, 0 files unresolved (glob)
+
+Add real change to the successors
+
+  $ echo 'babar' >> a
+  $ hg amend
+
+Make precursors public
+
+  $ hg phase --hidden --public 8
+  1 new bumped changesets
+  $ glog
+  @  12:(73b15c7566e9|d5c7ef82d003)@default\(draft\) bk:\[\] newer a (re)
+  |
+  o  9:7bc2f5967f5e@default(draft) bk:[] add c
+  |
+  | o  8:1cf0aacfd363@default(public) bk:[] newer a
+  |/
+  o  7:66719795a494@default(public) bk:[changea] changea
+  |
+  o  0:07f494440405@default(public) bk:[] adda
+  
+
+Stabilize!
+
+  $ hg evolve --any --dry-run --bumped
+  recreate:[12] newer a
+  atop:[8] newer a
+  hg rebase --rev (73b15c7566e9|d5c7ef82d003) --dest 66719795a494; (re)
+  hg update 1cf0aacfd363;
+  hg revert --all --rev (73b15c7566e9|d5c7ef82d003); (re)
+  hg commit --msg "bumped update to %s" (no-eol)
+  $ hg evolve --any --confirm --bumped
+  recreate:[12] newer a
+  atop:[8] newer a
+  perform evolve? [Ny] n
+  abort: evolve aborted by user
+  [255]
+  $ echo y | hg evolve --any --confirm --config ui.interactive=True --bumped
+  recreate:[12] newer a
+  atop:[8] newer a
+  perform evolve? [Ny] y
+  rebasing to destination parent: 66719795a494
+  computing new diff
+  committed as c2c1151aa854
+  working directory is now at c2c1151aa854
+  $ glog
+  @  14:c2c1151aa854@default(draft) bk:[] bumped update to 1cf0aacfd363:
+  |
+  | o  9:7bc2f5967f5e@default(draft) bk:[] add c
+  | |
+  o |  8:1cf0aacfd363@default(public) bk:[] newer a
+  |/
+  o  7:66719795a494@default(public) bk:[changea] changea
+  |
+  o  0:07f494440405@default(public) bk:[] adda
+  
+
+Stabilize divergent changesets with same parent
+===============================================
+
+  $ rm a.orig
+  $ hg up 9
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cat << EOF >> a
+  > flore
+  > arthur
+  > zephir
+  > some
+  > less
+  > conflict
+  > EOF
+  $ hg ci -m 'More addition'
+  $ glog
+  @  15:3932c176bbaa@default(draft) bk:[] More addition
+  |
+  | o  14:(a7cabd7bd9c2|671b9d7eeaec)@default\(draft\) bk:\[\] bumped update to 1cf0aacfd363: (re)
+  | |
+  o |  9:7bc2f5967f5e@default(draft) bk:[] add c
+  | |
+  | o  8:1cf0aacfd363@default(public) bk:[] newer a
+  |/
+  o  7:66719795a494@default(public) bk:[changea] changea
+  |
+  o  0:07f494440405@default(public) bk:[] adda
+  
+  $ echo 'babar' >> a
+  $ hg amend
+  $ hg up --hidden 15
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ mv a a.old
+  $ echo 'jungle' > a
+  $ cat a.old >> a
+  $ rm a.old
+  $ hg amend
+  2 new divergent changesets
+  $ glog
+  @  19:eacc9c8240fe@default(draft) bk:[] More addition
+  |
+  | o  17:d2f173e25686@default(draft) bk:[] More addition
+  |/
+  | o  14:(a7cabd7bd9c2|671b9d7eeaec)@default\(draft\) bk:\[\] bumped update to 1cf0aacfd363: (re)
+  | |
+  o |  9:7bc2f5967f5e@default(draft) bk:[] add c
+  | |
+  | o  8:1cf0aacfd363@default(public) bk:[] newer a
+  |/
+  o  7:66719795a494@default(public) bk:[changea] changea
+  |
+  o  0:07f494440405@default(public) bk:[] adda
+  
+
+Stabilize it
+
+  $ hg evolve -qn --confirm --divergent
+  merge:[19] More addition
+  with: [17] More addition
+  base: [15] More addition
+  perform evolve? [Ny] n
+  abort: evolve aborted by user
+  [255]
+  $ echo y | hg evolve -qn --confirm --config ui.interactive=True --divergent
+  merge:[19] More addition
+  with: [17] More addition
+  base: [15] More addition
+  perform evolve? [Ny] y
+  hg update -c eacc9c8240fe &&
+  hg merge d2f173e25686 &&
+  hg commit -m "auto merge resolving conflict between eacc9c8240fe and d2f173e25686"&&
+  hg up -C 3932c176bbaa &&
+  hg revert --all --rev tip &&
+  hg commit -m "`hg log -r eacc9c8240fe --template={desc}`";
+  $ hg evolve -v --divergent
+  merge:[19] More addition
+  with: [17] More addition
+  base: [15] More addition
+  merging divergent changeset
+  resolving manifests
+  merging a
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  amending changeset eacc9c8240fe
+  committing files:
+  a
+  committing manifest
+  committing changelog
+  copying changeset 283ccd10e2b8 to 7bc2f5967f5e
+  committing files:
+  a
+  committing manifest
+  committing changelog
+  committed changeset 21:f344982e63c4
+  working directory is now at f344982e63c4
+  $ hg st
+  $ glog
+  @  21:f344982e63c4@default(draft) bk:[] More addition
+  |
+  | o  14:(a7cabd7bd9c2|671b9d7eeaec)@default\(draft\) bk:\[\] bumped update to 1cf0aacfd363: (re)
+  | |
+  o |  9:7bc2f5967f5e@default(draft) bk:[] add c
+  | |
+  | o  8:1cf0aacfd363@default(public) bk:[] newer a
+  |/
+  o  7:66719795a494@default(public) bk:[changea] changea
+  |
+  o  0:07f494440405@default(public) bk:[] adda
+  
+  $ hg summary
+  parent: 21:f344982e63c4 tip
+   More addition
+  branch: default
+  commit: (clean)
+  update: 2 new changesets, 2 branch heads (merge)
+  phases: 3 draft
+  $ hg export .
+  # HG changeset patch
+  # User test
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID f344982e63c462b1e44c0371c804685389e673a9
+  # Parent  7bc2f5967f5e4ed277f60a89b7b04cc5d6407ced
+  More addition
+  
+  diff -r 7bc2f5967f5e -r f344982e63c4 a
+  --- a/a	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,9 @@
+  +jungle
+   a
+  +flore
+  +arthur
+  +zephir
+  +some
+  +less
+  +conflict
+  +babar
+
+Check conflict during divergence resolution
+-------------------------------------------------
+
+  $ hg up --hidden 15
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ echo 'gotta break' >> a
+  $ hg amend
+  2 new divergent changesets
+# reamend so that the case is not the first precursor.
+  $ hg amend -m "More addition (2)"
+  $ hg phase 'divergent()'
+  21: draft
+  24: draft
+  $ hg evolve -qn --divergent
+  hg update -c 0b336205a5d0 &&
+  hg merge f344982e63c4 &&
+  hg commit -m "auto merge resolving conflict between 0b336205a5d0 and f344982e63c4"&&
+  hg up -C 3932c176bbaa &&
+  hg revert --all --rev tip &&
+  hg commit -m "`hg log -r 0b336205a5d0 --template={desc}`";
+  $ hg evolve --divergent
+  merge:[24] More addition (2)
+  with: [21] More addition
+  base: [15] More addition
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abort
+  abort: merge conflict between several amendments (this is not automated yet)
+  (/!\ You can try:
+  /!\ * manual merge + resolve => new cset X
+  /!\ * hg up to the parent of the amended changeset (which are named W and Z)
+  /!\ * hg revert --all -r X
+  /!\ * hg ci -m "same message as the amended changeset" => new cset Y
+  /!\ * hg prune -n Y W Z
+  )
+  [255]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-touch.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,127 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > logtemplate={rev}:{node|short} {desc}\n
+  > [defaults]
+  > amend=-d "0 0"
+  > [extensions]
+  > hgext.rebase=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ hg init repo
+  $ cd repo
+  $ echo A > a
+  $ hg add a
+  $ hg commit -m a
+
+Basic usage
+
+  $ hg log -G
+  @  0:e93df3427f45 a
+  
+  $ hg touch .
+  $ hg log -G
+  @  1:[0-9a-f]{12} a (re)
+  
+
+
+Revive usage
+
+  $ echo A > b
+  $ hg add b
+  $ hg commit -m ab --amend
+  $ hg up --hidden 1
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ hg log -G
+  o  3:[0-9a-f]{12} ab (re)
+  
+  @  1:[0-9a-f]{12} a (re)
+  
+  $ hg touch .
+  [1] a
+  reviving this changeset will create divergence unless you make a duplicate.
+  (a)llow divergence or (d)uplicate the changeset?  a
+  2 new divergent changesets
+  $ hg log -G
+  @  4:[0-9a-f]{12} a (re)
+  
+  o  3:[0-9a-f]{12} ab (re)
+  
+  $ hg prune 3
+  1 changesets pruned
+
+Duplicate
+
+  $ hg touch --duplicate .
+  $ hg log -G
+  @  5:[0-9a-f]{12} a (re)
+  
+  o  4:[0-9a-f]{12} a (re)
+  
+
+Multiple touch
+
+  $ echo C > c
+  $ hg add c
+  $ hg commit -m c
+  $ echo D > d
+  $ hg add d
+  $ hg commit -m d
+  $ hg log -G
+  @  7:[0-9a-f]{12} d (re)
+  |
+  o  6:[0-9a-f]{12} c (re)
+  |
+  o  5:[0-9a-f]{12} a (re)
+  
+  o  4:[0-9a-f]{12} a (re)
+  
+  $ hg touch 6:7
+  $ hg log -G
+  @  9:[0-9a-f]{12} d (re)
+  |
+  o  8:[0-9a-f]{12} c (re)
+  |
+  o  5:[0-9a-f]{12} a (re)
+  
+  o  4:[0-9a-f]{12} a (re)
+  
+
+check move data kept after rebase on touch:
+
+  $ touch gna1
+  $ hg commit -Am gna1
+  adding gna1
+  $ hg mv gna1 gna2
+  $ hg commit -m move
+  $ hg st -C --change=tip
+  A gna2
+    gna1
+  R gna1
+  $ hg up .^
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+  $ hg touch
+  1 new unstable changesets
+
+  $ hg rebase -s 11 -d 12
+  rebasing 11:* "move" (glob)
+  $ hg st -C --change=tip
+  A gna2
+    gna1
+  R gna1
+
+check that the --duplicate option does not create divergence
+
+  $ hg touch --duplicate 11 --hidden
+  1 new unstable changesets
+
+check that reviving a changeset with no successor does not show the prompt
+
+  $ hg prune 14
+  1 changesets pruned
+  $ hg touch 14 --hidden
+  1 new unstable changesets
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-tutorial.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,858 @@
+
+Initial setup
+-------------
+
+This Mercurial configuration example is used for testing.
+.. Various setup
+
+  $ cat >> $HGRCPATH << EOF
+  > [ui]
+  > # This is change the default output of log for clear tutorial
+  > logtemplate ="{node|short} ({phase}): {desc}\n"
+  > [diff]
+  > # use "git" diff format, clearer and smarter format
+  > 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
+  > # (this tutorial is automatically tested.)
+  > amend = amend -d '0 0'
+  > 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 | grep log
+  ui.logtemplate="{node|short} ({phase}): {desc}\n"
+
+Improved git format diff:
+
+  $ hg showconfig diff
+  diff.git=1
+
+And of course, we enable the experimental extensions for mutable history:
+
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > evolve = $TESTDIR/../hgext3rd/evolve/
+  > # enabling rebase is also needed for now
+  > rebase =
+  > EOF
+
+-----------------------
+Single Developer Usage
+-----------------------
+
+This tutorial shows how to use evolution to rewrite history locally.
+
+
+Fixing mistake with `hg amend`
+--------------------------------
+
+We are versioning 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 (glob)
+  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 log -G
+  @  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
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # 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 log -G
+  @  d85de4546133 (draft): adding fruit
+  |
+  o  4d5dc8187023 (draft): adding condiment
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
+hopefully. I can use `hg commit --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 commit --amend
+
+A new changeset with the right diff replace the wrong one.
+
+  $ hg log -G
+  @  9d0363b81950 (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
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID 9d0363b81950646bc6ad1ec5de8b8197ea586541
+  # 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 made a change remotely.
+
+  $ 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 (glob)
+  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
+  |
+  | @  9d0363b81950 (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 --dest 9ca060c80d74 --source 4d5dc8187023
+  rebasing 1:4d5dc8187023 "adding condiment"
+  merging shopping
+  rebasing 4:9d0363b81950 "adding fruit"
+  merging shopping
+
+
+My local work is now rebased on the remote one.
+
+  $ hg log -G
+  @  41aff6a42b75 (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
+  @  1125e39fbf21 (draft): transport
+  |
+  o  41aff6a42b75 (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 41aff6a42b75
+  1 changesets pruned
+
+The silly changeset is gone.
+
+  $ hg log -G
+  @  41aff6a42b75 (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
+  @  fac207dec9f5 (draft): SPAM SPAM
+  |
+  o  10b8aeaa8cc8 (draft): bathroom stuff
+  |
+  o  41aff6a42b75 (draft): adding fruit
+  |
+  o  dfd3a2d7691e (draft): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
+.. note:: We can'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 the 'grab' alias for that.
+
+.. note: grab is an alias for `hg rebase --dest . --rev <target>; hg up <there>`
+
+  $ hg up 'p1(10b8aeaa8cc8)' # going on "bathroom stuff" parent
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg grab fac207dec9f5 # moving "SPAM SPAM" to the working directory parent
+  rebasing 10:fac207dec9f5 "SPAM SPAM" (tip)
+  merging shopping
+  ? files updated, 0 files merged, 0 files removed, 0 files unresolved (glob)
+  $ hg log -G
+  @  a224f2a4fb9f (draft): SPAM SPAM
+  |
+  | o  10b8aeaa8cc8 (draft): bathroom stuff
+  |/
+  o  41aff6a42b75 (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
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID a224f2a4fb9f9f828f608959912229d7b38b26de
+  # Parent  41aff6a42b7578ec7ec3cb2041633f1ca43cca96
+  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 10b8aeaa8cc8
+
+we can now push our change:
+
+  $ hg push remote
+  pushing to $TESTTMP/remote (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 1 files
+  6 new obsolescence markers
+
+for simplicity sake we get the bathroom change in line again
+
+  $ hg grab 10b8aeaa8cc8
+  rebasing 9:10b8aeaa8cc8 "bathroom stuff"
+  merging shopping
+  ? files updated, 0 files merged, 0 files removed, 0 files unresolved (glob)
+  $ hg phase --draft .
+  $ hg log -G
+  @  75954b8cd933 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
+
+
+Splitting change
+------------------
+
+This part is not written yet, but you can use either the `histedit` extension
+of the `uncommit` command to splitting a change.
+
+  $ hg help uncommit
+  hg uncommit [OPTION]... [NAME]
+  
+  move changes from parent revision to working directory
+  
+      Changes to selected files in the checked out revision appear again as
+      uncommitted changed in the working directory. A new revision without the
+      selected changes is created, becomes the checked out revision, and
+      obsoletes the previous one.
+  
+      The --include option specifies patterns to uncommit. The --exclude option
+      specifies patterns to keep in the commit.
+  
+      The --rev argument let you change the commit file to a content of another
+      revision. It still does not change the content of your file in the working
+      directory.
+  
+      Return 0 if changed files are uncommitted.
+  
+  options ([+] can be repeated):
+  
+   -a --all                 uncommit all changes when no arguments given
+   -r --rev VALUE           revert commit content to REV instead
+   -I --include PATTERN [+] include names matching the given patterns
+   -X --exclude PATTERN [+] exclude names matching the given patterns
+  
+  (some details hidden, use --verbose to show complete help)
+
+
+The edit command of histedit can be used to split changeset:
+
+
+Collapsing change
+------------------
+
+The tutorial part is not written yet but can use `hg fold`:
+
+  $ hg help fold
+  hg fold [OPTION]... [-r] REV
+  
+  aliases: squash
+  
+  fold multiple revisions into a single one
+  
+      With --from, folds all the revisions linearly between the given revisions
+      and the parent of the working directory.
+  
+      With --exact, folds only the specified revisions while ignoring the parent
+      of the working directory. In this case, the given revisions must form a
+      linear unbroken chain.
+  
+  options ([+] can be repeated):
+  
+   -r --rev VALUE [+] revision to fold
+      --exact         only fold specified revisions
+      --from          fold revisions linearly to working copy parent
+   -m --message TEXT  use text as commit message
+   -l --logfile FILE  read commit message from file
+   -d --date DATE     record the specified date as commit date
+   -u --user USER     record the specified user as committer
+  
+  (some details hidden, use --verbose to show complete help)
+
+
+-----------------------
+Collaboration
+-----------------------
+
+
+sharing mutable changesets
+----------------------------
+
+To share mutable changesets 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
+  [1]
+
+the localrepo does not have any specific configuration for `phases.publish`. It
+is ``true`` by default.
+
+  $ hg pull local
+  pulling from $TESTTMP/local (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  $ hg log -G
+  o  75954b8cd933 (public): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (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.
+
+.. Warning: Rollback is actually a dangerous kind of internal command that is deprecated and should not be exposed to user. Please forget you read about it until someone fix this tutorial.
+
+  $ hg rollback
+  repository tip rolled back to revision 4 (undo pull)
+  $ hg log -G
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (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 (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  1 new obsolescence markers
+  (run 'hg update' to get a working copy)
+  $ hg log -G
+  o  75954b8cd933 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (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 75954b8cd933 -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 75954b8cd933 -q
+  $ sed -i'' -e 's/... More bathroom stuff to come/Bath Robe/' shopping
+  $ hg commit --amend
+  $ hg log -G
+  @  a44c85f957d3 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (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 (glob)
+  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 unstable 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  bf1b0d202029 (draft): animals
+  |
+  | @  a44c85f957d3 (draft): bathroom stuff
+  | |
+  x |  75954b8cd933 (draft): bathroom stuff
+  |/
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
+The older version 75954b8cd933 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 a44c85f957d3 as a new version of 75954b8cd933. 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 (glob)
+  searching for changes
+  abort: push includes unstable changeset: bf1b0d202029!
+  (use 'hg evolve' to get a stable history or --force to ignore warnings)
+  [255]
+ 
+
+
+
+To resolve this unstable state, you need to rebase bf1b0d202029 onto
+a44c85f957d3. The `hg evolve` command will do this for you.
+
+It has a --dry-run option to only suggest the next move.
+
+  $ hg evolve --dry-run
+  move:[15] animals
+  atop:[14] bathroom stuff
+  hg rebase -r bf1b0d202029 -d a44c85f957d3
+
+Let's do it
+
+  $ hg evolve
+  move:[15] animals
+  atop:[14] bathroom stuff
+  merging shopping
+  working directory is now at ee942144f952
+
+The old version of bathroom is hidden again.
+
+  $ hg log -G
+  @  ee942144f952 (draft): animals
+  |
+  o  a44c85f957d3 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (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 (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 1 files (+1 heads)
+  3 new obsolescence markers
+
+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 (glob)
+  searching for changes
+  no changes found
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+
+now let's see where we are, and update to the successor
+
+  $ hg parents
+  bf1b0d202029 (draft): animals
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ hg evolve
+  update:[8] animals
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at ee942144f952
+
+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 (glob)
+  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  99f039c5ec9e (draft): SPAM SPAM SPAM
+  |
+  @  ee942144f952 (draft): animals
+  |
+  o  a44c85f957d3 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (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 ee942144f952
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory now at a44c85f957d3
+  1 changesets pruned
+  1 new unstable 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  99f039c5ec9e (draft): SPAM SPAM SPAM
+  |
+  x  ee942144f952 (draft): animals
+  |
+  @  a44c85f957d3 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
+  $ hg log -r 'unstable()'
+  99f039c5ec9e (draft): SPAM SPAM SPAM
+
+  $ hg evolve
+  move:[17] SPAM SPAM SPAM
+  atop:[14] bathroom stuff
+  merging shopping
+  working directory is now at 40aa40daeefb
+
+  $ hg log -G
+  @  40aa40daeefb (draft): SPAM SPAM SPAM
+  |
+  o  a44c85f957d3 (draft): bathroom stuff
+  |
+  o  a224f2a4fb9f (public): SPAM SPAM
+  |
+  o  41aff6a42b75 (public): adding fruit
+  |
+  o  dfd3a2d7691e (public): adding condiment
+  |
+  o  9ca060c80d74 (public): SPAM
+  |
+  o  7e82d3f3c2cb (public): Monthy Python Shopping list
+  
+
+
+Handling Divergent amend
+----------------------------------------------
+
+We can detect that multiple diverging amendments have been made.
+The `evolve` command can solve this situation. But all corner case are not
+handled now.
+
+This section needs to be written.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-uncommit.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,364 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ glog() {
+  >   hg glog --template '{rev}:{node|short}@{branch}({separate("/", obsolete, phase)}) {desc|firstline}\n' "$@"
+  > }
+
+  $ hg init repo
+  $ cd repo
+
+Cannot uncommit null changeset
+
+  $ hg uncommit
+  abort: cannot rewrite immutable changeset
+  [255]
+
+Cannot uncommit public changeset
+
+  $ echo a > a
+  $ hg ci -Am adda a
+  $ hg phase --public .
+  $ hg uncommit
+  abort: cannot rewrite immutable changeset
+  [255]
+  $ hg phase --force --draft .
+
+Cannot uncommit merge
+
+  $ hg up -q null
+  $ echo b > b
+  $ echo c > c
+  $ echo d > d
+  $ echo f > f
+  $ echo g > g
+  $ echo j > j
+  $ echo m > m
+  $ echo n > n
+  $ echo o > o
+  $ hg ci -Am addmore
+  adding b
+  adding c
+  adding d
+  adding f
+  adding g
+  adding j
+  adding m
+  adding n
+  adding o
+  created new head
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg uncommit
+  abort: cannot uncommit while merging
+  [255]
+  $ hg ci -m merge
+  $ hg uncommit
+  abort: cannot uncommit merge changeset
+  [255]
+
+Prepare complicated changeset
+
+  $ hg branch bar
+  marked working directory as branch bar
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg cp a aa
+  $ echo b >> b
+  $ hg rm c
+  $ echo d >> d
+  $ echo e > e
+  $ hg mv f ff
+  $ hg mv g h
+  $ echo j >> j
+  $ echo k > k
+  $ echo l > l
+  $ hg rm m
+  $ hg rm n
+  $ echo o >> o
+  $ hg ci -Am touncommit
+  adding e
+  adding k
+  adding l
+  $ hg st --copies --change .
+  M b
+  M d
+  M j
+  M o
+  A aa
+    a
+  A e
+  A ff
+    f
+  A h
+    g
+  A k
+  A l
+  R c
+  R f
+  R g
+  R m
+  R n
+  $ hg man -r .
+  a
+  aa
+  b
+  d
+  e
+  ff
+  h
+  j
+  k
+  l
+  o
+
+Add a couple of bookmarks
+
+  $ glog --hidden
+  @  3:5eb72dbe0cb4@bar(draft) touncommit
+  |
+  o    2:f63b90038565@default(draft) merge
+  |\
+  | o  1:f15c744d48e8@default(draft) addmore
+  |
+  o  0:07f494440405@default(draft) adda
+  
+  $ hg bookmark -r 2 unrelated
+  $ hg bookmark touncommit-bm
+  $ hg bookmark --inactive touncommit-bm-inactive
+  $ hg bookmarks
+   * touncommit-bm             3:5eb72dbe0cb4
+     touncommit-bm-inactive    3:5eb72dbe0cb4
+     unrelated                 2:f63b90038565
+
+Prepare complicated working directory
+
+  $ hg branch foo
+  marked working directory as branch foo
+  $ hg mv ff f
+  $ hg mv h i
+  $ hg rm j
+  $ hg rm k
+  $ echo l >> l
+  $ echo m > m
+  $ echo o > o
+
+Test uncommit without argument, should be a no-op
+
+  $ hg uncommit
+  abort: nothing to uncommit
+  (use --all to uncommit all files)
+  [255]
+  $ hg bookmarks
+   * touncommit-bm             3:5eb72dbe0cb4
+     touncommit-bm-inactive    3:5eb72dbe0cb4
+     unrelated                 2:f63b90038565
+
+Test no matches
+
+  $ hg uncommit --include nothere
+  abort: nothing to uncommit
+  (use --all to uncommit all files)
+  [255]
+
+Enjoy uncommit
+
+  $ hg uncommit aa b c f ff g h j k l m o
+  $ hg branch
+  foo
+  $ hg st --copies
+  M b
+  A aa
+    a
+  A i
+    g
+  A l
+  R c
+  R g
+  R j
+  R m
+  $ cat aa
+  a
+  $ cat b
+  b
+  b
+  $ cat l
+  l
+  l
+  $ cat m
+  m
+  $ test -f c && echo 'error: c was removed!'
+  [1]
+  $ test -f j && echo 'error: j was removed!'
+  [1]
+  $ test -f k && echo 'error: k was removed!'
+  [1]
+  $ hg st --copies --change .
+  M d
+  A e
+  R n
+  $ hg man -r .
+  a
+  b
+  c
+  d
+  e
+  f
+  g
+  j
+  m
+  o
+  $ hg cat -r . d
+  d
+  d
+  $ hg cat -r . e
+  e
+  $ glog --hidden
+  @  4:e8db4aa611f6@bar(draft) touncommit
+  |
+  | x  3:5eb72dbe0cb4@bar(obsolete/draft) touncommit
+  |/
+  o    2:f63b90038565@default(draft) merge
+  |\
+  | o  1:f15c744d48e8@default(draft) addmore
+  |
+  o  0:07f494440405@default(draft) adda
+  
+  $ hg bookmarks
+   * touncommit-bm             4:e8db4aa611f6
+     touncommit-bm-inactive    4:e8db4aa611f6
+     unrelated                 2:f63b90038565
+  $ hg debugobsolete
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 e8db4aa611f6d5706374288e6898e498f5c44098 0 (*) {'user': 'test'} (glob)
+
+Test phase is preserved, no local changes
+
+  $ hg up -C 3 --hidden
+  8 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (leaving bookmark touncommit-bm)
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ hg --config extensions.purge= purge
+  $ hg uncommit -I 'set:added() and e'
+  2 new divergent changesets
+  $ hg st --copies
+  A e
+  $ hg st --copies --change .
+  M b
+  M d
+  M j
+  M o
+  A aa
+    a
+  A ff
+    f
+  A h
+    g
+  A k
+  A l
+  R c
+  R f
+  R g
+  R m
+  R n
+  $ glog --hidden
+  @  5:a1d4c1ad76cc@bar(draft) touncommit
+  |
+  | o  4:e8db4aa611f6@bar(draft) touncommit
+  |/
+  | x  3:5eb72dbe0cb4@bar(obsolete/draft) touncommit
+  |/
+  o    2:f63b90038565@default(draft) merge
+  |\
+  | o  1:f15c744d48e8@default(draft) addmore
+  |
+  o  0:07f494440405@default(draft) adda
+  
+  $ hg debugobsolete
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 e8db4aa611f6d5706374288e6898e498f5c44098 0 (*) {'user': 'test'} (glob)
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 a1d4c1ad76cc7eb5e8a36ef52396da334b6d59c5 0 (*) {'user': 'test'} (glob)
+
+Test --all
+
+  $ hg up -C 3 --hidden
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory parent is obsolete!
+  (use 'hg evolve' to update to its successor)
+  $ hg --config extensions.purge= purge
+  $ hg uncommit --all -X e
+  1 new divergent changesets
+  $ hg st --copies
+  M b
+  M d
+  M j
+  M o
+  A aa
+    a
+  A ff
+    f
+  A h
+    g
+  A k
+  A l
+  R c
+  R f
+  R g
+  R m
+  R n
+  $ hg st --copies --change .
+  A e
+
+  $ hg debugobsolete
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 e8db4aa611f6d5706374288e6898e498f5c44098 0 (*) {'user': 'test'} (glob)
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 a1d4c1ad76cc7eb5e8a36ef52396da334b6d59c5 0 (*) {'user': 'test'} (glob)
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 c4cbebac3751269bdf12d1466deabcc78521d272 0 (*) {'user': 'test'} (glob)
+
+Display a warning if nothing left
+
+  $ hg uncommit e
+  new changeset is empty
+  (use 'hg prune .' to remove it)
+  $ hg debugobsolete
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 e8db4aa611f6d5706374288e6898e498f5c44098 0 (*) {'user': 'test'} (glob)
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 a1d4c1ad76cc7eb5e8a36ef52396da334b6d59c5 0 (*) {'user': 'test'} (glob)
+  5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 c4cbebac3751269bdf12d1466deabcc78521d272 0 (*) {'user': 'test'} (glob)
+  c4cbebac3751269bdf12d1466deabcc78521d272 4f1c269eab68720f54e88ce3c1dc02b2858b6b89 0 (*) {'user': 'test'} (glob)
+
+Test instability warning
+
+  $ hg ci -m touncommit
+  $ echo unrelated > unrelated
+  $ hg ci -Am addunrelated unrelated
+  $ hg previous
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [8] touncommit
+  $ hg uncommit aa
+  1 new unstable changesets
+
+Test uncommiting agains a different base
+
+  $ hg cat b --rev .
+  b
+  b
+  $ hg cat b --rev .^
+  b
+  $ hg cat b --rev 0
+  b: no such file in rev 07f494440405
+  [1]
+  $ hg uncommit --rev . b
+  abort: cannot uncommit to parent changeset
+  [255]
+  $ hg uncommit --rev 0 b
+  $ hg cat b --rev .
+  b: no such file in rev 5b27f6b17da2
+  [1]
+
+Test uncommiting precursors
+
+  $ hg uncommit --hidden --rev 'precursors(.)' b
+  $ hg cat b --rev .
+  b
+  b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-unstable.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,321 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ mkstack() {
+  >    # Creates a stack of commit based on $1 with messages from $2, $3 ..
+  >    hg update "$1" -C
+  >    shift
+  >    mkcommits $*
+  > }
+
+  $ mkcommits() {
+  >   for i in $@; do mkcommit $i ; done
+  > }
+
+==============================================================================
+Test instability resolution for a changeset unstable because its parent
+is obsolete with one successor
+==============================================================================
+  $ hg init test1
+  $ cd test1
+  $ mkcommits _a _b _c
+  $ hg up "desc(_b)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg amend -m "bprime"
+  1 new unstable changesets
+  $ hg log -G
+  @  3:36050226a9b9@default(draft) bprime
+  |
+  | o  2:102002290587@default(draft) add _c
+  | |
+  | x  1:37445b16603b@default(draft) add _b
+  |/
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+  $ hg evo --all --any --unstable
+  move:[2] add _c
+  atop:[3] bprime
+  working directory is now at fdcf3523a74d
+  $ hg log -G
+  @  4:fdcf3523a74d@default(draft) add _c
+  |
+  o  3:36050226a9b9@default(draft) bprime
+  |
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+  $ cd ..
+
+===============================================================================
+Test instability resolution for a merge changeset unstable because one
+of its parent is obsolete
+Not supported yet
+==============================================================================
+
+  $ hg init test2
+  $ cd test2
+  $ mkcommit base
+  $ mkcommits _a
+  $ hg up "desc(base)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit _c
+  created new head
+  $ hg merge "desc(_a)" >/dev/null
+  $ hg commit -m "merge"
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg amend -m "aprime"
+  1 new unstable changesets
+  $ hg log -G
+  @  4:47127ea62e5f@default(draft) aprime
+  |
+  | o    3:6b4280e33286@default(draft) merge
+  | |\
+  +---o  2:474da87dd33b@default(draft) add _c
+  | |
+  | x  1:b3264cec9506@default(draft) add _a
+  |/
+  o  0:b4952fcf48cf@default(draft) add base
+  
+
+  $ hg evo --all --any --unstable
+  move:[3] merge
+  atop:[4] aprime
+  working directory is now at 0bf3f3a59c8c
+  $ hg log -G
+  @    5:0bf3f3a59c8c@default(draft) merge
+  |\
+  | o  4:47127ea62e5f@default(draft) aprime
+  | |
+  o |  2:474da87dd33b@default(draft) add _c
+  |/
+  o  0:b4952fcf48cf@default(draft) add base
+  
+
+  $ cd ..
+
+===============================================================================
+Test instability resolution for a merge changeset unstable because both
+of its parent are obsolete
+Not supported yet
+==============================================================================
+
+  $ hg init test3
+  $ cd test3
+  $ mkcommit base
+  $ mkcommits _a
+  $ hg up "desc(base)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit _c
+  created new head
+  $ hg merge "desc(_a)" >/dev/null
+  $ hg commit -m "merge"
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg amend -m "aprime"
+  1 new unstable changesets
+  $ hg up "desc(_c)"
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg amend -m "cprime"
+  $ hg log -G
+  @  5:2db39fda7e2f@default(draft) cprime
+  |
+  | o  4:47127ea62e5f@default(draft) aprime
+  |/
+  | o    3:6b4280e33286@default(draft) merge
+  | |\
+  +---x  2:474da87dd33b@default(draft) add _c
+  | |
+  | x  1:b3264cec9506@default(draft) add _a
+  |/
+  o  0:b4952fcf48cf@default(draft) add base
+  
+
+  $ hg evo --all --any --unstable
+  warning: no support for evolving merge changesets with two obsolete parents yet
+  (Redo the merge (6b4280e33286) and use `hg prune <old> --succ <new>` to obsolete the old one)
+  $ hg log -G
+  @  5:2db39fda7e2f@default(draft) cprime
+  |
+  | o  4:47127ea62e5f@default(draft) aprime
+  |/
+  | o    3:6b4280e33286@default(draft) merge
+  | |\
+  +---x  2:474da87dd33b@default(draft) add _c
+  | |
+  | x  1:b3264cec9506@default(draft) add _a
+  |/
+  o  0:b4952fcf48cf@default(draft) add base
+  
+
+  $ cd ..
+
+===============================================================================
+Test instability resolution for a changeset unstable because its parent
+is obsolete with multiple successors all in one chain (simple split)
+==============================================================================
+
+  $ hg init test4
+  $ cd test4
+  $ mkcommits _a _b _c
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommits bprimesplit1 bprimesplit2
+  created new head
+  $ hg prune "desc(_b)" -s "desc(bprimesplit1) + desc(bprimesplit2)" --split
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg log -G
+  @  4:2a4ccc0bb20c@default(draft) add bprimesplit2
+  |
+  o  3:8b87864bd0f4@default(draft) add bprimesplit1
+  |
+  | o  2:102002290587@default(draft) add _c
+  | |
+  | x  1:37445b16603b@default(draft) add _b
+  |/
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+  $ hg evo --all --any --unstable
+  move:[2] add _c
+  atop:[4] add bprimesplit2
+  working directory is now at 387cc1e837d7
+  $ hg log -G
+  @  5:387cc1e837d7@default(draft) add _c
+  |
+  o  4:2a4ccc0bb20c@default(draft) add bprimesplit2
+  |
+  o  3:8b87864bd0f4@default(draft) add bprimesplit1
+  |
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+
+  $ cd ..
+
+===============================================================================
+Test instability resolution for a changeset unstable because its parent
+is obsolete with multiple successors on one branches but in reverse
+order (cross-split).
+==============================================================================
+
+  $ hg init test5
+  $ cd test5
+  $ mkcommits _a _b _c
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommits bprimesplit1 bprimesplit2
+  created new head
+  $ hg prune "desc(_b)" -s "desc(bprimesplit1) + desc(bprimesplit2)" --split
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommits bsecondsplit1 bsecondsplit2
+  created new head
+  $ hg prune "desc(bprimesplit1)" -s "desc(bsecondsplit2)"
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg prune "desc(bprimesplit2)" -s "desc(bsecondsplit1)"
+  1 changesets pruned
+  $ hg log -G
+  @  6:59b942dbda14@default(draft) add bsecondsplit2
+  |
+  o  5:8ffdae67d696@default(draft) add bsecondsplit1
+  |
+  | o  2:102002290587@default(draft) add _c
+  | |
+  | x  1:37445b16603b@default(draft) add _b
+  |/
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+  $ hg evo --all --any --unstable
+  move:[2] add _c
+  atop:[6] add bsecondsplit2
+  working directory is now at 98e3f21461ff
+  $ hg log -G
+  @  7:98e3f21461ff@default(draft) add _c
+  |
+  o  6:59b942dbda14@default(draft) add bsecondsplit2
+  |
+  o  5:8ffdae67d696@default(draft) add bsecondsplit1
+  |
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+
+  $ cd ..
+
+===============================================================================
+Test instability resolution for a changeset unstable because its parent
+is obsolete with multiple successors on two branches.
+Not supported yet
+==============================================================================
+
+  $ hg init test6
+  $ cd test6
+  $ mkcommits _a _b _c
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit bprimesplit1
+  created new head
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bprimesplit2
+  created new head
+  $ hg prune "desc(_b)" -s "desc(bprimesplit1) + desc(bprimesplit2)" --split
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg log -G
+  @  4:3c69ea6aa93e@default(draft) add bprimesplit2
+  |
+  | o  3:8b87864bd0f4@default(draft) add bprimesplit1
+  |/
+  | o  2:102002290587@default(draft) add _c
+  | |
+  | x  1:37445b16603b@default(draft) add _b
+  |/
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+  $ hg evo --all --any --unstable
+  cannot solve split accross two branches
+  $ hg log -G
+  @  4:3c69ea6aa93e@default(draft) add bprimesplit2
+  |
+  | o  3:8b87864bd0f4@default(draft) add bprimesplit1
+  |/
+  | o  2:102002290587@default(draft) add _c
+  | |
+  | x  1:37445b16603b@default(draft) add _b
+  |/
+  o  0:135f39f4bd78@default(draft) add _a
+  
+
+
+  $ cd ..
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-userguide.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,333 @@
+ensure that all the scenarios in the user guide work as documented
+
+basic repo
+  $ hg init t
+  $ cd t
+  $ touch file1.c file2.c
+  $ hg -q commit -A -m init
+
+example 1: commit creates a changeset in draft phase
+(this is nothing to do with evolve, but it's mentioned in the user guide)
+  $ echo 'feature Y' >> file1.c
+  $ hg commit -u alice -d '0 0' -m 'implement feature X'
+  $ hg phase -r .
+  1: draft
+  $ hg identify -in
+  6e725fd2be6f 1
+
+example 2: unsafe amend with plain vanilla Mercurial: the original
+commit is stripped
+  $ hg commit --amend -u alice -d '1 0' -m 'implement feature Y'
+  saved backup bundle to $TESTTMP/t/.hg/strip-backup/6e725fd2be6f-42cc74d4-amend-backup.hg (glob)
+  $ hg log -r 23fe4ac6d3f1
+  abort: unknown revision '23fe4ac6d3f1'!
+  [255]
+  $ hg identify -in
+  fe0ecd3bd2a4 1
+
+enable evolve for safe history modification
+  $ cat >> $HGRCPATH <<EOF
+  > [alias]
+  > shortlog = log --template '{rev}:{node|short}  {phase}  {desc|firstline}\n'
+  > [extensions]
+  > rebase =
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+example 3: safe amend with "hg commit --amend" (figure 2)
+  $ echo 'tweak feature Y' >> file1.c
+  $ hg commit --amend -u alice -d '2 0' -m 'implement feature Y'
+  $ hg shortlog -q -r fe0ecd3bd2a4
+  abort: hidden revision 'fe0ecd3bd2a4'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg --hidden shortlog -G
+  @  3:934359450037  draft  implement feature Y
+  |
+  | x  2:6c5f78d5d467  draft  temporary amend commit for fe0ecd3bd2a4
+  | |
+  | x  1:fe0ecd3bd2a4  draft  implement feature Y
+  |/
+  o  0:08c4b6f4efc8  draft  init
+  
+example 3 redux: repeat safe amend, this time with "hg amend"
+  $ hg rollback -q
+  $ hg amend -u alice -d '2 0' -m 'implement feature Y'
+  $ hg --hidden shortlog -G
+  @  3:934359450037  draft  implement feature Y
+  |
+  | x  2:6c5f78d5d467  draft  temporary amend commit for fe0ecd3bd2a4
+  | |
+  | x  1:fe0ecd3bd2a4  draft  implement feature Y
+  |/
+  o  0:08c4b6f4efc8  draft  init
+  
+example 4: prune at head (figure 3)
+  $ echo 'debug hack' >> file1.c
+  $ hg commit -m 'debug hack'
+  $ hg prune .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory now at 934359450037
+  1 changesets pruned
+  $ hg parents --template '{rev}:{node|short}  {desc|firstline}\n'
+  3:934359450037  implement feature Y
+  $ hg --hidden shortlog -G -r 3:
+  x  4:a3e0ef24aaf0  draft  debug hack
+  |
+  @  3:934359450037  draft  implement feature Y
+  |
+  ~
+
+example 5: uncommit files at head (figure 4)
+  $ echo 'relevant' >> file1.c
+  $ echo 'irrelevant' >> file2.c
+  $ hg commit -u dan -d '10 0' -m 'fix bug 234'
+  $ hg uncommit file2.c
+  $ hg status
+  M file2.c
+  $ hg --hidden shortlog -G -r 'descendants(3) - 4'
+  @  6:c8defeecf7a4  draft  fix bug 234
+  |
+  | x  5:da4331967f5f  draft  fix bug 234
+  |/
+  o  3:934359450037  draft  implement feature Y
+  |
+  ~
+  $ hg parents --template '{rev}:{node|short}  {desc|firstline}\n{files}\n'
+  6:c8defeecf7a4  fix bug 234
+  file1.c
+  $ hg revert --no-backup file2.c
+
+example 6: fold multiple changesets together into one (figure 5)
+  $ echo step1 >> file1.c
+  $ hg commit -m 'step 1'
+  $ echo step2 >> file1.c
+  $ hg commit -m 'step 2'
+  $ echo step3 >> file2.c
+  $ hg commit -m 'step 3'
+  $ hg log --template '{rev}:{node|short}  {desc|firstline}\n' -r 7::
+  7:05e61aab8294  step 1
+  8:be6d5bc8e4cc  step 2
+  9:35f432d9f7c1  step 3
+  $ hg fold -d '0 0' -m 'fix bug 64' --from -r 7::
+  3 changesets folded
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg --hidden shortlog -G -r 6::
+  @  10:171c6a79a27b  draft  fix bug 64
+  |
+  | x  9:35f432d9f7c1  draft  step 3
+  | |
+  | x  8:be6d5bc8e4cc  draft  step 2
+  | |
+  | x  7:05e61aab8294  draft  step 1
+  |/
+  o  6:c8defeecf7a4  draft  fix bug 234
+  |
+  ~
+  $ hg --hidden log -q -r 'successors(7) | successors(8) | successors(9)'
+  10:171c6a79a27b
+  $ hg --hidden log -q -r 'precursors(10)'
+  7:05e61aab8294
+  8:be6d5bc8e4cc
+  9:35f432d9f7c1
+  $ hg diff -c 10 -U 0
+  diff -r c8defeecf7a4 -r 171c6a79a27b file1.c
+  --- a/file1.c	Thu Jan 01 00:00:10 1970 +0000
+  +++ b/file1.c	Thu Jan 01 00:00:00 1970 +0000
+  @@ -3,0 +4,2 @@
+  +step1
+  +step2
+  diff -r c8defeecf7a4 -r 171c6a79a27b file2.c
+  --- a/file2.c	Thu Jan 01 00:00:10 1970 +0000
+  +++ b/file2.c	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +step3
+
+setup for example 7: amend an older changeset
+  $ echo 'fix fix oops fix' > file2.c
+  $ hg commit -u bob -d '3 0' -m 'fix bug 17'
+  $ echo 'cleanup' >> file1.c
+  $ hg commit -u bob -d '4 0' -m 'cleanup'
+  $ echo 'new feature' >> file1.c
+  $ hg commit -u bob -d '5 0' -m 'feature 23'
+  $ hg --hidden shortlog -G -r 10::
+  @  13:dadcbba2d606  draft  feature 23
+  |
+  o  12:debd46bb29dc  draft  cleanup
+  |
+  o  11:3e1cb8f70c02  draft  fix bug 17
+  |
+  o  10:171c6a79a27b  draft  fix bug 64
+  |
+  ~
+
+example 7: amend an older changeset (figures 6, 7)
+  $ hg update -q 11
+  $ echo 'fix fix fix fix' > file2.c
+  $ hg amend -u bob -d '6 0'
+  2 new unstable changesets
+  $ hg shortlog -r 'obsolete()'
+  11:3e1cb8f70c02  draft  fix bug 17
+  $ hg shortlog -r 'unstable()'
+  12:debd46bb29dc  draft  cleanup
+  13:dadcbba2d606  draft  feature 23
+  $ hg --hidden shortlog -G -r 10::
+  @  15:395cbeda3a06  draft  fix bug 17
+  |
+  | x  14:f7fab707e247  draft  temporary amend commit for 3e1cb8f70c02
+  | |
+  | | o  13:dadcbba2d606  draft  feature 23
+  | | |
+  | | o  12:debd46bb29dc  draft  cleanup
+  | |/
+  | x  11:3e1cb8f70c02  draft  fix bug 17
+  |/
+  o  10:171c6a79a27b  draft  fix bug 64
+  |
+  ~
+  $ hg evolve -q --all
+  $ hg shortlog -G -r 10::
+  @  17:91b4b0f8b5c5  draft  feature 23
+  |
+  o  16:fe8858bd9bc2  draft  cleanup
+  |
+  o  15:395cbeda3a06  draft  fix bug 17
+  |
+  o  10:171c6a79a27b  draft  fix bug 64
+  |
+  ~
+
+setup for example 8: prune an older changeset (figure 8)
+  $ echo 'useful' >> file1.c
+  $ hg commit -u carl -d '7 0' -m 'useful work'
+  $ echo 'debug' >> file2.c
+  $ hg commit -u carl -d '8 0' -m 'debug hack'
+  $ echo 'more useful' >> file1.c
+  $ hg commit -u carl -d '9 0' -m 'more work'
+  $ hg shortlog -G -r 17::
+  @  20:ea8fafca914b  draft  more work
+  |
+  o  19:b23d06b457a8  draft  debug hack
+  |
+  o  18:1f33e68b18b9  draft  useful work
+  |
+  o  17:91b4b0f8b5c5  draft  feature 23
+  |
+  ~
+
+example 8: prune an older changeset (figures 8, 9)
+  $ hg prune 19
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg --hidden shortlog -G -r 18::
+  @  20:ea8fafca914b  draft  more work
+  |
+  x  19:b23d06b457a8  draft  debug hack
+  |
+  o  18:1f33e68b18b9  draft  useful work
+  |
+  ~
+  $ hg evolve -q --all --any
+  $ hg --hidden shortlog -G -r 18::
+  @  21:4393e5877437  draft  more work
+  |
+  | x  20:ea8fafca914b  draft  more work
+  | |
+  | x  19:b23d06b457a8  draft  debug hack
+  |/
+  o  18:1f33e68b18b9  draft  useful work
+  |
+  ~
+
+example 9: uncommit files from an older changeset (discard changes)
+(figure 10)
+  $ echo 'this fixes bug 53' >> file1.c
+  $ echo 'debug hack' >> file2.c
+  $ hg commit -u dan -d '11 0' -m 'fix bug 53'
+  $ echo 'and this handles bug 67' >> file1.c
+  $ hg commit -u dan -d '12 0' -m 'fix bug 67'
+  $ hg update 22
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg shortlog -G -r 21::
+  o  23:4db2428c8ae3  draft  fix bug 67
+  |
+  @  22:f84357446753  draft  fix bug 53
+  |
+  o  21:4393e5877437  draft  more work
+  |
+  ~
+  $ hg uncommit file2.c
+  1 new unstable changesets
+  $ hg status
+  M file2.c
+  $ hg revert file2.c
+  $ hg evolve --all --any
+  move:[23] fix bug 67
+  atop:[24] fix bug 53
+  working directory is now at 0d972d6888e6
+  $ hg --hidden shortlog -G -r 21::
+  @  25:0d972d6888e6  draft  fix bug 67
+  |
+  o  24:71bb83d674c5  draft  fix bug 53
+  |
+  | x  23:4db2428c8ae3  draft  fix bug 67
+  | |
+  | x  22:f84357446753  draft  fix bug 53
+  |/
+  o  21:4393e5877437  draft  more work
+  |
+  ~
+  $ rm file2.c.orig
+
+example 10: uncommit files from an older changeset (keep changes)
+(figures 11, 12)
+  $ echo 'fix a bug' >> file1.c
+  $ echo 'useful but unrelated' >> file2.c
+  $ hg commit -u dan -d '11 0' -m 'fix a bug'
+  $ echo 'new feature' >> file1.c
+  $ hg commit -u dan -d '12 0' -m 'new feature'
+  $ hg update 26
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg --hidden shortlog -G -r 25::
+  o  27:fbb3c6d50427  draft  new feature
+  |
+  @  26:5b31a1239ab9  draft  fix a bug
+  |
+  o  25:0d972d6888e6  draft  fix bug 67
+  |
+  ~
+  $ hg uncommit file2.c
+  1 new unstable changesets
+  $ hg status
+  M file2.c
+  $ hg commit -m 'useful tweak'
+  $ hg --hidden shortlog -G -r 25::
+  @  29:51e0d8c0a922  draft  useful tweak
+  |
+  o  28:2594e98553a9  draft  fix a bug
+  |
+  | o  27:fbb3c6d50427  draft  new feature
+  | |
+  | x  26:5b31a1239ab9  draft  fix a bug
+  |/
+  o  25:0d972d6888e6  draft  fix bug 67
+  |
+  ~
+  $ hg evolve --all --any
+  move:[27] new feature
+  atop:[28] fix a bug
+  working directory is now at 166c1c368ab6
+  $ hg --hidden shortlog -G -r 25::
+  @  30:166c1c368ab6  draft  new feature
+  |
+  | o  29:51e0d8c0a922  draft  useful tweak
+  |/
+  o  28:2594e98553a9  draft  fix a bug
+  |
+  | x  27:fbb3c6d50427  draft  new feature
+  | |
+  | x  26:5b31a1239ab9  draft  fix a bug
+  |/
+  o  25:0d972d6888e6  draft  fix bug 67
+  |
+  ~
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-wireproto-bundle1.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,97 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [ui]
+  > ssh=python "$RUNTESTDIR/dummyssh"
+  > [phases]
+  > publish = False
+  > [extensions]
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+setup repo
+
+  $ hg init server
+
+  $ hg clone ssh://user@dummy/server client
+  no changes found
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cp -r client other
+
+Smoke testing
+===============
+
+  $ cd client
+  $ mkcommit 0
+  $ mkcommit a
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  $ hg pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  no changes found
+  $ hg pull -R ../other
+  pulling from ssh://user@dummy/server
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg push -R ../other
+  pushing to ssh://user@dummy/server
+  searching for changes
+  no changes found
+  [1]
+
+Push
+=============
+
+  $ echo 'A' > a
+  $ hg amend
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  remote: 2 new obsolescence markers
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  no changes found
+  [1]
+
+Pull
+=============
+
+  $ hg -R ../other pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  2 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg -R ../other pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  no changes found
+
+  $ cd ..
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-wireproto.t	Thu Mar 02 18:07:46 2017 +0100
@@ -0,0 +1,152 @@
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [experimental]
+  > obsmarkers-exchange-debug=true
+  > bundle2-exp=true
+  > [ui]
+  > ssh=python "$RUNTESTDIR/dummyssh"
+  > [phases]
+  > publish = False
+  > [extensions]
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+setup repo
+
+  $ hg init server
+
+  $ hg clone ssh://user@dummy/server client
+  no changes found
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cp -r client other
+
+Smoke testing
+===============
+
+  $ cd client
+  $ mkcommit 0
+  $ mkcommit a
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 2 changesets with 2 changes to 2 files
+  $ hg pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  no changes found
+  $ hg pull -R ../other
+  pulling from ssh://user@dummy/server
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg push -R ../other
+  pushing to ssh://user@dummy/server
+  searching for changes
+  no changes found
+  [1]
+
+Push
+=============
+
+  $ echo 'A' > a
+  $ hg amend
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  remote: obsmarker-exchange: 139 bytes received
+  remote: 2 new obsolescence markers
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  no changes found
+  [1]
+
+Pull
+=============
+
+  $ hg -R ../other pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  obsmarker-exchange: 139 bytes received
+  2 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg -R ../other pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  no changes found
+
+Test some markers discovery
+===========================
+
+  $ echo c > C
+  $ hg add C
+  $ hg commit -m C
+  $ echo c >> C
+  $ hg amend
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: obsmarker-exchange: 139 bytes received
+  remote: 2 new obsolescence markers
+  $ hg -R ../other pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  obsmarker-exchange: 139 bytes received
+  2 new obsolescence markers
+  (run 'hg update' to get a working copy)
+
+some common hidden
+
+  $ hg touch .
+  $ hg push
+  pushing to ssh://user@dummy/server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 0 changes to 1 files (+1 heads)
+  remote: obsmarker-exchange: 208 bytes received
+  remote: 1 new obsolescence markers
+  $ hg -R ../other pull
+  pulling from ssh://user@dummy/server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 0 changes to 1 files (+1 heads)
+  obsmarker-exchange: 208 bytes received
+  1 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+
+  $ cd ..