test-compat: merge with mercurial-4.1 branch mercurial-4.0
authorPierre-Yves David <pierre-yves.david@octobus.net>
Fri, 20 Oct 2017 18:43:55 +0200
branchmercurial-4.0
changeset 3110 50be10c63825
parent 3109 3024ae293732 (diff)
parent 3003 ddf28837f5af (current diff)
child 3111 7518ff7f26da
child 3119 088ea9b74e47
test-compat: merge with mercurial-4.1 branch
tests/test-check-flake8.t
tests/test-check-setup-manifest.t
tests/test-discovery-obshashrange.t
tests/test-evolve-obshistory-complex.t
tests/test-evolve-obshistory.t
tests/test-evolve-templates.t
tests/test-obsolete.t
tests/test-stabilize-conflict.t
tests/test-stabilize-order.t
tests/test-topic-change.t
tests/test-topic-tutorial.t
--- a/.hgtags	Wed Sep 27 01:18:39 2017 +0200
+++ b/.hgtags	Fri Oct 20 18:43:55 2017 +0200
@@ -56,3 +56,5 @@
 e60248f26f923f4460682252f7863ff86f7b86b0 6.4.0
 734c0bc066cdc0121a20a9cb44c8cc30c653be94 6.5.0
 cc3e09e033a3c632c9ac35badbf8b5d53f584049 6.6.0
+3a4f75c6619c7ef7d78ee0912efd6cb01d55b521 6.7.0
+430ad68292d76b9387d1eeadf289951f51fd88d3 6.7.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGELOG	Fri Oct 20 18:43:55 2017 +0200
@@ -0,0 +1,627 @@
+Changelog
+=========
+
+6.8.0 -- in progress
+----------------
+
+topic(0.4.0)
+
+  * topic: fix handling of bookmarks and phases while changing topics.
+
+6.7.2 -- in progress
+----------------
+
+  * pager: pager support to `obslog` and `evolve --list`
+
+topic(0.3.2)
+
+  * pager: pager support to `topics` and `stack`
+
+6.7.1 -- 2017-10-10
+-------------------
+
+  * obsfate: fix case were current user would disapear from the user list
+
+topic (0.3.1)
+
+  * topic: introduce a documented 'experimental.topic-mode' config
+  * topic: add support for 'random' topic mode (see documentation for details)
+  * stack: fix evolution preview for simple split.
+  * fix a performance regression affecting all transactions.
+    (the more non public changeset (hidden included), the slower)
+
+6.7.0 -- 2017-09-27
+-------------------
+
+  * compatibility with change in future 4.4 at this release date,
+  * documentation: improvement to content, wording and graphs,
+  * obslog: improved templatability,
+  * obslog/log: improve verb used to describe and evolution,
+  * pstatus/pdiff: update to full command. They now appears in the help,
+  * uncommit: add a --interactive option (4.3+ only).
+
+topic (0.3.0)
+
+  * push: add a --topic option to mirror --bookmark and --branch,
+  * stack: improve display of interleaved topic,
+  * stack: improve display of merge commit,
+  * topic: add a new 'debugconvertbookmark' commands (4.3+ only),
+    It helps migrating from bookmark feature branch to topic feature branch,
+  * topic: --age flag also shows the user who last touched the topic,
+  * topic: be more informative about topic activation and deactivation,
+  * topic: gain a --current flag,
+  * topic: small clarification and cleanup on various output.
+
+6.6.0 -- 2017-07-25
+-------------------
+
+  - amend: add a --extract flag to move change back to the working copy,
+    (same as uncommit, but accessible through the amend commit)
+  - split: now properly refuse to split public changeset,
+  - commands: unify and improve the pre-rewrite validation and error message,
+  - uncommit: add support for --current-date and --current-user option,
+  - fold: add support for --current-date and --current-user option,
+  - metaedit: add support for --current-date and --current-user option,
+  - split: add support for --current-date and --current-user option,
+  - compat: use various new API instead of the one deprecated in 4.3,
+    (when available)
+  - documentation: various minor documentation update.
+
+topic (0.2.0):
+
+  - topic: add --age option to sort topic by the most recently touched,
+  - topic: add a 't0' to access the root of a topic while keeping it active,
+  - topic: allow 'hg prev' to me move to 't0',
+  - topic: add a config option to enforce topic on new commit,
+    (experimental.enforce-topic)
+  - topic: make command names valid as expected, even if ui.strict=true.
+
+6.5.0 -- 2017-07-02
+-------------------
+
+features:
+
+ - obslog: gain a --patch flag to display changes introduced by the evolution
+  (Currently limited to in simple case only)
+ - log: display obsolescence fate by default, (future 4.3 only)
+ - doc: various minor improvement.
+
+bugfixes:
+
+ - evolve: fix branch preservation for merge,
+ - obsfate: improve support for advanced template reformating,
+ - split: preserve author of the splitted changeset.
+ - grab: properly fix hg executable on windows.
+
+topic (0.1.0):
+
+ - stack: also show the unstable status for the current changeset, (issue5553)
+ - stack: properly abort when and unknown topic is requested,
+ - stack: add basic and raw support for named branches,
+ - topic: changing topic on revs no longer adds extra instability, (issue5441)
+ - topic: topics: rename '--change' flag to '--rev' flag,
+ - topic: multiple large performance improvements,
+ - topic: various small output improvement,
+ - topic: improved topic preservation for various commands.
+
+
+6.4.0 -- 2017-06-16
+-------------------
+
+ - template: signifiant improvement to the '{obsfate}' template (now 4.2+ only)
+ - template: fix 'successors' and 'precursors' template to expose hex-node
+ - effect flag: the experiment is now active by default,
+   (see 'hg help -e evolve' to opt out)
+ - effect flag: fix a small bug related to hidden changeset,
+ - obscache: reduce impact on large repository
+ - obshashrange: install a '.max-revs' option see extension help for details
+
+6.3.1 -- 2017-06-01
+-------------------
+
+ - also backport the "revelant-markers" fix when using "evolve.serveronly"
+
+6.3.0 -- 2017-05-31
+-------------------
+
+ - olog: add an 'obslog' alias
+ - olog: add an '--all' option to show the whole obsolescence history tree.
+ - evolution: add an experiment to track the effect of rewrites.
+   (See hg help - evolve for details)
+ - exchange: fix the "relevant-markers" algorithm to include inline prune.
+   This will impact discovery of obsmarkers between server and client if one
+   still uses the old algorithm. Please upgrade both clients and servers as
+   soon as possible.
+   (See changeset 176d1a0ce385 in core Mercurial for details)
+ - obsdiscovery: add a config flag to disable all obsmarkers discovery
+   (See hg help - evolve for details)
+ - template: add a 'precursors' template that display the closests precursors of changesets
+ - template: add a 'successors' template that display the closests successors of changesets
+ - template: add a 'obsfate' template that display how a changeset has evolved
+ - new discovery experiment: add options to restrict memory consumption on
+   large repository (see "hg help -e evolve" for details).
+ - evolve: fix --rev handling in --list mode
+
+6.2.1 -- 2017-05-23
+-------------------
+
+ - prune: fix a crash related to color handling,
+ - next: fix a crash related to color handling,
+ - discovery: document the 'obshashrange' experiment,
+ - cache: reduce the warming load in case of reset,
+ - cache: add a 'experimental.obshashcache.warm-cache' option to allow
+   disabling post transaction cache warming.
+
+6.2.0 -- 2017-05-18
+-------------------
+
+ - olog: a new command to inspect the obs-history of a changeset (hg-4.0 + only),
+ - topic: have thg display topic name if possible,
+ - blackbox: log more information about discovery and cache computation,
+ - obscache: more efficient update in the (rare) case of a transaction adding
+   markers without changesets,
+ - obscache: fix more cache invalidation propagation,
+ - obscache: also enable the new cache (from 6.1.0) for 'evolve.server-only',
+ - obshashrange-cache: update incrementally in the (common) case of a
+   transaction not affecting existing range,
+ - obshashrange-cache: keep the cache warm after each transaction,
+ - topic: now requires Mercurial 4.0 or above,
+ - stack: now display if current revision is in bad state (issue5533),
+ - stack: fix json output to be valid json.
+
+6.1.0 -- 2017-05-03
+-------------------
+
+ - improve message about obsolete working copy parent,
+ - improve message issued  when accessing hidden nodes (4.2 only),
+ - introduce a new caches to reduce the impact of evolution on read-only commands,
+ - add a 'experimental.auto-publish' config. See `hg help -e evolve` for details.
+ - fix the propagation of some some cache invalidation,
+
+6.0.1 -- 2017-04-20
+-------------------
+
+ - template: adapt to change in 4.2,
+ - fix 'debugrecordpruneparents' (outdated API usage)
+ - checkheads: give priority to updated 4.2 code,
+ - serveronly: fix repository initialization.
+
+6.0.0 -- 2017-03-31
+-------------------
+
+- push: improved detection of obsoleted remote branch (issue4354),
+- drop compatibility for Mercurial < 3.8,
+- removed old (unpackaged) pushexperiment extension,
+- move all extensions in the official 'hgext3rd' namespace package,
+- add the "topic" experimental extensions. See the README.topic file for details
+- officially ship 'evolve.serveronly' extensions. That extensions contains
+  only the part related to exchange and is intended to be used by server.
+
+  Using the extension will enable evolution, use 'experimental.evolution=!'
+  to disable obsmarkers echange.  The old '__temporary__.advertiseobsolete'
+  option is no longer supported.
+
+- a new prototype of obsmarker discovery is available. The prototype is still
+  at early stage and not recommended for production.
+  Examples of current limitations:
+
+  - write access to the repo is highly recommanded for all operation,
+  - large memory footprint,
+  - initial caching is slow,
+  - unusable on large repo (because of various issue pointed earlier),
+  - likely to constains various bugs.
+
+  It can be tested by setting `experimental.obshashrange=1` on both client and
+  server. It is recommanded to get in touch with the evolve maintainer if you
+  decide to test it.
+
+- the 'debugrecordpruneparents' have been moved into the 'evolve.legacy'
+  separate extension. enable that extentions if you need to convert/update
+  markers in an old repository.
+
+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/MANIFEST.in	Wed Sep 27 01:18:39 2017 +0200
+++ b/MANIFEST.in	Fri Oct 20 18:43:55 2017 +0200
@@ -18,9 +18,10 @@
 include hgext3rd/__init__.py
 include hgext3rd/evolve/*.py
 include hgext3rd/topic/*.py
+include hgext3rd/topic/README
 include MANIFEST.in
 include README
-include README-topic
+include CHANGELOG
 include setup.py
 include tests/*.py
 include tests/*.sh
--- a/README	Wed Sep 27 01:18:39 2017 +0200
+++ b/README	Fri Oct 20 18:43:55 2017 +0200
@@ -117,600 +117,3 @@
 In addition, we have compatibility branches to check tests on older version of
 Mercurial. They are the "mercurial-x.y" branches. They are used to apply
 expected test change only, no code change should happen there.
-
-Changelog
-=========
-
-6.7.0 - in progress
--------------------
-
-  * documentation: improvement to content, wording and graphs,
-  * compatibility with change in future 4.4 at this release date,
-  * obslog/log: improve verb used to describe and evolution,
-  * obslog: improved templatability
-  * pstatus/pdiff: update to full command. They now appears in the help.
-  * uncommit: add a --interactive option.
-
-  * stack: improve display of interleaved topic
-  * stack: improve display of merge commit
-  * topic: gain a --current flag
-  * topic: add a new 'debugconvertbookmark' commands.
-    It helps migrating from bookmark feature branch to topic feature branch.
-  * topic: small clarification and cleanup on various output
-  * push: add a --topic option to mirror --bookmark and --branch.
-  * topic: be more informative about topic activation and deactivation
-  * topic: --age flag also shows the user who last touched the topic
-
-6.6.0 -- 2017-07-25
--------------------
-
-  - amend: add a --extract flag to move change back to the working copy,
-    (same as uncommit, but accessible through the amend commit)
-  - split: now properly refuse to split public changeset,
-  - commands: unify and improve the pre-rewrite validation and error message,
-  - uncommit: add support for --current-date and --current-user option,
-  - fold: add support for --current-date and --current-user option,
-  - metaedit: add support for --current-date and --current-user option,
-  - split: add support for --current-date and --current-user option,
-  - compat: use various new API instead of the one deprecated in 4.3,
-    (when available)
-  - documentation: various minor documentation update.
-
-topic (0.2.0):
-
-  - topic: add --age option to sort topic by the most recently touched,
-  - topic: add a 't0' to access the root of a topic while keeping it active,
-  - topic: allow 'hg prev' to me move to 't0',
-  - topic: add a config option to enforce topic on new commit,
-    (experimental.enforce-topic)
-  - topic: make command names valid as expected, even if ui.strict=true.
-
-6.5.0 -- 2017-07-02
--------------------
-
-features:
-
- - obslog: gain a --patch flag to display changes introduced by the evolution
-  (Currently limited to in simple case only)
- - log: display obsolescence fate by default, (future 4.3 only)
- - doc: various minor improvement.
-
-bugfixes:
-
- - evolve: fix branch preservation for merge,
- - obsfate: improve support for advanced template reformating,
- - split: preserve author of the splitted changeset.
- - grab: properly fix hg executable on windows.
-
-topic (0.1.0):
-
- - stack: also show the unstable status for the current changeset, (issue5553)
- - stack: properly abort when and unknown topic is requested,
- - stack: add basic and raw support for named branches,
- - topic: changing topic on revs no longer adds extra instability, (issue5441)
- - topic: topics: rename '--change' flag to '--rev' flag,
- - topic: multiple large performance improvements,
- - topic: various small output improvement,
- - topic: improved topic preservation for various commands.
-
-
-6.4.0 -- 2017-06-16
--------------------
-
- - template: signifiant improvement to the '{obsfate}' template (now 4.2+ only)
- - template: fix 'successors' and 'precursors' template to expose hex-node
- - effect flag: the experiment is now active by default,
-   (see 'hg help -e evolve' to opt out)
- - effect flag: fix a small bug related to hidden changeset,
- - obscache: reduce impact on large repository
- - obshashrange: install a '.max-revs' option see extension help for details
-
-6.3.1 -- 2017-06-01
--------------------
-
- - also backport the "revelant-markers" fix when using "evolve.serveronly"
-
-6.3.0 -- 2017-05-31
--------------------
-
- - olog: add an 'obslog' alias
- - olog: add an '--all' option to show the whole obsolescence history tree.
- - evolution: add an experiment to track the effect of rewrites.
-   (See hg help - evolve for details)
- - exchange: fix the "relevant-markers" algorithm to include inline prune.
-   This will impact discovery of obsmarkers between server and client if one
-   still uses the old algorithm. Please upgrade both clients and servers as
-   soon as possible.
-   (See changeset 176d1a0ce385 in core Mercurial for details)
- - obsdiscovery: add a config flag to disable all obsmarkers discovery
-   (See hg help - evolve for details)
- - template: add a 'precursors' template that display the closests precursors of changesets
- - template: add a 'successors' template that display the closests successors of changesets
- - template: add a 'obsfate' template that display how a changeset has evolved
- - new discovery experiment: add options to restrict memory consumption on
-   large repository (see "hg help -e evolve" for details).
- - evolve: fix --rev handling in --list mode
-
-6.2.1 -- 2017-05-23
--------------------
-
- - prune: fix a crash related to color handling,
- - next: fix a crash related to color handling,
- - discovery: document the 'obshashrange' experiment,
- - cache: reduce the warming load in case of reset,
- - cache: add a 'experimental.obshashcache.warm-cache' option to allow
-   disabling post transaction cache warming.
-
-6.2.0 -- 2017-05-18
--------------------
-
- - olog: a new command to inspect the obs-history of a changeset (hg-4.0 + only),
- - topic: have thg display topic name if possible,
- - blackbox: log more information about discovery and cache computation,
- - obscache: more efficient update in the (rare) case of a transaction adding
-   markers without changesets,
- - obscache: fix more cache invalidation propagation,
- - obscache: also enable the new cache (from 6.1.0) for 'evolve.server-only',
- - obshashrange-cache: update incrementally in the (common) case of a
-   transaction not affecting existing range,
- - obshashrange-cache: keep the cache warm after each transaction,
- - topic: now requires Mercurial 4.0 or above,
- - stack: now display if current revision is in bad state (issue5533),
- - stack: fix json output to be valid json.
-
-6.1.0 -- 2017-05-03
--------------------
-
- - improve message about obsolete working copy parent,
- - improve message issued  when accessing hidden nodes (4.2 only),
- - introduce a new caches to reduce the impact of evolution on read-only commands,
- - add a 'experimental.auto-publish' config. See `hg help -e evolve` for details.
- - fix the propagation of some some cache invalidation,
-
-6.0.1 -- 2017-04-20
--------------------
-
- - template: adapt to change in 4.2,
- - fix 'debugrecordpruneparents' (outdated API usage)
- - checkheads: give priority to updated 4.2 code,
- - serveronly: fix repository initialization.
-
-6.0.0 -- 2017-03-31
--------------------
-
-- push: improved detection of obsoleted remote branch (issue4354),
-- drop compatibility for Mercurial < 3.8,
-- removed old (unpackaged) pushexperiment extension,
-- move all extensions in the official 'hgext3rd' namespace package,
-- add the "topic" experimental extensions. See the README.topic file for details
-- officially ship 'evolve.serveronly' extensions. That extensions contains
-  only the part related to exchange and is intended to be used by server.
-
-  Using the extension will enable evolution, use 'experimental.evolution=!'
-  to disable obsmarkers echange.  The old '__temporary__.advertiseobsolete'
-  option is no longer supported.
-
-- a new prototype of obsmarker discovery is available. The prototype is still
-  at early stage and not recommended for production.
-  Examples of current limitations:
-
-  - write access to the repo is highly recommanded for all operation,
-  - large memory footprint,
-  - initial caching is slow,
-  - unusable on large repo (because of various issue pointed earlier),
-  - likely to constains various bugs.
-
-  It can be tested by setting `experimental.obshashrange=1` on both client and
-  server. It is recommanded to get in touch with the evolve maintainer if you
-  decide to test it.
-
-- the 'debugrecordpruneparents' have been moved into the 'evolve.legacy'
-  separate extension. enable that extentions if you need to convert/update
-  markers in an old repository.
-
-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-topic	Wed Sep 27 01:18:39 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-Topic Extension
-================
-
-This packages also provides the ``topic`` experiment in an independent
-extension. It implements a new experimental concept to provide lightweight
-feature branches for the mutable parts of the history. The experiments is still
-at an early stage and have significant usability and performance issues when
-enabled.
-
-How to Install
-==============
-
-The ``topic`` extension is included into the ``evolve` package, so the same instruction apply.
-
-Using Pip
----------
-
-You can install the latest version using pip::
-
-    $ pip install --user hg-evolve
-
-Then just enable it in you hgrc::
-
-    $ hg config --edit # adds the two line below:
-    [extensions]
-    topic =
-
-From Source
------------
-
-To install a local version from source::
-
-    $ hg clone https://www.mercurial-scm.org/repo/evolve/
-    $ cd evolve
-    $ make install-home
-
-Enable
-------
-
-The topic extensions is included in the evolve package. See the install instruction for evolve.
-
-Then enable it in you configuration::
-
-    $ hg config --edit # adds the two line below:
-    [extensions]
-    topic =
-
-Documentation
--------------
-
-* 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.
--- a/debian/changelog	Wed Sep 27 01:18:39 2017 +0200
+++ b/debian/changelog	Fri Oct 20 18:43:55 2017 +0200
@@ -1,3 +1,15 @@
+mercurial-evolve (6.7.1-1) unstable; urgency=medium
+ 
+   * new upstream release
+ 
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org>  Tue, 10 Oct 2017 16:03:23 +0200
+
+mercurial-evolve (6.7.0-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org>  Wed, 27 Sep 2017 16:17:40 +0200
+
 mercurial-evolve (6.6.0-1) unstable; urgency=medium
 
   * new upstream release
--- a/hgext3rd/evolve/__init__.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/__init__.py	Fri Oct 20 18:43:55 2017 +0200
@@ -374,6 +374,16 @@
 extsetup = eh.final_extsetup
 reposetup = eh.final_reposetup
 cmdtable = eh.cmdtable
+configtable = eh.configtable
+
+# Configuration
+eh.configitem('experimental', 'evolutioncommands')
+eh.configitem('experimental', 'evolution.allnewcommands')
+eh.configitem('experimental', 'prunestrip')
+
+# hack around because we need an actual default there
+if configtable:
+    configtable['experimental']['evolution.allnewcommands'].default = None
 
 # pre hg 4.0 compat
 
@@ -418,7 +428,7 @@
     # 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')
+    evolvecommands = ui.configlist('experimental', 'evolutioncommands', [])
     evolveopts = ui.configlist('experimental', 'evolution')
     if evolveopts and (commandopt not in evolveopts and
                        'all' not in evolveopts):
@@ -492,11 +502,11 @@
 
 @eh.uisetup
 def _installalias(ui):
-    if ui.config('alias', 'odiff', None) is None:
+    if ui.config('alias', 'odiff') is None:
         ui.setconfig('alias', 'odiff',
                      "diff --hidden --rev 'limit(precursors(.),1)' --rev .",
                      'evolve')
-    if ui.config('alias', 'grab', None) is None:
+    if ui.config('alias', 'grab') is None:
         if os.name == 'nt':
             hgexe = ('"%s"' % util.hgexecutable())
             ui.setconfig('alias', 'grab', "! " + hgexe
@@ -924,7 +934,7 @@
             repo.setparents(repo['.'].node(), nullid)
             repo.dirstate.write(tr)
             # fix up dirstate for copies and renames
-            copies.duplicatecopies(repo, dest.rev(), orig.p1().rev())
+            compat.duplicatecopies(repo, repo[None], dest.rev(), orig.p1().rev())
 
         class LocalMergeFailure(MergeFailure, exc.__class__):
             pass
@@ -1523,6 +1533,7 @@
     troublecategories = ['phasedivergent', 'contentdivergent', 'orphan']
     specifiedcategories = [t for t in troublecategories if opts[t]]
     if listopt:
+        compat.startpager(ui, 'evolve')
         listtroubles(ui, repo, specifiedcategories, **opts)
         return
 
@@ -2246,7 +2257,7 @@
                            "backup bundle")),
     ])
 def stripwrapper(orig, ui, repo, *revs, **kwargs):
-    if (not ui.configbool('experimental', 'prunestrip') or
+    if (not ui.configbool('experimental', 'prunestrip', False) or
         kwargs.get('bundle', False)):
         return orig(ui, repo, *revs, **kwargs)
 
--- a/hgext3rd/evolve/compat.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/compat.py	Fri Oct 20 18:43:55 2017 +0200
@@ -7,6 +7,7 @@
 """
 
 from mercurial import (
+    copies,
     context,
     hg,
     obsolete,
@@ -172,3 +173,17 @@
 
 if not util.safehasattr(obsolete, '_computephasedivergentset'):
     obsolete._computephasedivergentset = obsolete.cachefor('phasedivergent')(obsolete._computebumpedset)
+
+def startpager(ui, cmd):
+    """function to start a pager in case ui.pager() exists"""
+    if util.safehasattr(ui, 'pager'):
+        ui.pager(cmd)
+
+def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
+    # cannot use anything else until 4.3 support is dropped.
+    assert wctx.rev() is None
+    if copies.duplicatecopies.__code__.co_argcount < 5:
+        # pre 4.4 duplicatecopies compat
+        copies.duplicatecopies(repo, rev, fromrev, skiprev=skiprev)
+    else:
+        copies.duplicatecopies(repo, wctx, rev, fromrev, skiprev=skiprev)
--- a/hgext3rd/evolve/exthelper.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/exthelper.py	Fri Oct 20 18:43:55 2017 +0200
@@ -17,6 +17,13 @@
     from mercurial import cmdutil
     command = cmdutil.command
 
+configitem = None
+dynamicdefault = None
+if util.safehasattr(registrar, 'configitem'):
+    configitem = registrar.configitem
+    from mercurial import configitems
+    dynamicdefault = configitems.dynamicdefault
+
 class exthelper(object):
     """Helper for modular extension setup
 
@@ -39,6 +46,22 @@
         self.cmdtable = {}
         self.command = command(self.cmdtable)
 
+        self.configtable = {}
+        self._configitem = None
+        if configitem is not None:
+            self._configitem = configitem(self.configtable)
+
+    def configitem(self, section, config):
+        """For Mercurial 4.4 and above, register a config item
+
+        For now constraint to 'dynamicdefault' until we only support version with the feature.
+        Older version would otherwise not use the declare default.
+
+        For older version no-op fallback for old Mercurial versions
+        """
+        if self._configitem is not None:
+            self._configitem(section, config, default=dynamicdefault)
+
     def merge(self, other):
         self._uicallables.extend(other._uicallables)
         self._extcallables.extend(other._extcallables)
@@ -50,6 +73,11 @@
         self._functionwrappers.extend(other._functionwrappers)
         self._duckpunchers.extend(other._duckpunchers)
         self.cmdtable.update(other.cmdtable)
+        for section, items in other.configtable.iteritems():
+            if section in self.configtable:
+                self.configtable[section].update(items)
+            else:
+                self.configtable[section] = items
 
     def final_uisetup(self, ui):
         """Method to be used as the extension uisetup
--- a/hgext3rd/evolve/hack/directaccess.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/hack/directaccess.py	Fri Oct 20 18:43:55 2017 +0200
@@ -24,6 +24,14 @@
     from mercurial import cmdutil
     command = cmdutil.command(cmdtable)
 
+if util.safehasattr(registrar, 'configitem'):
+    configtable = {}
+    configitem = registrar.configitem(configtable)
+
+    configitem('directaccess', 'loadsafter',
+               default=[],
+    )
+
 # By default, all the commands have directaccess with warnings
 # List of commands that have no directaccess and directaccess with no warning
 directaccesslevel = [
--- a/hgext3rd/evolve/hack/inhibit.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/hack/inhibit.py	Fri Oct 20 18:43:55 2017 +0200
@@ -236,8 +236,11 @@
     repo._obsoletenotrebased = r.keys()
     return r
 
-def _clearrebased(orig, ui, repo, *args, **kwargs):
-    r = orig(ui, repo, *args, **kwargs)
+def _clearrebased(orig, ui, repo, dest, state, skipped, collapsedas=None,
+                  keepf=False, **kwargs):
+    r = orig(ui, repo, dest, state, skipped, collapsedas, keepf, **kwargs)
+    if keepf:
+        return r
     tonode = repo.changelog.node
     if util.safehasattr(repo, '_obsoletenotrebased'):
         _deinhibitmarkers(repo, [tonode(k) for k in repo._obsoletenotrebased])
--- a/hgext3rd/evolve/legacy.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/legacy.py	Fri Oct 20 18:43:55 2017 +0200
@@ -129,16 +129,16 @@
                     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)
+                    lookup_errors = (error.RepoLookupError, error.LookupError)
                     if len(oldobject) != 40:
                         try:
                             oldobject = repo[oldobject].node()
-                        except LOOKUP_ERRORS:
+                        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:
+                        except lookup_errors:
                             pass
 
                     oldmark['date'] = '%i %i' % tuple(oldmark['date'])
--- a/hgext3rd/evolve/metadata.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/metadata.py	Fri Oct 20 18:43:55 2017 +0200
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-__version__ = '6.7.0.dev'
-testedwith = '3.8.4 3.9.2 4.0.2 4.1.3 4.2.2'
+__version__ = '6.8.0.dev'
+testedwith = '3.8.4 3.9.2 4.0.2 4.1.3 4.2.3 4.3.2'
 minimumhgversion = '3.8'
 buglink = 'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obscache.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/obscache.py	Fri Oct 20 18:43:55 2017 +0200
@@ -111,9 +111,12 @@
 
     return obsstore
 
-if obsolete._readmarkers.__code__.co_argcount > 1:
+if obsolete._fm0readmarkers.__code__.co_argcount > 1:
     # hg-4.3+ has the "offset" parameter, and _fm?readmarkers also have an
     # extra "stop" parameter
+    # Note that _readmarkers is wrapped by @util.nogc, so its co_argcount is
+    # misleadingly 0. So we check _fm0readmarkers instead, which increased its
+    # argument count in the same changeset (5d3ba439).
     _readmarkers = obsolete._readmarkers
 else:
     # XXX copied as is from Mercurial 4.2 and added the "offset" parameters
--- a/hgext3rd/evolve/obsdiscovery.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/obsdiscovery.py	Fri Oct 20 18:43:55 2017 +0200
@@ -72,6 +72,13 @@
 eh.merge(stablerange.eh)
 obsexcmsg = utility.obsexcmsg
 
+# Config
+eh.configitem('experimental', 'evolution.obsdiscovery')
+eh.configitem('experimental', 'obshashrange')
+eh.configitem('experimental', 'obshashrange.warm-cache')
+eh.configitem('experimental', 'obshashrange.max-revs')
+eh.configitem('experimental', 'obshashrange.lru-size')
+
 ##################################
 ###  Code performing discovery ###
 ##################################
--- a/hgext3rd/evolve/obsexchange.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/obsexchange.py	Fri Oct 20 18:43:55 2017 +0200
@@ -44,6 +44,7 @@
 obsexcmsg = utility.obsexcmsg
 obsexcprg = utility.obsexcprg
 
+eh.configitem('experimental', 'verbose-obsolescence-exchange')
 
 _bestformat = max(obsolete.formats.keys())
 
--- a/hgext3rd/evolve/obshistory.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/obshistory.py	Fri Oct 20 18:43:55 2017 +0200
@@ -19,8 +19,15 @@
     obsolete,
     node as nodemod,
     scmutil,
+    util,
 )
 
+try:
+    from mercurial import obsutil
+    obsutil.marker
+except ImportError:
+    obsutil = None
+
 from mercurial.i18n import _
 
 from . import (
@@ -30,6 +37,18 @@
 
 eh = exthelper.exthelper()
 
+# Config
+efd = {'default': True} # pass a default value unless the config is registered
+
+@eh.extsetup
+def enableeffectflags(ui):
+    item = (getattr(ui, '_knownconfig', {})
+            .get('experimental', {})
+            .get('evolution.effect-flags'))
+    if item is not None:
+        item.default = True
+        efd.clear()
+
 @eh.command(
     'obslog|olog',
     [('G', 'graph', True, _("show the revision DAG")),
@@ -66,6 +85,7 @@
 
     Returns 0 on success.
     """
+    compat.startpager(ui, 'obslog')
     revs = list(revs) + opts['rev']
     if not revs:
         revs = ['.']
@@ -132,7 +152,7 @@
     succ = successors[0]
 
     if succ not in repo:
-        return False, "succ is unknown locally"
+        return False, "successor is unknown locally"
 
     # Check that both node and succ have the same parents
     nodep1, nodep2 = repo[node].p1(), repo[node].p2()
@@ -498,7 +518,7 @@
                 fm.plain("\n")
                 fm.plain(contentpatch)
         else:
-            patch = "    (No patch available yet, %s)" % _patchavailable[1]
+            patch = "    (No patch available, %s)" % _patchavailable[1]
             fm.plain("\n")
             # TODO: should be in json too
             fm.plain(patch)
@@ -616,46 +636,48 @@
             return False
     return True
 
-@eh.wrapfunction(obsolete, 'createmarkers')
-def createmarkerswithbits(orig, repo, relations, flag=0, date=None,
-                          metadata=None, **kwargs):
-    """compute 'effect-flag' and augment the created markers
+# Wrap pre Mercurial 4.4 createmarkers that didn't included effect-flag
+if not util.safehasattr(obsutil, 'geteffectflag'):
+    @eh.wrapfunction(obsolete, 'createmarkers')
+    def createmarkerswithbits(orig, repo, relations, flag=0, date=None,
+                              metadata=None, **kwargs):
+        """compute 'effect-flag' and augment the created markers
 
-    Wrap obsolete.createmarker in order to compute the effect of each
-    relationship and store them as flag in the metadata.
+        Wrap obsolete.createmarker in order to compute the effect of each
+        relationship and store them as flag in the metadata.
 
-    While we experiment, we store flag in a metadata field. This field is
-    "versionned" to easilly allow moving to other meaning for flags.
+        While we experiment, we store flag in a metadata field. This field is
+        "versionned" to easilly allow moving to other meaning for flags.
 
-    The comparison of description or other infos just before creating the obs
-    marker might induce overhead in some cases. However it is a good place to
-    start since it automatically makes all markers creation recording more
-    meaningful data. In the future, we can introduce way for commands to
-    provide precomputed effect to avoid the overhead.
-    """
-    if not repo.ui.configbool('experimental', 'evolution.effect-flags', True):
-        return orig(repo, relations, flag, date, metadata, **kwargs)
-    if metadata is None:
-        metadata = {}
-    tr = repo.transaction('add-obsolescence-marker')
-    try:
-        for r in relations:
-            # Compute the effect flag for each obsmarker
-            effect = geteffectflag(r)
+        The comparison of description or other infos just before creating the obs
+        marker might induce overhead in some cases. However it is a good place to
+        start since it automatically makes all markers creation recording more
+        meaningful data. In the future, we can introduce way for commands to
+        provide precomputed effect to avoid the overhead.
+        """
+        if not repo.ui.configbool('experimental', 'evolution.effect-flags', **efd):
+            return orig(repo, relations, flag, date, metadata, **kwargs)
+        if metadata is None:
+            metadata = {}
+        tr = repo.transaction('add-obsolescence-marker')
+        try:
+            for r in relations:
+                # Compute the effect flag for each obsmarker
+                effect = geteffectflag(r)
 
-            # Copy the metadata in order to add them, we copy because the
-            # effect flag might be different per relation
-            m = metadata.copy()
-            # we store the effect even if "0". This disctinct markers created
-            # without the feature with markers recording a no-op.
-            m['ef1'] = "%d" % effect
+                # Copy the metadata in order to add them, we copy because the
+                # effect flag might be different per relation
+                m = metadata.copy()
+                # we store the effect even if "0". This disctinct markers created
+                # without the feature with markers recording a no-op.
+                m['ef1'] = "%d" % effect
 
-            # And call obsolete.createmarkers for creating the obsmarker for real
-            orig(repo, [r], flag, date, m, **kwargs)
+                # And call obsolete.createmarkers for creating the obsmarker for real
+                orig(repo, [r], flag, date, m, **kwargs)
 
-        tr.close()
-    finally:
-        tr.release()
+            tr.close()
+        finally:
+            tr.release()
 
 def _getobsfate(successorssets):
     """ Compute a changeset obsolescence fate based on his successorssets.
@@ -765,6 +787,41 @@
         verb = 'split'
     return {'verb': verb}
 
+# Hijack callers of successorsetverb
+if util.safehasattr(obsutil, 'obsfateprinter'):
+
+    @eh.wrapfunction(obsutil, 'obsfateprinter')
+    def obsfateprinter(orig, successors, markers, ui):
+
+        def closure(successors):
+            return _successorsetverb(successors, markers)['verb']
+
+        if not util.safehasattr(obsutil, 'successorsetverb'):
+            return orig(successors, markers, ui)
+
+        # Save the old value
+        old = obsutil.successorsetverb
+
+        try:
+            # Replace by own
+            obsutil.successorsetverb = closure
+
+            # Call the orig
+            result = orig(successors, markers, ui)
+
+            # And return result
+            return result
+        finally:
+            # Replace the old one
+            obsutil.successorsetverb = old
+
+# XXX temporary disable operation to clarify tests changes
+if util.safehasattr(obsutil, 'markersoperations'):
+
+    @eh.wrapfunction(obsutil, 'markersoperations')
+    def markersoperations(orig, *args, **kwargs):
+        return []
+
 FORMATSSETSFUNCTIONS = [
     _successorsetdates,
     _successorsetusers,
--- a/hgext3rd/evolve/safeguard.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/safeguard.py	Fri Oct 20 18:43:55 2017 +0200
@@ -16,6 +16,8 @@
 
 eh = exthelper.exthelper()
 
+eh.configitem('experimental', 'auto-publish')
+
 @eh.reposetup
 def setuppublishprevention(ui, repo):
 
--- a/hgext3rd/evolve/serveronly.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/serveronly.py	Fri Oct 20 18:43:55 2017 +0200
@@ -47,6 +47,7 @@
 extsetup = eh.final_extsetup
 reposetup = eh.final_reposetup
 cmdtable = eh.cmdtable
+configtable = eh.configtable
 
 @eh.reposetup
 def default2evolution(ui, repo):
--- a/hgext3rd/evolve/templatekw.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/evolve/templatekw.py	Fri Oct 20 18:43:55 2017 +0200
@@ -47,69 +47,78 @@
         return templatekw.showlist('trouble', ctx.instabilities(), plural='troubles',
                                    **args)
 
-def closestprecursors(repo, nodeid):
-    """ Yield the list of next precursors pointing on visible changectx nodes
-    """
-
-    precursors = repo.obsstore.predecessors
-    stack = [nodeid]
+if util.safehasattr(templatekw, 'showpredecessors'):
+    eh.templatekw("precursors")(templatekw.showpredecessors)
+else:
+    # for version <= hg4.3
+    def closestprecursors(repo, nodeid):
+        """ Yield the list of next precursors pointing on visible changectx nodes
+        """
 
-    while stack:
-        current = stack.pop()
-        currentpreccs = precursors.get(current, ())
+        precursors = repo.obsstore.predecessors
+        stack = [nodeid]
 
-        for prec in currentpreccs:
-            precnodeid = prec[0]
+        while stack:
+            current = stack.pop()
+            currentpreccs = precursors.get(current, ())
+
+            for prec in currentpreccs:
+                precnodeid = prec[0]
 
-            if precnodeid in repo:
-                yield precnodeid
-            else:
-                stack.append(precnodeid)
+                if precnodeid in repo:
+                    yield precnodeid
+                else:
+                    stack.append(precnodeid)
 
-@eh.templatekw("precursors")
-def shownextvisibleprecursors(repo, ctx, **args):
-    """Returns a string containing the list of the closest precursors
-    """
-    precursors = sorted(closestprecursors(repo, ctx.node()))
-    precursors = [node.hex(p) for p in precursors]
+    @eh.templatekw("precursors")
+    def shownextvisibleprecursors(repo, ctx, **args):
+        """Returns a string containing the list of the closest precursors
+        """
+        precursors = sorted(closestprecursors(repo, ctx.node()))
+        precursors = [node.hex(p) for p in precursors]
 
-    # <= hg-4.1 requires an explicite gen.
-    # we can use None once the support is dropped
-    #
-    # They also requires an iterator instead of an iterable.
-    gen = iter(" ".join(p[:12] for p in precursors))
-    return templatekw._hybrid(gen.__iter__(), precursors, lambda x: {'precursor': x},
-                              lambda d: d['precursor'][:12])
+        # <= hg-4.1 requires an explicite gen.
+        # we can use None once the support is dropped
+        #
+        # They also requires an iterator instead of an iterable.
+        gen = iter(" ".join(p[:12] for p in precursors))
+        return templatekw._hybrid(gen.__iter__(), precursors, lambda x: {'precursor': x},
+                                  lambda d: d['precursor'][:12])
 
 def closestsuccessors(repo, nodeid):
     """ returns the closest visible successors sets instead.
     """
     return directsuccessorssets(repo, nodeid)
 
-@eh.templatekw("successors")
-def shownextvisiblesuccessors(repo, ctx, templ, **args):
-    """Returns a string of sets of successors for a changectx
+if util.safehasattr(templatekw, 'showsuccessorssets'):
+    eh.templatekw("successors")(templatekw.showsuccessorssets)
+else:
+    # for version <= hg4.3
 
-    Format used is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and
-    ctx2 while also diverged into ctx3"""
-    if not ctx.obsolete():
-        return ''
+    @eh.templatekw("successors")
+    def shownextvisiblesuccessors(repo, ctx, templ, **args):
+        """Returns a string of sets of successors for a changectx
 
-    ssets, _ = closestsuccessors(repo, ctx.node())
-    ssets = [[node.hex(n) for n in ss] for ss in ssets]
+        Format used is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and
+        ctx2 while also diverged into ctx3"""
+        if not ctx.obsolete():
+            return ''
 
-    data = []
-    gen = []
-    for ss in ssets:
-        subgen = '[%s]' % ', '.join(n[:12] for n in ss)
-        gen.append(subgen)
-        h = templatekw._hybrid(iter(subgen), ss, lambda x: {'successor': x},
-                               lambda d: "%s" % d["successor"])
-        data.append(h)
+        ssets, _ = closestsuccessors(repo, ctx.node())
+        ssets = [[node.hex(n) for n in ss] for ss in ssets]
 
-    gen = ', '.join(gen)
-    return templatekw._hybrid(iter(gen), data, lambda x: {'successorset': x},
-                              lambda d: d["successorset"])
+        data = []
+        gen = []
+        for ss in ssets:
+            subgen = '[%s]' % ', '.join(n[:12] for n in ss)
+            gen.append(subgen)
+            h = templatekw._hybrid(iter(subgen), ss, lambda x: {'successor': x},
+                                   lambda d: "%s" % d["successor"])
+            data.append(h)
+
+        gen = ', '.join(gen)
+        return templatekw._hybrid(iter(gen), data, lambda x: {'successorset': x},
+                                  lambda d: d["successorset"])
 
 def _getusername(ui):
     """the default username in the config or None"""
@@ -191,17 +200,6 @@
     # Verb
     line.append(obsfateline['verb'])
 
-    # Users
-    if (verbose or normal) and 'users' in obsfateline:
-        users = obsfateline['users']
-
-        if normal:
-            username = _getusername(ui)
-            users = [user for user in users if user != username]
-
-        if users:
-            line.append(" by %s" % ",".join(users))
-
     # Successors
     successors = obsfateline["successors"]
 
@@ -209,6 +207,20 @@
         fmtsuccessors = map(lambda s: s[:12], successors)
         line.append(" as %s" % ", ".join(fmtsuccessors))
 
+    # Users
+    if (verbose or normal) and 'users' in obsfateline:
+        users = obsfateline['users']
+
+        if not verbose:
+            # If current user is the only user, do not show anything if not in
+            # verbose mode
+            username = _getusername(ui)
+            if len(users) == 1 and users[0] == username:
+                users = None
+
+        if users:
+            line.append(" by %s" % ", ".join(users))
+
     # Date
     if verbose:
         min_date = obsfateline['min_date']
@@ -234,13 +246,13 @@
 
     return "\n".join(lines)
 
-@eh.templatekw("obsfate")
-def showobsfate(repo, ctx, **args):
+@eh.templatekw("obsfatedata")
+def showobsfatedata(repo, ctx, **args):
     # Get the needed obsfate data
     values = obsfatedata(repo, ctx)
 
     if values is None:
-        return ''
+        return templatekw.showlist("obsfatedata", [], args)
 
     # Format each successorset successors list
     for raw in values:
@@ -291,8 +303,16 @@
 
     return templatekw._hybrid(gen, values, lambda x: {name: x}, fmt)
 
-# Check if we can hook directly on the changeset_printer
-if util.safehasattr(cmdutil.changeset_printer, '_exthook'):
+# rely on core mercurial starting from 4.4 for the obsfate template
+if not util.safehasattr(templatekw, 'showobsfate'):
+
+    @eh.templatekw("obsfate")
+    def showobsfate(*args, **kwargs):
+        return showobsfatedata(*args, **kwargs)
+
+if util.safehasattr(cmdutil.changeset_printer, '_showobsfate'):
+    pass # already included by default
+elif util.safehasattr(cmdutil.changeset_printer, '_exthook'):
     @eh.wrapfunction(cmdutil.changeset_printer, '_exthook')
     def exthook(original, self, ctx):
         # Call potential other extensions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/topic/README	Fri Oct 20 18:43:55 2017 +0200
@@ -0,0 +1,53 @@
+Topic Extension
+================
+
+This packages also provides the ``topic`` experiment in an independent
+extension. It implements a new experimental concept to provide lightweight
+feature branches for the mutable parts of the history. The experiments is still
+at an early stage and have significant usability and performance issues when
+enabled.
+
+How to Install
+==============
+
+The ``topic`` extension is included into the ``evolve` package, so the same instruction apply.
+
+Using Pip
+---------
+
+You can install the latest version using pip::
+
+    $ pip install --user hg-evolve
+
+Then just enable it in you hgrc::
+
+    $ hg config --edit # adds the two line below:
+    [extensions]
+    topic =
+
+From Source
+-----------
+
+To install a local version from source::
+
+    $ hg clone https://www.mercurial-scm.org/repo/evolve/
+    $ cd evolve
+    $ make install-home
+
+Enable
+------
+
+The topic extensions is included in the evolve package. See the install instruction for evolve.
+
+Then enable it in you configuration::
+
+    $ hg config --edit # adds the two line below:
+    [extensions]
+    topic =
+
+Documentation
+-------------
+
+* 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.
--- a/hgext3rd/topic/__init__.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/topic/__init__.py	Fri Oct 20 18:43:55 2017 +0200
@@ -48,10 +48,26 @@
 
 Be aware that this extension is still an experiment, commands and other features
 are likely to be change/adjusted/dropped over time as we refine the concept.
+
+topic-mode
+==========
+
+The topic extension can be configured to ensure the user do not forget to add
+a topic when committing a new topic::
+
+    [experimental]
+    # behavior when commit is made without an active topic
+    topic-mode = ignore # do nothing special (default)
+    topic-mode = warning # print a warning
+    topic-mode = enforce # abort the commit (except for merge)
+    topic-mode = enforce-all # abort the commit (even for merge)
+    topic-mode = random # use a randomized generated topic (except for merge)
+    topic-mode = random-all # use a randomized generated topic (even for merge)
 """
 
 from __future__ import absolute_import
 
+import functools
 import re
 import time
 import weakref
@@ -88,6 +104,7 @@
     stack,
     topicmap,
     discovery,
+    randomname
 )
 
 if util.safehasattr(registrar, 'command'):
@@ -122,11 +139,44 @@
               'topic.active': 'green',
              }
 
-__version__ = '0.3.0.dev'
-testedwith = '4.0.2 4.1.3 4.2.1'
+__version__ = '0.4.0.dev'
+
+testedwith = '4.0.2 4.1.3 4.2.3 4.3.3'
 minimumhgversion = '4.0'
 buglink = 'https://bz.mercurial-scm.org/'
 
+if util.safehasattr(registrar, 'configitem'):
+    configtable = {}
+    configitem = registrar.configitem(configtable)
+
+    configitem('experimental', 'enforce-topic',
+               default=False,
+    )
+    configitem('experimental', 'topic-mode',
+               default=None,
+    )
+    configitem('_internal', 'keep-topic',
+               default=False,
+    )
+
+    def extsetup(ui):
+        # register config that strickly belong to other code (thg, core, etc)
+        #
+        # To ensure all config items we used are registerd, we register them if
+        # nobody else did so far.
+        from mercurial import configitems
+        extraitem = functools.partial(configitems._register, ui._knownconfig)
+        if ('experimental' not in ui._knownconfig
+                or not ui._knownconfig['experimental'].get('thg.displaynames')):
+            extraitem('experimental', 'thg.displaynames',
+                      default=None,
+            )
+        if ('devel' not in ui._knownconfig
+                or not ui._knownconfig['devel'].get('random')):
+            extraitem('devel', 'randomseed',
+                      default=None,
+            )
+
 def _contexttopic(self, force=False):
     if not (force or self.mutable()):
         return ''
@@ -232,7 +282,7 @@
 
     repo = repo.unfiltered()
 
-    if repo.ui.config('experimental', 'thg.displaynames', None) is None:
+    if repo.ui.config('experimental', 'thg.displaynames') is None:
         repo.ui.setconfig('experimental', 'thg.displaynames', 'topics',
                           source='topic-extension')
 
@@ -322,14 +372,14 @@
             ct = self.currenttopic
             if not ct:
                 return tr
-            ctwasempty = stack.stackdata(self, topic=ct)['changesetcount'] == 0
+            ctwasempty = stack.stack(self, topic=ct).changesetcount == 0
 
             reporef = weakref.ref(self)
 
             def currenttopicempty(tr):
                 # check active topic emptyness
                 repo = reporef()
-                csetcount = stack.stackdata(repo, topic=ct)['changesetcount']
+                csetcount = stack.stack(repo, topic=ct).changesetcount
                 empty = csetcount == 0
                 if empty and not ctwasempty:
                     ui.status('active topic %r is now empty\n' % ct)
@@ -445,6 +495,8 @@
         # Have some restrictions on the topic name just like bookmark name
         scmutil.checknewlabel(repo, topic, 'topic')
 
+    compat.startpager(ui, 'topics')
+
     if list:
         if clear or rev:
             raise error.Abort(_("cannot use --clear or --rev with --list"))
@@ -480,7 +532,7 @@
 
     ct = repo.currenttopic
     if clear:
-        empty = stack.stackdata(repo, topic=ct)['changesetcount'] == 0
+        empty = stack.stack(repo, topic=ct).changesetcount == 0
         if empty:
             if ct:
                 ui.status(_('clearing empty topic "%s"\n') % ct)
@@ -524,6 +576,7 @@
         topic = repo.currenttopic
     if topic is None:
         branch = repo[None].branch()
+    compat.startpager(ui, 'stack')
     return stack.showstack(ui, repo, branch=branch, topic=topic, opts=opts)
 
 @command('debugcb|debugconvertbookmark', [
@@ -702,25 +755,43 @@
         p1 = c.p1().node()
         p2 = c.p2().node()
         if p1 in successors:
-            p1 = successors[p1]
+            p1 = successors[p1][0]
         if p2 in successors:
-            p2 = successors[p2]
-        mc = context.memctx(
-            repo, (p1, p2), c.description(),
-            c.files(), filectxfn,
-            user=c.user(), date=c.date(), extra=fixedextra)
-        newnode = repo.commitctx(mc)
-        successors[c.node()] = newnode
+            p2 = successors[p2][0]
+        mc = context.memctx(repo,
+                            (p1, p2),
+                            c.description(),
+                            c.files(),
+                            filectxfn,
+                            user=c.user(),
+                            date=c.date(),
+                            extra=fixedextra)
+
+        # phase handling
+        commitphase = c.phase()
+        if util.safehasattr(repo.ui, 'configoverride'):
+            overrides = {('phases', 'new-commit'): commitphase}
+            with repo.ui.configoverride(overrides, 'changetopic'):
+                newnode = repo.commitctx(mc)
+        else: # do not attempt to preserver phase (hg <= 4.0)
+            newnode = repo.commitctx(mc)
+
+        successors[c.node()] = (newnode,)
         ui.debug('new node id is %s\n' % node.hex(newnode))
-        obsolete.createmarkers(repo, [(c, (repo[newnode],))])
         rewrote += 1
+
+    # create obsmarkers and move bookmarks
+    # XXX we should be creating marker as we go instead of only at the end,
+    # this makes the operations more modulars
+    compat.cleanupnodes(repo, successors, 'changetopics')
+
     # move the working copy too
     wctx = repo[None]
     # in-progress merge is a bit too complex for now.
     if len(wctx.parents()) == 1:
         newid = successors.get(wctx.p1().node())
         if newid is not None:
-            hg.update(repo, newid, quietempty=True)
+            hg.update(repo, newid[0], quietempty=True)
     return rewrote
 
 def _listtopics(ui, repo, opts):
@@ -732,7 +803,7 @@
         return _showlasttouched(repo, fm, opts)
     activetopic = repo.currenttopic
     namemask = '%s'
-    if repo.topics and ui.verbose:
+    if repo.topics:
         maxwidth = max(len(t) for t in repo.topics)
         namemask = '%%-%is' % maxwidth
     for topic in sorted(repo.topics):
@@ -748,38 +819,46 @@
             fm.plain(' %s ' % marker, label=label)
         fm.write('topic', namemask, topic, label=label)
         fm.data(active=active)
+
+        data = stack.stack(repo, topic=topic)
+        fm.plain(' (')
+        if ui.verbose:
+            fm.write('branches+', 'on branch: %s',
+                     '+'.join(data.branches), # XXX use list directly after 4.0 is released
+                     label='topic.list.branches')
+
+            fm.plain(', ')
+        fm.write('changesetcount', '%d changesets', data.changesetcount,
+                 label='topic.list.changesetcount')
+
+        if data.troubledcount:
+            fm.plain(', ')
+            fm.write('troubledcount', '%d troubled',
+                     data.troubledcount,
+                     label='topic.list.troubledcount')
+
+        headcount = len(data.heads)
+        if 1 < headcount:
+            fm.plain(', ')
+            fm.write('headcount', '%d heads',
+                     headcount,
+                     label='topic.list.headcount.multiple')
+
         if ui.verbose:
             # XXX we should include the data even when not verbose
-            data = stack.stackdata(repo, topic=topic)
-            fm.plain(' (')
-            fm.write('branches+', 'on branch: %s',
-                     '+'.join(data['branches']), # XXX use list directly after 4.0 is released
-                     label='topic.list.branches')
-            fm.plain(', ')
-            fm.write('changesetcount', '%d changesets', data['changesetcount'],
-                     label='topic.list.changesetcount')
-            if data['troubledcount']:
-                fm.plain(', ')
-                fm.write('troubledcount', '%d troubled',
-                         data['troubledcount'],
-                         label='topic.list.troubledcount')
-            if 1 < data['headcount']:
-                fm.plain(', ')
-                fm.write('headcount', '%d heads',
-                         data['headcount'],
-                         label='topic.list.headcount.multiple')
-            if 0 < data['behindcount']:
+
+            behindcount = data.behindcount
+            if 0 < behindcount:
                 fm.plain(', ')
                 fm.write('behindcount', '%d behind',
-                         data['behindcount'],
+                         behindcount,
                          label='topic.list.behindcount')
-            elif -1 == data['behindcount']:
+            elif -1 == behindcount:
                 fm.plain(', ')
                 fm.write('behinderror', '%s',
-                         _('ambiguous destination: %s') % data['behinderror'],
+                         _('ambiguous destination: %s') % data.behinderror,
                          label='topic.list.behinderror')
-            fm.plain(')')
-        fm.plain('\n')
+        fm.plain(')\n')
     fm.end()
 
 def _showlasttouched(repo, fm, opts):
@@ -875,18 +954,68 @@
     # i18n: column positioning for "hg summary"
     ui.write(_("topic:  %s\n") % ui.label(t, 'topic.active'))
 
+_validmode = [
+    'ignore',
+    'warning',
+    'enforce',
+    'enforce-all',
+    'random',
+    'random-all',
+]
+
+def _configtopicmode(ui):
+    """ Parse the config to get the topicmode
+    """
+    topicmode = ui.config('experimental', 'topic-mode')
+
+    # Fallback to read enforce-topic
+    if topicmode is None:
+        enforcetopic = ui.configbool('experimental', 'enforce-topic')
+        if enforcetopic:
+            topicmode = "enforce"
+    if topicmode not in _validmode:
+        topicmode = _validmode[0]
+
+    return topicmode
+
 def commitwrap(orig, ui, repo, *args, **opts):
     with repo.wlock():
-        enforcetopic = ui.configbool('experimental', 'enforce-topic')
+        topicmode = _configtopicmode(ui)
+        ismergecommit = len(repo[None].parents()) == 2
+
+        notopic = not repo.currenttopic
+        mayabort = (topicmode == "enforce" and not ismergecommit)
+        maywarn = (topicmode == "warning"
+                   or (topicmode == "enforce" and ismergecommit))
+
+        mayrandom = False
+        if topicmode == "random":
+            mayrandom = not ismergecommit
+        elif topicmode == "random-all":
+            mayrandom = True
+
+        if topicmode == 'enforce-all':
+            ismergecommit = False
+            mayabort = True
+            maywarn = False
+
+        hint = _("see 'hg help -e topic.topic-mode' for details")
         if opts.get('topic'):
             t = opts['topic']
             with repo.vfs.open('topic', 'w') as f:
                 f.write(t)
-        elif not repo.currenttopic and enforcetopic:
+        elif opts.get('amend'):
+            pass
+        elif notopic and mayabort:
             msg = _("no active topic")
-            hint = _("set a current topic or use '--config " +
-                     "experimental.enforce-topic=no' to commit without a topic")
             raise error.Abort(msg, hint=hint)
+        elif notopic and maywarn:
+            ui.warn(_("warning: new draft commit without topic\n"))
+            if not ui.quiet:
+                ui.warn(("(%s)\n") % hint)
+        elif notopic and mayrandom:
+            with repo.vfs.open('topic', 'w') as f:
+                f.write(randomname.randomtopicname(ui))
         return orig(ui, repo, *args, **opts)
 
 def committextwrap(orig, repo, ctx, subs, extramsg):
@@ -917,7 +1046,7 @@
         # rebased commit. We have explicitly stored in config if rebase is
         # running.
         ot = repo.currenttopic
-        empty = stack.stackdata(repo, topic=ot)['changesetcount'] == 0
+        empty = stack.stack(repo, topic=ot).changesetcount == 0
         if repo.ui.hasconfig('experimental', 'topicrebase'):
             isrebase = True
         if repo.ui.configbool('_internal', 'keep-topic'):
--- a/hgext3rd/topic/compat.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/topic/compat.py	Fri Oct 20 18:43:55 2017 +0200
@@ -7,7 +7,11 @@
 """
 from __future__ import absolute_import
 
-from mercurial import obsolete
+from mercurial import (
+    obsolete,
+    scmutil,
+    util,
+)
 
 getmarkers = None
 successorssets = None
@@ -22,3 +26,22 @@
     getmarkers = obsolete.getmarkers
 if successorssets is None:
     successorssets = obsolete.successorssets
+
+def startpager(ui, cmd):
+    """function to start a pager in case ui.pager() exists"""
+    try:
+        ui.pager(cmd)
+    except AttributeError:
+        pass
+
+def cleanupnodes(repo, replacements, operation, moves=None):
+    # create obsmarkers and move bookmarks
+    # XXX we should be creating marker as we go instead of only at the end,
+    # this makes the operations more modulars
+    if util.safehasattr(scmutil, 'cleanupnodes'):
+        scmutil.cleanupnodes(repo, replacements, 'changetopics',
+                             moves=moves)
+    else:
+        relations = [(repo[o], tuple(repo[n] for n in new))
+                     for (o, new) in replacements.iteritems()]
+        obsolete.createmarkers(repo, relations)
--- a/hgext3rd/topic/evolvebits.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/topic/evolvebits.py	Fri Oct 20 18:43:55 2017 +0200
@@ -81,8 +81,16 @@
                  obs)
         obs = obs.parents()[0]
         newer = compat.successorssets(repo, obs.node())
-    if len(newer) > 1 or len(newer[0]) > 1:
+    if 1 < len(newer):
+        # divergence case
+        # we should pick as arbitrary one
         raise MultipleSuccessorsError(newer)
+    elif 1 < len(newer[0]):
+        splitheads = list(repo.revs('heads(%ln::%ln)', newer[0], newer[0]))
+        if 1 < len(splitheads):
+            # split case, See if we can make sense of it.
+            raise MultipleSuccessorsError(newer)
+        return splitheads[0]
 
     return repo[newer[0][0]].rev()
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/topic/randomname.py	Fri Oct 20 18:43:55 2017 +0200
@@ -0,0 +1,1011 @@
+# randomname.py - topic extension
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""random topic generator utils
+"""
+
+import random
+
+animals = [
+    'aardvark',
+    'albatross',
+    'alligator',
+    'alpaca',
+    'ant',
+    'anteater',
+    'antelope',
+    'ape',
+    'armadillo',
+    'baboon',
+    'badger',
+    'barracuda',
+    'bat',
+    'bear',
+    'beaver',
+    'bee',
+    'beetle',
+    'bison',
+    'boar',
+    'buffalo',
+    'bushbaby',
+    'bustard',
+    'butterfly',
+    'camel',
+    'capuchin',
+    'carabao',
+    'caribou',
+    'cat',
+    'caterpillar',
+    'cattle',
+    'chameleon',
+    'chamois',
+    'cheetah',
+    'chicken',
+    'chimpanzee',
+    'chinchilla',
+    'chipmunk',
+    'chough',
+    'cicada',
+    'clam',
+    'cobra',
+    'cockroach',
+    'cod',
+    'cormorant',
+    'coyote',
+    'crab',
+    'crane',
+    'cricket',
+    'crocodile',
+    'crow',
+    'curlew',
+    'deer',
+    'dinosaur',
+    'dog',
+    'dogfish',
+    'dolphin',
+    'donkey',
+    'dotterel',
+    'dove',
+    'dragon',
+    'dragonfly',
+    'duck',
+    'dugong',
+    'dunlin',
+    'eagle',
+    'echidna',
+    'eel',
+    'eland',
+    'elephant',
+    'elk',
+    'emu',
+    'falcon',
+    'ferret',
+    'finch',
+    'fish',
+    'flamingo',
+    'fly',
+    'fox',
+    'frog',
+    'gaur',
+    'gazelle',
+    'gecko',
+    'gerbil',
+    'giraffe',
+    'gnat',
+    'gnu',
+    'goat',
+    'goldfish',
+    'goose',
+    'gorilla',
+    'goshawk',
+    'grasshopper',
+    'grouse',
+    'guanaco',
+    'guinea',
+    'gull',
+    'hamster',
+    'hare',
+    'hawk',
+    'hedgehog',
+    'heron',
+    'herring',
+    'hippopotamus',
+    'hornet',
+    'horse',
+    'horsecrab',
+    'hound',
+    'hummingbird',
+    'hyena',
+    'hyrax',
+    'ibex',
+    'ibis',
+    'iguana',
+    'impala',
+    'insect',
+    'jackal',
+    'jaguar',
+    'jay',
+    'jellyfish',
+    'kangaroo',
+    'koala',
+    'kouprey',
+    'kudu',
+    'lapwing',
+    'lark',
+    'lemming',
+    'lemur',
+    'leopard',
+    'lion',
+    'lizard',
+    'llama',
+    'lobster',
+    'locust',
+    'loris',
+    'louse',
+    'lynx',
+    'lyrebird',
+    'magpie',
+    'mallard',
+    'mammoth',
+    'manatee',
+    'marten',
+    'meerkat',
+    'mink',
+    'minnow',
+    'mole',
+    'mongoose',
+    'monkey',
+    'moose',
+    'mosquito',
+    'mouse',
+    'mule',
+    'muskrat',
+    'narwhal',
+    'newt',
+    'nightingale',
+    'numbat',
+    'octopus',
+    'okapi',
+    'opossum',
+    'oryx',
+    'ostrich',
+    'otter',
+    'owl',
+    'ox',
+    'oyster',
+    'panda',
+    'panther',
+    'parrot',
+    'partridge',
+    'peacock',
+    'peafowl',
+    'pelican',
+    'penguin',
+    'pheasant',
+    'pig',
+    'pigeon',
+    'platypus',
+    'pony',
+    'porcupine',
+    'porpoise',
+    'prairie',
+    'puffin',
+    'pug',
+    'quagga',
+    'quail',
+    'quelea',
+    'rabbit',
+    'raccoon',
+    'ram',
+    'rat',
+    'raven',
+    'reindeer',
+    'rhea',
+    'rhinoceros',
+    'rook',
+    'ruff',
+    'salamander',
+    'salmon',
+    'sambar',
+    'sandpiper',
+    'sardine',
+    'scorpion',
+    'seahorse',
+    'seal',
+    'serval',
+    'shark',
+    'sheep',
+    'shrew',
+    'shrimp',
+    'skink',
+    'skunk',
+    'snail',
+    'snake',
+    'spider',
+    'squid',
+    'squirrel',
+    'starling',
+    'stinkbug',
+    'stork',
+    'swan',
+    'tapir',
+    'tarsier',
+    'termite',
+    'tern',
+    'tiger',
+    'toad',
+    'trout',
+    'turkey',
+    'turtle',
+    'unicorn',
+    'viper',
+    'vulture',
+    'wallaby',
+    'walrus',
+    'wasp',
+    'weasel',
+    'whale',
+    'wolf',
+    'wolverine',
+    'wombat',
+    'woodchuck',
+    'woodcock',
+    'woodpecker',
+    'worm',
+    'wren',
+    'yak',
+    'zebra',
+    'zorilla'
+]
+
+adjectives = [
+    'abiding',
+    'abject',
+    'ablaze',
+    'able',
+    'aboard',
+    'abounding',
+    'absorbed',
+    'absorbing',
+    'abstracted',
+    'abundant',
+    'acceptable',
+    'accessible',
+    'accurate',
+    'acoustic',
+    'adamant',
+    'adaptable',
+    'adhesive',
+    'adjoining',
+    'adorable',
+    'adventurous',
+    'affable',
+    'affectionate',
+    'agreeable',
+    'alert',
+    'alive',
+    'alluring',
+    'amazing',
+    'ambiguous',
+    'ambitious',
+    'amiable',
+    'amicable',
+    'amused',
+    'amusing',
+    'ancient',
+    'animated',
+    'apricot',
+    'aquatic',
+    'arctic',
+    'arenaceous',
+    'aromatic',
+    'aspiring',
+    'assiduous',
+    'assorted',
+    'astonishing',
+    'attractive',
+    'auspicious',
+    'automatic',
+    'available',
+    'average',
+    'awake',
+    'aware',
+    'awesome',
+    'axiomatic',
+    'bashful',
+    'bawdy',
+    'beautiful',
+    'beefy',
+    'befitting',
+    'beneficial',
+    'benevolent',
+    'bent',
+    'best',
+    'better',
+    'bewildered',
+    'bewitching',
+    'big',
+    'billowy',
+    'bizarre',
+    'black',
+    'blithe',
+    'blue',
+    'blushing',
+    'bouncy',
+    'boundless',
+    'brainy',
+    'brash',
+    'brave',
+    'brawny',
+    'brazen',
+    'breezy',
+    'brief',
+    'bright',
+    'brilliant',
+    'broad',
+    'brown',
+    'bucolic',
+    'bulky',
+    'bumpy',
+    'burgundy',
+    'burly',
+    'bustling',
+    'busy',
+    'calm',
+    'capable',
+    'capricious',
+    'captivating',
+    'carefree',
+    'careful',
+    'caring',
+    'carrot',
+    'ceaseless',
+    'cerise',
+    'certain',
+    'challenging',
+    'changeable',
+    'charming',
+    'cheerful',
+    'chief',
+    'chilly',
+    'chipper',
+    'classy',
+    'clean',
+    'clear',
+    'clever',
+    'cloudy',
+    'coherent',
+    'colorful',
+    'colossal',
+    'comfortable',
+    'common',
+    'communicative',
+    'compassionate',
+    'complete',
+    'complex',
+    'compulsive',
+    'confused',
+    'conscientious',
+    'conscious',
+    'conservative',
+    'considerate',
+    'convivial',
+    'cooing',
+    'cool',
+    'cooperative',
+    'coordinated',
+    'courageous',
+    'courteous',
+    'crazy',
+    'creative',
+    'crispy',
+    'crooked',
+    'crowded',
+    'cuddly',
+    'cultured',
+    'cunning',
+    'curious',
+    'curly',
+    'curved',
+    'curvy',
+    'cut',
+    'cute',
+    'daily',
+    'damp',
+    'dapper',
+    'dashing',
+    'dazzling',
+    'dear',
+    'debonair',
+    'decisive',
+    'decorous',
+    'deep',
+    'defiant',
+    'delicate',
+    'delicious',
+    'delighted',
+    'delightful',
+    'delirious',
+    'descriptive',
+    'detached',
+    'detailed',
+    'determined',
+    'different',
+    'diligent',
+    'diminutive',
+    'diplomatic',
+    'discreet',
+    'distinct',
+    'distinctive',
+    'dramatic',
+    'dry',
+    'dynamic',
+    'dynamite',
+    'eager',
+    'early',
+    'earthy',
+    'easy',
+    'easygoing',
+    'eatable',
+    'economic',
+    'ecstatic',
+    'educated',
+    'efficacious',
+    'efficient',
+    'effortless',
+    'eight',
+    'elastic',
+    'elated',
+    'electric',
+    'elegant',
+    'elfin',
+    'elite',
+    'eminent',
+    'emotional',
+    'enchanted',
+    'enchanting',
+    'encouraging',
+    'endless',
+    'energetic',
+    'enormous',
+    'entertaining',
+    'enthusiastic',
+    'envious',
+    'epicurean',
+    'equable',
+    'equal',
+    'eternal',
+    'ethereal',
+    'evanescent',
+    'even',
+    'excellent',
+    'excited',
+    'exciting',
+    'exclusive',
+    'exotic',
+    'expensive',
+    'exquisite',
+    'extroverted',
+    'exuberant',
+    'exultant',
+    'fabulous',
+    'fair',
+    'faithful',
+    'familiar',
+    'famous',
+    'fancy',
+    'fantastic',
+    'far',
+    'fascinated',
+    'fast',
+    'fearless',
+    'female',
+    'fertile',
+    'festive',
+    'few',
+    'fine',
+    'first',
+    'five',
+    'fixed',
+    'flamboyant',
+    'flashy',
+    'flat',
+    'flawless',
+    'flirtatious',
+    'florid',
+    'flowery',
+    'fluffy',
+    'fluttering',
+    'foamy',
+    'foolish',
+    'foregoing',
+    'fortunate',
+    'four',
+    'frank',
+    'free',
+    'frequent',
+    'fresh',
+    'friendly',
+    'full',
+    'functional',
+    'funny',
+    'furry',
+    'future',
+    'futuristic',
+    'fuzzy',
+    'gabby',
+    'gainful',
+    'garrulous',
+    'general',
+    'generous',
+    'gentle',
+    'giant',
+    'giddy',
+    'gifted',
+    'gigantic',
+    'gilded',
+    'glamorous',
+    'gleaming',
+    'glorious',
+    'glossy',
+    'glowing',
+    'godly',
+    'good',
+    'goofy',
+    'gorgeous',
+    'graceful',
+    'grandiose',
+    'grateful',
+    'gratis',
+    'gray',
+    'great',
+    'green',
+    'gregarious',
+    'grey',
+    'groovy',
+    'guiltless',
+    'gusty',
+    'guttural',
+    'habitual',
+    'half',
+    'hallowed',
+    'halting',
+    'handsome',
+    'happy',
+    'hard',
+    'hardworking',
+    'harmonious',
+    'heady',
+    'healthy',
+    'heavenly',
+    'helpful',
+    'hilarious',
+    'historical',
+    'holistic',
+    'hollow',
+    'honest',
+    'honorable',
+    'hopeful',
+    'hospitable',
+    'hot',
+    'huge',
+    'humorous',
+    'hungry',
+    'hushed',
+    'hypnotic',
+    'illustrious',
+    'imaginary',
+    'imaginative',
+    'immense',
+    'imminent',
+    'impartial',
+    'important',
+    'imported',
+    'impossible',
+    'incandescent',
+    'inconclusive',
+    'incredible',
+    'independent',
+    'industrious',
+    'inexpensive',
+    'innate',
+    'innocent',
+    'inquisitive',
+    'instinctive',
+    'intellectual',
+    'intelligent',
+    'intense',
+    'interesting',
+    'internal',
+    'intuitive',
+    'inventive',
+    'invincible',
+    'jazzy',
+    'jolly',
+    'joyful',
+    'joyous',
+    'judicious',
+    'juicy',
+    'jumpy',
+    'keen',
+    'kind',
+    'kindhearted',
+    'kindly',
+    'knotty',
+    'knowing',
+    'knowledgeable',
+    'known',
+    'laconic',
+    'large',
+    'lavish',
+    'lean',
+    'learned',
+    'left',
+    'legal',
+    'level',
+    'light',
+    'likeable',
+    'literate',
+    'little',
+    'lively',
+    'living',
+    'long',
+    'longing',
+    'loud',
+    'lovely',
+    'loving',
+    'loyal',
+    'lucky',
+    'luminous',
+    'lush',
+    'luxuriant',
+    'luxurious',
+    'lyrical',
+    'magenta',
+    'magical',
+    'magnificent',
+    'majestic',
+    'male',
+    'mammoth',
+    'many',
+    'marvelous',
+    'massive',
+    'material',
+    'mature',
+    'meandering',
+    'meaty',
+    'medical',
+    'mellow',
+    'melodic',
+    'melted',
+    'merciful',
+    'mighty',
+    'miniature',
+    'miniscule',
+    'minor',
+    'minute',
+    'misty',
+    'modern',
+    'modest',
+    'momentous',
+    'motionless',
+    'mountainous',
+    'mute',
+    'mysterious',
+    'narrow',
+    'natural',
+    'near',
+    'neat',
+    'nebulous',
+    'necessary',
+    'neighborly',
+    'new',
+    'next',
+    'nice',
+    'nifty',
+    'nimble',
+    'nine',
+    'nippy',
+    'noiseless',
+    'noisy',
+    'nonchalant',
+    'normal',
+    'numberless',
+    'numerous',
+    'nutritious',
+    'obedient',
+    'observant',
+    'obtainable',
+    'oceanic',
+    'omniscient',
+    'one',
+    'open',
+    'opposite',
+    'optimal',
+    'optimistic',
+    'opulent',
+    'orange',
+    'ordinary',
+    'organic',
+    'outgoing',
+    'outrageous',
+    'outstanding',
+    'oval',
+    'overjoyed',
+    'overt',
+    'palatial',
+    'panoramic',
+    'parallel',
+    'passionate',
+    'past',
+    'pastoral',
+    'patient',
+    'peaceful',
+    'perfect',
+    'periodic',
+    'permissible',
+    'perpetual',
+    'persistent',
+    'petite',
+    'philosophical',
+    'physical',
+    'picturesque',
+    'pink',
+    'pioneering',
+    'piquant',
+    'plausible',
+    'pleasant',
+    'plucky',
+    'poised',
+    'polite',
+    'possible',
+    'powerful',
+    'practical',
+    'precious',
+    'premium',
+    'present',
+    'pretty',
+    'previous',
+    'private',
+    'probable',
+    'productive',
+    'profound',
+    'profuse',
+    'protective',
+    'proud',
+    'psychedelic',
+    'public',
+    'pumped',
+    'purple',
+    'purring',
+    'puzzled',
+    'puzzling',
+    'quaint',
+    'quick',
+    'quicker',
+    'quickest',
+    'quiet',
+    'quirky',
+    'quixotic',
+    'quizzical',
+    'rainy',
+    'rapid',
+    'rare',
+    'rational',
+    'ready',
+    'real',
+    'rebel',
+    'receptive',
+    'red',
+    'reflective',
+    'regular',
+    'relaxed',
+    'reliable',
+    'relieved',
+    'remarkable',
+    'reminiscent',
+    'reserved',
+    'resolute',
+    'resonant',
+    'resourceful',
+    'responsible',
+    'rich',
+    'ridiculous',
+    'right',
+    'rightful',
+    'ripe',
+    'ritzy',
+    'roasted',
+    'robust',
+    'romantic',
+    'roomy',
+    'round',
+    'royal',
+    'ruddy',
+    'rural',
+    'rustic',
+    'sable',
+    'safe',
+    'salty',
+    'same',
+    'satisfying',
+    'savory',
+    'scientific',
+    'scintillating',
+    'scrumptious',
+    'second',
+    'secret',
+    'secretive',
+    'seemly',
+    'selective',
+    'sensible',
+    'separate',
+    'shaggy',
+    'shaky',
+    'shining',
+    'shiny',
+    'short',
+    'shy',
+    'silent',
+    'silky',
+    'silly',
+    'simple',
+    'simplistic',
+    'sincere',
+    'six',
+    'sizzling',
+    'skillful',
+    'sleepy',
+    'slick',
+    'slim',
+    'smart',
+    'smiling',
+    'smooth',
+    'soaring',
+    'sociable',
+    'soft',
+    'solid',
+    'sophisticated',
+    'sparkling',
+    'special',
+    'spectacular',
+    'speedy',
+    'spicy',
+    'spiffy',
+    'spiritual',
+    'splendid',
+    'spooky',
+    'spotless',
+    'spotted',
+    'square',
+    'standing',
+    'statuesque',
+    'steadfast',
+    'steady',
+    'steep',
+    'stimulating',
+    'straight',
+    'straightforward',
+    'striking',
+    'striped',
+    'strong',
+    'stunning',
+    'stupendous',
+    'sturdy',
+    'subsequent',
+    'substantial',
+    'subtle',
+    'successful',
+    'succinct',
+    'sudden',
+    'super',
+    'superb',
+    'supreme',
+    'swanky',
+    'sweet',
+    'swift',
+    'sympathetic',
+    'synonymous',
+    'talented',
+    'tall',
+    'tame',
+    'tan',
+    'tangible',
+    'tangy',
+    'tasteful',
+    'tasty',
+    'telling',
+    'temporary',
+    'tempting',
+    'ten',
+    'tender',
+    'terrific',
+    'tested',
+    'thankful',
+    'therapeutic',
+    'thin',
+    'thinkable',
+    'third',
+    'thoughtful',
+    'three',
+    'thrifty',
+    'tidy',
+    'tiny',
+    'toothsome',
+    'towering',
+    'tranquil',
+    'tremendous',
+    'tricky',
+    'true',
+    'truthful',
+    'two',
+    'typical',
+    'ubiquitous',
+    'ultra',
+    'unassuming',
+    'unbiased',
+    'uncovered',
+    'understanding',
+    'understood',
+    'unequaled',
+    'unique',
+    'unusual',
+    'unwritten',
+    'upbeat',
+    'useful',
+    'utopian',
+    'utter',
+    'uttermost',
+    'valuable',
+    'various',
+    'vast',
+    'verdant',
+    'vermilion',
+    'versatile',
+    'versed',
+    'victorious',
+    'vigorous',
+    'violet',
+    'vivacious',
+    'voiceless',
+    'voluptuous',
+    'wacky',
+    'waiting',
+    'wakeful',
+    'wandering',
+    'warm',
+    'warmhearted',
+    'wealthy',
+    'whimsical',
+    'whispering',
+    'white',
+    'whole',
+    'wholesale',
+    'whopping',
+    'wide',
+    'wiggly',
+    'wild',
+    'willing',
+    'windy',
+    'winsome',
+    'wiry',
+    'wise',
+    'wistful',
+    'witty',
+    'womanly',
+    'wonderful',
+    'workable',
+    'young',
+    'youthful',
+    'yummy',
+    'zany',
+    'zealous',
+    'zesty',
+    'zippy'
+]
+
+def randomtopicname(ui):
+    if ui.configint("devel", "randomseed"):
+        random.seed(ui.configint("devel", "randomseed"))
+    return random.choice(adjectives) + "-" + random.choice(animals)
--- a/hgext3rd/topic/stack.py	Wed Sep 27 01:18:39 2017 +0200
+++ b/hgext3rd/topic/stack.py	Fri Oct 20 18:43:55 2017 +0200
@@ -34,9 +34,9 @@
         if topic is not None and branch is not None:
             raise error.ProgrammingError('both branch and topic specified (not defined yet)')
         elif topic is not None:
-            trevs = repo.revs("topic(%s) - obsolete()", topic)
+            trevs = repo.revs("not obsolete() and topic(%s)", topic)
         elif branch is not None:
-            trevs = repo.revs("branch(%s) - public() - obsolete() - topic()", branch)
+            trevs = repo.revs("not public() and branch(%s) - obsolete() - topic()", branch)
         else:
             raise error.ProgrammingError('neither branch and topic specified (not defined yet)')
         self._revs = trevs
@@ -275,28 +275,30 @@
     # super crude initial version
     for idx, isentry, ctx in entries[::-1]:
 
+        symbol = None
         states = []
         iscurrentrevision = repo.revs('%d and parents()', ctx.rev())
 
+        if iscurrentrevision:
+            states.append('current')
+            symbol = '@'
+
+        if ctx.orphan():
+            symbol = '$'
+            states.append('unstable')
+
         if not isentry:
             symbol = '^'
             # "base" is kind of a "ghost" entry
-            # skip other label for them (no current, no unstable)
-            states = ['base']
-        elif ctx.orphan():
-            # current revision can be unstable also, so in that case show both
-            # the states and the symbol '@' (issue5553)
-            if iscurrentrevision:
-                states.append('current')
-                symbol = '@'
-            symbol = '$'
-            states.append('unstable')
-        elif iscurrentrevision:
-            states.append('current')
-            symbol = '@'
-        else:
+            states.append('base')
+
+        # none of the above if statments get executed
+        if not symbol:
             symbol = ':'
             states.append('clean')
+
+        states.sort()
+
         fm.startitem()
         fm.data(isentry=isentry)
 
--- a/tests/test-check-flake8.t	Wed Sep 27 01:18:39 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#require test-repo
-
-  $ checkflake8() {
-  >   if ! (which flake8 > /dev/null); then
-  >     echo skipped: missing tool: flake8;
-  >     exit 80;
-  >   fi;
-  > };
-  $ checkflake8
-
-Copied from Mercurial core (60ee2593a270)
-
-  $ cd "`dirname "$TESTDIR"`"
-
-run flake8 if it exists; if it doesn't, then just skip
-
-  $ hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' 2>/dev/null \
-  > | xargs -0 flake8
--- a/tests/test-check-setup-manifest.t	Wed Sep 27 01:18:39 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#require test-repo
-
-  $ checkcm() {
-  >   if ! (which check-manifest > /dev/null); then
-  >     echo skipped: missing tool: check-manifest;
-  >     exit 80;
-  >   fi;
-  > };
-  $ checkcm
-  $ cat << EOF >> $HGRCPATH
-  > [experimental]
-  > evolution=all
-  > EOF
-
-Run check manifest:
-
-  $ cd $TESTDIR/..
-  $ check-manifest
-  lists of files in version control and sdist match
--- a/tests/test-evolve-cycles.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-evolve-cycles.t	Fri Oct 20 18:43:55 2017 +0200
@@ -292,7 +292,7 @@
                       0
                   ],
                   "effect": [
-                      *, (glob)
+                      "description",
                       "parent",
                       "content"
                   ],
--- a/tests/test-evolve-obshistory.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-evolve-obshistory.t	Fri Oct 20 18:43:55 2017 +0200
@@ -243,7 +243,7 @@
   $ hg obslog 'desc(B0)' --hidden --patch
   x  0dec01379d3b (2) B0
        pruned by test (*) (glob)
-         (No patch available yet, no successors)
+         (No patch available, no successors)
   
   $ hg obslog 'desc(B0)' --hidden --no-graph -Tjson | python -m json.tool
   [
@@ -377,7 +377,7 @@
   $ hg obslog 471597cad322 --hidden --patch
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
   $ hg obslog 471597cad322 --hidden --no-graph -Tjson | python -m json.tool
   [
@@ -412,7 +412,7 @@
   |
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
 With the all option, it should show the three changesets
   $ hg obslog --all 337fec4d2edc --patch
@@ -422,7 +422,7 @@
   |/
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
 Check that debugobshistory on the second successor after split show
 the revision plus the splitted one
@@ -431,7 +431,7 @@
   |
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
 With the all option, it should show the three changesets
   $ hg obslog f257fde29c7a --all --patch
@@ -441,7 +441,7 @@
   |/
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
 Obslog with all option all should also works on the splitted commit
   $ hg obslog -a 471597cad322 --hidden --patch
@@ -451,7 +451,7 @@
   |/
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
 Check that debugobshistory on both successors after split show
 a coherent graph
@@ -462,7 +462,7 @@
   |/
   x  471597cad322 (1) A0
        rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (2))
+         (No patch available, too many successors (2))
   
   $ hg update 471597cad322
   abort: hidden revision '471597cad322'!
@@ -629,7 +629,7 @@
   $ hg obslog de7290d8b885 --hidden --patch
   x  de7290d8b885 (1) A0
        rewritten(parent, content) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (4))
+         (No patch available, too many successors (4))
   
   $ hg obslog de7290d8b885 --hidden --all --patch
   o  1ae8bc733a14 (4) A0
@@ -642,7 +642,7 @@
   |/
   x  de7290d8b885 (1) A0
        rewritten(parent, content) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (4))
+         (No patch available, too many successors (4))
   
   $ hg obslog de7290d8b885 --hidden --no-graph -Tjson | python -m json.tool
   [
@@ -677,7 +677,7 @@
   |
   x  de7290d8b885 (1) A0
        rewritten(parent, content) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (4))
+         (No patch available, too many successors (4))
   
   $ hg obslog c7f044602e9b --no-graph -Tjson | python -m json.tool
   [
@@ -725,7 +725,7 @@
   |/
   x  de7290d8b885 (1) A0
        rewritten(parent, content) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (4))
+         (No patch available, too many successors (4))
   
   $ hg obslog 5 --all --patch
   o  1ae8bc733a14 (4) A0
@@ -738,7 +738,7 @@
   |/
   x  de7290d8b885 (1) A0
        rewritten(parent, content) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a by test (*) (glob)
-         (No patch available yet, too many successors (4))
+         (No patch available, too many successors (4))
   
   $ hg update de7290d8b885
   abort: hidden revision 'de7290d8b885'!
@@ -830,7 +830,7 @@
   |\
   x |  0dec01379d3b (2) B0
    /     rewritten(description, parent, content) as eb5a0daa2192 by test (*) (glob)
-  |        (No patch available yet, changesets rebased)
+  |        (No patch available, changesets rebased)
   |
   x  471f378eab4c (1) A0
        rewritten(description, content) as eb5a0daa2192 by test (*) (glob)
@@ -852,7 +852,7 @@
   $ hg obslog --hidden 0dec01379d3b --patch
   x  0dec01379d3b (2) B0
        rewritten(description, parent, content) as eb5a0daa2192 by test (*) (glob)
-         (No patch available yet, changesets rebased)
+         (No patch available, changesets rebased)
   
 Check that with all option, all changesets are shown
   $ hg obslog --hidden --all 0dec01379d3b --patch
@@ -860,7 +860,7 @@
   |\
   x |  0dec01379d3b (2) B0
    /     rewritten(description, parent, content) as eb5a0daa2192 by test (*) (glob)
-  |        (No patch available yet, changesets rebased)
+  |        (No patch available, changesets rebased)
   |
   x  471f378eab4c (1) A0
        rewritten(description, content) as eb5a0daa2192 by test (*) (glob)
@@ -884,7 +884,7 @@
   |\
   x |  0dec01379d3b (2) B0
    /     rewritten(description, parent, content) as eb5a0daa2192 by test (*) (glob)
-  |        (No patch available yet, changesets rebased)
+  |        (No patch available, changesets rebased)
   |
   x  471f378eab4c (1) A0
        rewritten(description, content) as eb5a0daa2192 by test (*) (glob)
@@ -917,7 +917,7 @@
                       0 (glob)
                   ],
                   "effect": [
-                      *, (glob)
+                      "description",
                       "content"
                   ],
                   "succnodes": [
@@ -1375,7 +1375,7 @@
   |
   x  b7ea6d14e664 (3) B1
   |    rewritten(description, parent, content) as eb5a0daa2192 by test (*) (glob)
-  |      (No patch available yet, changesets rebased)
+  |      (No patch available, changesets rebased)
   |
   x  0dec01379d3b (2) B0
        rewritten(description) as b7ea6d14e664 by test (*) (glob)
@@ -1407,7 +1407,7 @@
   |
   x  b7ea6d14e664 (3) B1
   |    rewritten(description, parent, content) as eb5a0daa2192 by test (*) (glob)
-  |      (No patch available yet, changesets rebased)
+  |      (No patch available, changesets rebased)
   |
   x  0dec01379d3b (2) B0
        rewritten(description) as b7ea6d14e664 by test (*) (glob)
@@ -1622,20 +1622,20 @@
   |
   x  fdf9bde5129a
   |    rewritten(description) as 7a230b46bf61 by test (*) (glob)
-  |      (No patch available yet, context is not local)
+  |      (No patch available, context is not local)
   |
   @  471f378eab4c (1) A0
        rewritten(description) as fdf9bde5129a by test (*) (glob)
-         (No patch available yet, succ is unknown locally)
+         (No patch available, successor is unknown locally)
   
   $ hg obslog 7a230b46bf61 --color=debug --patch
   o  [evolve.node|7a230b46bf61] [evolve.rev|(2)] [evolve.short_description|A2]
   |
   x  [evolve.node evolve.missing_change_ctx|fdf9bde5129a]
   |    [evolve.verb|rewritten](description) as [evolve.node|7a230b46bf61] by [evolve.user|test] [evolve.date|(*)] (glob)
-  |      (No patch available yet, context is not local)
+  |      (No patch available, context is not local)
   |
   @  [evolve.node|471f378eab4c] [evolve.rev|(1)] [evolve.short_description|A0]
        [evolve.verb|rewritten](description) as [evolve.node|fdf9bde5129a] by [evolve.user|test] [evolve.date|(*)] (glob)
-         (No patch available yet, succ is unknown locally)
+         (No patch available, successor is unknown locally)
   
--- a/tests/test-evolve-order.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-evolve-order.t	Fri Oct 20 18:43:55 2017 +0200
@@ -102,7 +102,7 @@
   |/
   o  0:f92638be10c7@default(public) add p
   
-  $ hg evolve --rev "unstable()"
+  $ hg evolve --rev "orphan()"
   move:[11] bprime
   atop:[12] asecond
   move:[7] add _c
@@ -257,7 +257,7 @@
   2 files updated, 0 files merged, 3 files removed, 0 files unresolved
   $ hg amend -m 'b3second'
   1 new unstable changesets
-  $ hg evolve --rev 'unstable()'
+  $ hg evolve --rev "orphan()"
   move:[30] add b4_
   atop:[35] b3second
   skipping 0b9488394e89: divergent rewriting. can't choose destination
--- a/tests/test-evolve-templates.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-evolve-templates.t	Fri Oct 20 18:43:55 2017 +0200
@@ -30,7 +30,7 @@
   $ mkcommit ROOT
   $ mkcommit A0
   $ echo 42 >> A0
-  $ HGUSER=test1 hg amend -m "A1" --config devel.default-date="1234567890 0"
+  $ HGUSER=test hg amend -m "A1" --config devel.default-date="1234567890 0"
   $ HGUSER=test2 hg amend -m "A2" --config devel.default-date="987654321 0"
   $ hg log --hidden -G
   @  changeset:   4:d004c8f274b9
@@ -76,7 +76,7 @@
   |    rewritten(description) as d004c8f274b9 by test2 (*) (glob)
   |
   @  471f378eab4c (1) A0
-       rewritten(description, content) as a468dc9b3633 by test1 (*) (glob)
+       rewritten(description, content) as a468dc9b3633 by test (*) (glob)
   
   $ hg tlog
   o  d004c8f274b9
--- a/tests/test-evolve.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-evolve.t	Fri Oct 20 18:43:55 2017 +0200
@@ -384,9 +384,9 @@
 
 Test commit -o options
 
-  $ hg up 6
+  $ hg up -r "desc('a nifty feature')"
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ hg revert -r 7 --all
+  $ hg revert -r "desc('another feature')" --all
   adding file-from-B
   reverting main-file-1
   $ sed -i'' -e s/Zwei/deux/ main-file-1
@@ -399,7 +399,7 @@
 
 phase change turning obsolete changeset public issue a bumped warning
 
-  $ hg phase --hidden --public 7
+  $ hg phase --hidden --public 99833d22b0c6
   1 new bumped changesets
 
 all solving bumped troubled
@@ -428,22 +428,22 @@
   |
   o  0	: base - test
   
-  $ hg diff --hidden -r 9 -r 8
-  $ hg diff -r 9^ -r 9
+  $ hg diff --hidden -r 6707c5e1c49d -r 47d52a103155
+  $ hg diff -r 6707c5e1c49d^ -r 6707c5e1c49d
   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
+  $ hg log -r 'phasedivergent()' # 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
+  $ hg update 6707c5e1c49d
   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!'
@@ -952,12 +952,12 @@
 
 Evolve from the middle of a stack pick the right changesets.
 
-  $ hg up 7
+  $ hg up -r "desc('a1_')"
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg ci --amend -m 'a1__'
   2 new unstable changesets
 
-  $ hg up 8
+  $ hg up -r "desc('a2')"
   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__
@@ -978,7 +978,7 @@
 
 Evolve disables active bookmarks.
 
-  $ hg up 10
+  $ hg up -r "desc('a1__')"
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg bookmark testbookmark
   $ ls .hg/bookmarks*
@@ -991,25 +991,25 @@
   working directory is now at d952e93add6f
   $ ls .hg/bookmarks*
   .hg/bookmarks
-  $ hg log -G
-  @  11	: a2 - test
+  $ glog
+  @  11:d952e93add6f@mybranch(draft) a2
   |
-  o  10	testbookmark: a1__ - test
+  o  10:9f8b83c2e7f3@default(draft) a1__
   |
-  | o  9	: a3 - test
+  | o  9:777c26ca5e78@mybranch(draft) a3
   | |
-  | x  8	: a2 - test
+  | x  8:eb07e22a0e63@mybranch(draft) a2
   | |
-  | x  7	: a1_ - test
+  | x  7:faafc6cea0ba@default(draft) a1_
   |/
-  o  0	: a0 - test
+  o  0:07c1c36d9ef0@default(draft) a0
   
 
 Possibility to select what trouble to solve first, asking for bumped before
 divergent
-  $ hg up 10
+  $ hg up -r "desc('a1__')"
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg revert -r 11 --all
+  $ hg revert -r d952e93add6f --all
   reverting a
   $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
   o  11 [mybranch] a2
@@ -1027,7 +1027,7 @@
   $ echo "hello world" > newfile
   $ hg add newfile
   $ hg commit -m "add new file bumped" -o 11
-  $ hg phase --public --hidden 11
+  $ hg phase --public --hidden d952e93add6f
   1 new bumped changesets
   $ hg log -G
   @  12	: add new file bumped - test
@@ -1063,7 +1063,7 @@
   |/
   o  0	: a0 - test
   
-  $ hg evolve -r 12 --phasedivergent
+  $ hg evolve -r "desc('add new file bumped')" --phasedivergent
   recreate:[12] add new file bumped
   atop:[11] a2
   computing new diff
@@ -1073,18 +1073,6 @@
   move:[9] a3
   atop:[13] bumped update to d952e93add6f:
   working directory is now at cce26b684bfe
-  $ glog
-  @  14:cce26b684bfe@default(draft) a3
-  |
-  o  13:f15d32934071@default(draft) bumped update to d952e93add6f:
-  |
-  o  11:d952e93add6f@mybranch(public) a2
-  |
-  o  10:9f8b83c2e7f3@default(public) a1__
-  |
-  o  0:07c1c36d9ef0@default(public) a0
-  
-
 Check that we can resolve troubles in a revset with more than one commit
   $ hg up cce26b684bfe -C
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1132,15 +1120,15 @@
   
 
 Evolving an empty revset should do nothing
-  $ hg evolve --rev "16 and 15"
+  $ hg evolve --rev "beb41503aa3e and 27247fcb2df6"
   set of specified revisions is empty
   [1]
 
-  $ hg evolve --rev "14::" --phasedivergent
+  $ hg evolve --rev "cce26b684bfe::" --phasedivergent
   no phasedivergent changesets in specified revisions
   (do you want to use --orphan)
   [2]
-  $ hg evolve --rev "14::" --orphan
+  $ hg evolve --rev "cce26b684bfe::" --orphan
   move:[15] add gg
   atop:[18] a3
   move:[16] add gh
@@ -1263,7 +1251,7 @@
   > EOF
 
 Check hg evolve --rev on singled out commit
-  $ hg up 19 -C
+  $ hg up 24e63b319adf -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ mkcommit j1
   $ mkcommit j2
@@ -1274,7 +1262,7 @@
   $ hg add j4
   $ hg amend
   2 new unstable changesets
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   @  25:8dc373be86d9@default(draft) add j1
   |
   | o  23:d7eadcf6eccd@default(draft) add j3
@@ -1291,10 +1279,10 @@
   |
   ~
 
-  $ hg evolve --rev 23 --any
+  $ hg evolve --rev d7eadcf6eccd --any
   abort: cannot specify both "--rev" and "--any"
   [255]
-  $ hg evolve --rev 23
+  $ hg evolve --rev d7eadcf6eccd
   cannot solve instability of d7eadcf6eccd, skipping
 
 Check that uncommit respects the allowunstable option
@@ -1314,7 +1302,7 @@
   $ hg uncommit --all
   new changeset is empty
   (use 'hg prune .' to remove it)
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   @  26:044804d0c10d@default(draft) add j1
   |
   | o  23:d7eadcf6eccd@default(draft) add j3
@@ -1334,7 +1322,7 @@
 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
+  $ hg up e02107f98737
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg evolve --all
   nothing to evolve on current working copy parent
@@ -1346,7 +1334,7 @@
   move:[23] add j3
   atop:[27] add j2
   working directory is now at c9a20e2d74aa
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   @  28:c9a20e2d74aa@default(draft) add j3
   |
   o  27:b0e3066231e2@default(draft) add j2
@@ -1364,17 +1352,17 @@
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ mkcommit c5_
   created new head
-  $ hg prune '26 + 27'
+  $ hg prune '044804d0c10d + b0e3066231e2'
   abort: touch will orphan 1 descendants
   (see 'hg help evolution.instability')
   [255]
-  $ hg prune '19::28'
+  $ hg prune '24e63b319adf::c9a20e2d74aa'
   abort: touch will orphan 1 descendants
   (see 'hg help evolution.instability')
   [255]
-  $ hg prune '26::'
+  $ hg prune '044804d0c10d::'
   3 changesets pruned
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   @  29:2251801b6c91@default(draft) add c5_
   |
   | o  20:e02107f98737@default(draft) add gh
@@ -1393,7 +1381,7 @@
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ mkcommit unstableifparentisfolded
   created new head
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   @  30:68330ac625b8@default(draft) add unstableifparentisfolded
   |
   | o  29:2251801b6c91@default(draft) add c5_
@@ -1406,7 +1394,7 @@
   |
   ~
 
-  $ hg fold --exact "19::"
+  $ hg fold --exact "24e63b319adf::"
   2 changesets folded
 
 Check that evolve shows error while handling split commits
@@ -1417,7 +1405,7 @@
   > evolution=all
   > EOF
 
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   o  31:580886d07058@default(draft) add gg
   |
   | @  30:68330ac625b8@default(draft) add unstableifparentisfolded
@@ -1446,7 +1434,7 @@
   $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')" --split
   1 changesets pruned
   1 new unstable changesets
-  $ glog -r "18::"
+  $ glog -r "edc3c9de504e::"
   @  35:7a555adf2b4a@default(draft) _pp
   |
   o  34:2be4d2d5bf34@default(draft) _oo
@@ -1464,7 +1452,7 @@
   o  18:edc3c9de504e@default(draft) a3
   |
   ~
-  $ hg evolve --rev "18::"
+  $ hg evolve --rev "edc3c9de504e::"
   move:[33] add uu
   atop:[35] _pp
   working directory is now at 43c3f5ef149f
@@ -1486,35 +1474,12 @@
   $ hg add newlyadded
   $ hg commit -m "will cause conflict at evolve"
 
-  $ glog -r "edc3c9de504e::"
-  @  39:02e943732647@default(draft) will cause conflict at evolve
-  |
-  o  38:f8e30e9317aa@default(draft) will be evolved safely
-  |
-  o  37:36030b147271@default(draft) will be amended
-  |
-  o  36:43c3f5ef149f@default(draft) add uu
-  |
-  o  35:7a555adf2b4a@default(draft) _pp
-  |
-  o  34:2be4d2d5bf34@default(draft) _oo
-  |
-  | 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 update -q 36030b147271
   $ echo "amended" > newfile
   $ hg amend -m "amended"
   2 new unstable changesets
 
-  $ hg evolve --rev "37::"
+  $ hg evolve --rev "36030b147271::"
   move:[38] will be evolved safely
   atop:[41] amended
   move:[39] will cause conflict at evolve
@@ -1526,7 +1491,7 @@
   abort: unresolved merge conflicts (see hg help resolve)
   [255]
 
-  $ glog -r "36::" --hidden
+  $ glog -r "43c3f5ef149f::" --hidden
   @  42:c904da5245b0@default(draft) will be evolved safely
   |
   o  41:34ae045ec400@default(draft) amended
--- a/tests/test-exchange-obsmarkers-case-A6.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-exchange-obsmarkers-case-A6.t	Fri Oct 20 18:43:55 2017 +0200
@@ -74,7 +74,7 @@
   $ inspect_obsmarkers
   obsstore content
   ================
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   obshashtree
   ===========
   a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04 0000000000000000000000000000000000000000
@@ -100,7 +100,7 @@
   # testing echange of "A1" (e5ea8f9c7314)
   ## initial state
   # obstore: main
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
   # obstore: pulldest
   ## pushing "A1" from main to pushdest
@@ -110,9 +110,9 @@
   remote: 1 new obsolescence markers
   ## post push state
   # obstore: main
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pulldest
   ## pulling "e5ea8f9c7314" from main into pulldest
   pulling from main
@@ -120,11 +120,11 @@
   1 new obsolescence markers
   ## post pull state
   # obstore: main
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pulldest
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
 
 Actual Test (bare push version)
 -------------------------------
@@ -133,7 +133,7 @@
   ## Running testcase A.6.b
   ## initial state
   # obstore: main
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
   # obstore: pulldest
   ## pushing from main to pushdest
@@ -143,9 +143,9 @@
   remote: 1 new obsolescence markers
   ## post push state
   # obstore: main
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pulldest
   ## pulling from main into pulldest
   pulling from main
@@ -154,8 +154,8 @@
   1 new obsolescence markers
   ## post pull state
   # obstore: main
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pulldest
-  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (*) {'user': 'test'} (glob)
+  28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- a/tests/test-exchange-obsmarkers-case-A7.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-exchange-obsmarkers-case-A7.t	Fri Oct 20 18:43:55 2017 +0200
@@ -59,7 +59,7 @@
   $ inspect_obsmarkers
   obsstore content
   ================
-  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (*) {'user': 'test'} (glob)
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   obshashtree
   ===========
   a9bdc8b26820b1b87d585b82eb0ceb4a2ecdbc04 0000000000000000000000000000000000000000
@@ -81,7 +81,7 @@
   # testing echange of "O" (a9bdc8b26820)
   ## initial state
   # obstore: main
-  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (*) {'user': 'test'} (glob)
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
   # obstore: pulldest
   ## pushing "O" from main to pushdest
@@ -90,7 +90,7 @@
   no changes found
   ## post push state
   # obstore: main
-  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (*) {'user': 'test'} (glob)
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
   # obstore: pulldest
   ## pulling "a9bdc8b26820" from main into pulldest
@@ -98,6 +98,6 @@
   no changes found
   ## post pull state
   # obstore: main
-  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (*) {'user': 'test'} (glob)
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f5bc6836db60e308a17ba08bf050154ba9c4fad7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
   # obstore: pushdest
   # obstore: pulldest
--- a/tests/test-inhibit.t	Wed Sep 27 01:18:39 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,931 +0,0 @@
-  $ 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
-  1 new bumped changesets
-  $ 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! (2d66e189f5b5)
-  $ 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 -fr 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 "71eb4f100663::"
-  @  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 8c1c2edbaf1b -s 1192fa9fbc68
-  1 changesets pruned
-  $ hg up 71eb4f100663
-  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
-  $ hg rebase -r "8c1c2edbaf1b + c5a47ab27c2e" --keep -d 1192fa9fbc68 --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 "71eb4f100663::"
-  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 8c1c2edbaf1b -d 1192fa9fbc68 --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 "71eb4f100663::"
-  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 (glob)
-  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
--- a/tests/test-obsolete.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-obsolete.t	Fri Oct 20 18:43:55 2017 +0200
@@ -143,7 +143,7 @@
   $ qlog -r 'suspended()'
   3
   - 0d3f46688ccc
-  $ qlog -r 'unstable()'
+  $ qlog -r "orphan()"
   5
   - a7a6f2b5d8a5
 
@@ -573,7 +573,7 @@
   |
   o  0 - (public) 1f0dee641bb7 add a
   
-  $ hg log -r 'bumped()'
+  $ hg log -r 'phasedivergent()'
   changeset:   12:6db5e282cb91
   tag:         tip
   parent:      10:2033b4e49474
@@ -666,7 +666,7 @@
   phases: 3 draft
   bumped: 1 changesets
   $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63`
-  $ hg log -r 'divergent()'
+  $ hg log -r 'contentdivergent()'
   changeset:   12:6db5e282cb91
   parent:      10:2033b4e49474
   user:        test
--- a/tests/test-sharing.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-sharing.t	Fri Oct 20 18:43:55 2017 +0200
@@ -513,7 +513,7 @@
   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()'
+  $ hg log -q -r 'contentdivergent()'
 
 Figure SG10: Bob's repository after fixing divergence.
   $ hg --hidden shortlog -G -r 3::
--- a/tests/test-split.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-split.t	Fri Oct 20 18:43:55 2017 +0200
@@ -489,4 +489,4 @@
   summary:     split8
   
   $ hg topic
-   * mytopic
+   * mytopic (2 changesets)
--- a/tests/test-stabilize-conflict.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-stabilize-conflict.t	Fri Oct 20 18:43:55 2017 +0200
@@ -65,7 +65,7 @@
   $ safesed 's/huit/eight/' babar
   $ hg diff
   diff -r 9d5daf8bd956 babar
-  --- a/babar	Thu Jan 01 00:00:00 1970 +0000
+  --- a/babar	* (glob)
   +++ b/babar	* (glob)
   @@ -5,6 +5,6 @@
    cinq
@@ -160,7 +160,7 @@
   
 (fix the conflict and continue)
 
-  $ hg revert -r 71c18f70c34f --all
+  $ hg revert -r 5 --all
   reverting babar
   $ safesed 's/dix/ten/' babar
   $ hg resolve --all -m
--- a/tests/test-stabilize-order.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-stabilize-order.t	Fri Oct 20 18:43:55 2017 +0200
@@ -89,7 +89,7 @@
 
 Test stabilizing a descendant predecessor's child
 
-  $ hg up -r 005fe5914f78
+  $ hg up 7
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg debugobsolete > successors.old
   $ hg evolve -v
@@ -133,7 +133,7 @@
 
 Test behavior with --any
 
-  $ hg up 81b8bbcd5892
+  $ hg up 8
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo b >> b
   $ hg amend
@@ -149,7 +149,7 @@
   |
   o  0:c471ef929e6a@default(draft) addroot
   
-  $ hg up 0f691739f917
+  $ 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
--- a/tests/test-stabilize-result.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-stabilize-result.t	Fri Oct 20 18:43:55 2017 +0200
@@ -86,7 +86,7 @@
   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 revert -r "orphan()" a
   $ hg diff
   diff -r 66719795a494 a
   --- a/a	* (glob)
@@ -341,7 +341,7 @@
   2 new divergent changesets
 # reamend so that the case is not the first precursor.
   $ hg amend -m "More addition (2)"
-  $ hg phase 'divergent()'
+  $ hg phase 'contentdivergent()'
   21: draft
   24: draft
   $ hg evolve -qn --contentdivergent
--- a/tests/test-stack-branch.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-stack-branch.t	Fri Oct 20 18:43:55 2017 +0200
@@ -251,7 +251,7 @@
   ### target: foo (branch) (2 heads)
   b6$ c_f (unstable)
   b5$ c_e (unstable)
-  b2^ c_D (base)
+  b2^ c_D (base current)
   b4: c_h
   b3: c_g
   b2@ c_D (current)
@@ -285,7 +285,7 @@
   ### target: foo (branch) (2 heads)
   b6$ c_f (unstable)
   b5$ c_e (unstable)
-  b2^ c_D (base)
+  b2^ c_D (base current)
   b4: c_h
   b3: c_g
   b2@ c_D (current)
@@ -296,7 +296,7 @@
   ### target: foo (branch) (2 heads)
   b5$ c_f (unstable)
   b4$ c_e (unstable)
-  b1^ c_D (base)
+  b1^ c_D (base current)
   b3: c_h
   b2: c_g
   b1@ c_D (current)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-topic-change.t	Fri Oct 20 18:43:55 2017 +0200
@@ -0,0 +1,368 @@
+Tests for changing and clearing topics
+======================================
+
+  $ . "$TESTDIR/testlib/topic_setup.sh"
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > # disable the new graph style until we drop 3.7 support
+  > graphstyle.missing = |
+  > evolution=createmarkers, allowunstable
+  > [phases]
+  > publish=false
+  > [alias]
+  > glog = log -G -T "{rev}:{node|short} \{{topics}}\n{desc}  ({bookmarks})\n\n"
+  > EOF
+
+About the glog output: {} contains the topic name and () will contain the bookmark
+
+Setting up a repo
+----------------
+
+  $ hg init topics
+  $ cd topics
+  $ for ch in a b c d e f g h; do touch $ch; echo "foo" >> $ch; hg ci -Aqm "Added "$ch; done
+
+  $ hg glog
+  @  7:ec2426147f0e {}
+  |  Added h  ()
+  |
+  o  6:87d6d6676308 {}
+  |  Added g  ()
+  |
+  o  5:825660c69f0c {}
+  |  Added f  ()
+  |
+  o  4:aa98ab95a928 {}
+  |  Added e  ()
+  |
+  o  3:62615734edd5 {}
+  |  Added d  ()
+  |
+  o  2:28ad74487de9 {}
+  |  Added c  ()
+  |
+  o  1:29becc82797a {}
+  |  Added b  ()
+  |
+  o  0:18d04c59bb5d {}
+     Added a  ()
+  
+
+Clearing topic from revision without topic
+
+  $ hg topic -r . --clear
+  changed topic on 0 changes
+
+Clearing current topic when no active topic is not error
+
+  $ hg topic
+  $ hg topic --clear
+
+Setting topics to all the revisions
+
+  $ hg topic -r 0:: foo
+  switching to topic foo
+  changed topic on 8 changes
+  $ hg glog
+  @  15:05095f607171 {foo}
+  |  Added h  ()
+  |
+  o  14:97505b53ab0d {foo}
+  |  Added g  ()
+  |
+  o  13:75a8360fe626 {foo}
+  |  Added f  ()
+  |
+  o  12:abcedffeae90 {foo}
+  |  Added e  ()
+  |
+  o  11:1315a3808ed0 {foo}
+  |  Added d  ()
+  |
+  o  10:1fa891977a22 {foo}
+  |  Added c  ()
+  |
+  o  9:a53ba98dd6b8 {foo}
+  |  Added b  ()
+  |
+  o  8:86a186070af2 {foo}
+     Added a  ()
+  
+
+Clearing the active topic using --clear
+
+  $ hg topic
+   * foo (8 changesets)
+  $ hg topic --clear
+  $ hg topic
+     foo (8 changesets)
+Changing topics on some revisions (also testing issue 5441)
+
+  $ hg topic -r 12:: bar
+  switching to topic bar
+  changed topic on 4 changes
+  $ hg glog
+  @  19:d7d36e193ea7 {bar}
+  |  Added h  ()
+  |
+  o  18:e7b418d79a05 {bar}
+  |  Added g  ()
+  |
+  o  17:82e0b14f4d9e {bar}
+  |  Added f  ()
+  |
+  o  16:edc4a6b9ea60 {bar}
+  |  Added e  ()
+  |
+  o  11:1315a3808ed0 {foo}
+  |  Added d  ()
+  |
+  o  10:1fa891977a22 {foo}
+  |  Added c  ()
+  |
+  o  9:a53ba98dd6b8 {foo}
+  |  Added b  ()
+  |
+  o  8:86a186070af2 {foo}
+     Added a  ()
+  
+
+Changing topics without passing topic name and clear
+
+  $ hg topic -r .
+  abort: changing topic requires a topic name or --clear
+  [255]
+
+Changing topic using --current flag
+
+  $ hg topic foobar
+  $ hg topic -r . --current
+  active topic 'foobar' grew its first changeset
+  changed topic on 1 changes
+  $ hg glog -r .
+  @  20:c2d6b7df5dcf {foobar}
+  |  Added h  ()
+  |
+
+Changing topic in between the stack
+
+  $ hg topic -r 9::10 --current
+  changed topic on 2 changes
+  $ hg glog
+  o  22:1b88140feefe {foobar}
+  |  Added c  ()
+  |
+  o  21:c39cabfcbbf7 {foobar}
+  |  Added b  ()
+  |
+  | @  20:c2d6b7df5dcf {foobar}
+  | |  Added h  ()
+  | |
+  | o  18:e7b418d79a05 {bar}
+  | |  Added g  ()
+  | |
+  | o  17:82e0b14f4d9e {bar}
+  | |  Added f  ()
+  | |
+  | o  16:edc4a6b9ea60 {bar}
+  | |  Added e  ()
+  | |
+  | o  11:1315a3808ed0 {foo}
+  | |  Added d  ()
+  | |
+  | x  10:1fa891977a22 {foo}
+  | |  Added c  ()
+  | |
+  | x  9:a53ba98dd6b8 {foo}
+  |/   Added b  ()
+  |
+  o  8:86a186070af2 {foo}
+     Added a  ()
+  
+  $ hg rebase -s 11 -d 22
+  rebasing 11:1315a3808ed0 "Added d"
+  switching to topic foo
+  rebasing 16:edc4a6b9ea60 "Added e"
+  switching to topic bar
+  rebasing 17:82e0b14f4d9e "Added f"
+  rebasing 18:e7b418d79a05 "Added g"
+  rebasing 20:c2d6b7df5dcf "Added h"
+  switching to topic foobar
+
+  $ hg glog
+  @  27:a1a9465da59b {foobar}
+  |  Added h  ()
+  |
+  o  26:7c76c271395f {bar}
+  |  Added g  ()
+  |
+  o  25:7f26084dfaf1 {bar}
+  |  Added f  ()
+  |
+  o  24:b1f05e9ba0b5 {bar}
+  |  Added e  ()
+  |
+  o  23:f9869da2286e {foo}
+  |  Added d  ()
+  |
+  o  22:1b88140feefe {foobar}
+  |  Added c  ()
+  |
+  o  21:c39cabfcbbf7 {foobar}
+  |  Added b  ()
+  |
+  o  8:86a186070af2 {foo}
+     Added a  ()
+  
+Amending a topic
+----------------
+
+When the changeset has a topic and we have different active topic
+
+  $ hg topic wat
+  $ hg ci --amend
+  active topic 'wat' grew its first changeset
+  $ hg glog -r .
+  @  29:61470c956807 {wat}
+  |  Added h  ()
+  |
+
+Clear the current topic and amending
+
+  $ hg topic --clear
+  $ hg ci --amend
+  $ hg glog -r .
+  @  31:b584fa49f42e {}
+  |  Added h  ()
+  |
+
+When the changeset does not has a topic but we have an active topic
+
+  $ hg topic watwat
+  marked working directory as topic: watwat
+  $ hg ci --amend
+  active topic 'watwat' grew its first changeset
+  $ hg glog -r .
+  @  33:a24c31c35013 {watwat}
+  |  Added h  ()
+  |
+
+Testing changing topics on public changeset
+-------------------------------------------
+
+  $ hg phase -r 8 -p
+
+Clearing the topic
+
+  $ hg topic -r 8 --clear
+  abort: can't change topic of a public change
+  [255]
+
+Changing the topic
+
+  $ hg topic -r 8 foobarboo
+  abort: can't change topic of a public change
+  [255]
+
+Testing the bookmark movement
+-----------------------------
+
+  $ hg bookmark book
+  $ hg glog
+  @  33:a24c31c35013 {watwat}
+  |  Added h  (book)
+  |
+  o  26:7c76c271395f {bar}
+  |  Added g  ()
+  |
+  o  25:7f26084dfaf1 {bar}
+  |  Added f  ()
+  |
+  o  24:b1f05e9ba0b5 {bar}
+  |  Added e  ()
+  |
+  o  23:f9869da2286e {foo}
+  |  Added d  ()
+  |
+  o  22:1b88140feefe {foobar}
+  |  Added c  ()
+  |
+  o  21:c39cabfcbbf7 {foobar}
+  |  Added b  ()
+  |
+  o  8:86a186070af2 {}
+     Added a  ()
+  
+On clearing the topic
+
+  $ hg topic -r . --clear
+  clearing empty topic "watwat"
+  active topic 'watwat' is now empty
+  changed topic on 1 changes
+
+  $ hg glog
+  @  34:c48d6d71b2d9 {}
+  |  Added h  ()
+  |
+  | x  33:a24c31c35013 {watwat}
+  |/   Added h  (book)
+  |
+  o  26:7c76c271395f {bar}
+  |  Added g  ()
+  |
+  o  25:7f26084dfaf1 {bar}
+  |  Added f  ()
+  |
+  o  24:b1f05e9ba0b5 {bar}
+  |  Added e  ()
+  |
+  o  23:f9869da2286e {foo}
+  |  Added d  ()
+  |
+  o  22:1b88140feefe {foobar}
+  |  Added c  ()
+  |
+  o  21:c39cabfcbbf7 {foobar}
+  |  Added b  ()
+  |
+  o  8:86a186070af2 {}
+     Added a  ()
+  
+
+On changing the topic
+
+  $ hg bookmark bookboo
+  $ hg topic -r . movebook
+  switching to topic movebook
+  changed topic on 1 changes
+  $ hg glog
+  @  35:1b83d11095b9 {movebook}
+  |  Added h  ()
+  |
+  | x  34:c48d6d71b2d9 {}
+  |/   Added h  (bookboo)
+  |
+  | x  33:a24c31c35013 {watwat}
+  |/   Added h  (book)
+  |
+  o  26:7c76c271395f {bar}
+  |  Added g  ()
+  |
+  o  25:7f26084dfaf1 {bar}
+  |  Added f  ()
+  |
+  o  24:b1f05e9ba0b5 {bar}
+  |  Added e  ()
+  |
+  o  23:f9869da2286e {foo}
+  |  Added d  ()
+  |
+  o  22:1b88140feefe {foobar}
+  |  Added c  ()
+  |
+  o  21:c39cabfcbbf7 {foobar}
+  |  Added b  ()
+  |
+  o  8:86a186070af2 {}
+     Added a  ()
+  
--- a/tests/test-topic-dest.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic-dest.t	Fri Oct 20 18:43:55 2017 +0200
@@ -234,12 +234,12 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ hg topic
-     elephant
-   * monkey
+     elephant (1 changesets)
+   * monkey   (2 changesets)
   $ hg ci -m 'merge with default'
   $ hg topic
-     elephant
-   * monkey
+     elephant (1 changesets)
+   * monkey   (3 changesets)
   $ hg log -G
   @    13 (monkey) merge with default
   |\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-topic-mode.t	Fri Oct 20 18:43:55 2017 +0200
@@ -0,0 +1,330 @@
+  $ . "$TESTDIR/testlib/topic_setup.sh"
+
+Testing the config knob to forbid untopiced commit
+======================================================
+
+  $ hg init $TESTTMP/untopic-commit
+  $ cd $TESTTMP/untopic-commit
+  $ cat <<EOF >> .hg/hgrc
+  > [phases]
+  > publish=false
+  > EOF
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > topic-mode = enforce
+  > EOF
+  $ touch a b c d
+  $ hg add a
+  $ hg ci -m "Added a"
+  abort: no active topic
+  (see 'hg help -e topic.topic-mode' for details)
+  [255]
+
+(same test, checking we abort before the editor)
+
+  $ EDITOR=cat hg ci -m "Added a" --edit
+  abort: no active topic
+  (see 'hg help -e topic.topic-mode' for details)
+  [255]
+  $ hg ci -m "added a" --config experimental.topic-mode=ignore
+  $ hg log
+  changeset:   0:a154386e50d1
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added a
+  
+
+Testing the config knob to warn about untopiced commit
+==========================================================
+
+  $ hg init $TESTTMP/untopic-warn-commit
+  $ cd $TESTTMP/untopic-warn-commit
+  $ cat <<EOF >> .hg/hgrc
+  > [phases]
+  > publish=false
+  > EOF
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > topic-mode = warning
+  > EOF
+  $ touch a b c d
+  $ hg add a
+
+(same test, checking we abort before the editor)
+
+  $ HGEDITOR=cat hg ci -m "Added a" --edit
+  warning: new draft commit without topic
+  (see 'hg help -e topic.topic-mode' for details)
+  Added a
+  
+  
+  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: added a
+
+  $ HGEDITOR=cat hg ci --amend -m "Added a" --edit
+  Added a
+  
+  
+  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: added a
+  $ hg ci --amend -m "added a'" --config experimental.topic-mode=ignore
+  $ hg log
+  changeset:   2:2e862d8b5eff
+  tag:         tip
+  parent:      -1:000000000000
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added a'
+  
+
+Testing the config knob to warn about untopiced merge commit
+================================================================
+
+  $ hg init $TESTTMP/test-untopic-merge-commit
+  $ cd $TESTTMP/test-untopic-merge-commit
+  $ cat <<EOF >> .hg/hgrc
+  > [phases]
+  > publish=false
+  > EOF
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > topic-mode = enforce
+  > EOF
+  $ touch ROOT
+  $ hg commit -A -m "ROOT" --config experimental.topic-mode=ignore
+  adding ROOT
+  $ touch a
+  $ hg add a
+  $ hg topic mytopic
+  marked working directory as topic: mytopic
+  $ hg ci -m "Added a"
+  active topic 'mytopic' grew its first changeset
+
+  $ hg up -r "desc('ROOT')"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ touch default
+  $ hg add default
+  $ hg commit -m "default" --config experimental.topic-mode=ignore
+
+  $ hg merge mytopic
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "merge mytopic"
+  warning: new draft commit without topic
+  (see 'hg help -e topic.topic-mode' for details)
+
+  $ hg log -G
+  @    changeset:   3:676a445d1c09
+  |\   tag:         tip
+  | |  parent:      2:a4da109ee59f
+  | |  parent:      1:e5b6c632bd8e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     merge mytopic
+  | |
+  | o  changeset:   2:a4da109ee59f
+  | |  parent:      0:ec1d2790416d
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     default
+  | |
+  o |  changeset:   1:e5b6c632bd8e
+  |/   topic:       mytopic
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     Added a
+  |
+  o  changeset:   0:ec1d2790416d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     ROOT
+  
+
+Testing the config knob to about on untopiced merge commit
+================================================================
+
+  $ hg init $TESTTMP/test-untopic-merge-commit-abort
+  $ cd $TESTTMP/test-untopic-merge-commit-abort
+  $ cat <<EOF >> .hg/hgrc
+  > [phases]
+  > publish=false
+  > EOF
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > topic-mode = enforce-all
+  > EOF
+  $ touch ROOT
+  $ hg commit -A -m "ROOT" --config experimental.topic-mode=ignore
+  adding ROOT
+  $ touch a
+  $ hg add a
+  $ hg topic mytopic
+  marked working directory as topic: mytopic
+  $ hg ci -m "Added a"
+  active topic 'mytopic' grew its first changeset
+
+  $ hg up -r "desc('ROOT')"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ touch default
+  $ hg add default
+  $ hg commit -m "default" --config experimental.topic-mode=ignore
+
+  $ hg merge mytopic
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "merge mytopic"
+  abort: no active topic
+  (see 'hg help -e topic.topic-mode' for details)
+  [255]
+
+  $ hg log -G
+  @  changeset:   2:a4da109ee59f
+  |  tag:         tip
+  |  parent:      0:ec1d2790416d
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     default
+  |
+  | @  changeset:   1:e5b6c632bd8e
+  |/   topic:       mytopic
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     Added a
+  |
+  o  changeset:   0:ec1d2790416d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     ROOT
+  
+Testing the config knob to use a random topic for untopic commit
+====================================================================
+
+  $ hg init $TESTTMP/test-untopic-random
+  $ cd $TESTTMP/test-untopic-random
+  $ cat <<EOF >> .hg/hgrc
+  > [phases]
+  > publish=false
+  > EOF
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > topic-mode = random
+  > EOF
+
+  $ touch ROOT
+  $ hg commit -A -m "ROOT" --config experimental.topic-mode=ignore
+  adding ROOT
+
+  $ touch A
+  $ hg add A
+  $ hg commit -m "Add A" --config devel.randomseed=42
+  active topic 'panoramic-antelope' grew its first changeset
+
+  $ hg up -r "desc(ROOT)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+  $ touch B
+  $ hg add B
+  $ hg commit -m "Add B" --config devel.randomseed=128
+  active topic 'various-dove' grew its first changeset
+
+Test a merge too
+
+  $ hg phase --public -r .
+  active topic 'various-dove' is now empty
+  $ hg up default
+  clearing empty topic "various-dove"
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -G
+  @  changeset:   2:2d2acb6efad5
+  |  tag:         tip
+  |  parent:      0:ec1d2790416d
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     Add B
+  |
+  | o  changeset:   1:d4b548f35972
+  |/   topic:       panoramic-antelope
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     Add A
+  |
+  o  changeset:   0:ec1d2790416d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     ROOT
+  
+  $ hg merge panoramic-antelope
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m 'merge'
+Testing the config knob to use a random topic for untopic commit (even for merge)
+=================================================================================
+
+  $ hg init $TESTTMP/test-untopic-random-all
+  $ cd $TESTTMP/test-untopic-random-all
+  $ cat <<EOF >> .hg/hgrc
+  > [phases]
+  > publish=false
+  > EOF
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > topic-mode = random-all
+  > EOF
+
+  $ touch ROOT
+  $ hg commit -A -m "ROOT" --config experimental.topic-mode=ignore
+  adding ROOT
+
+  $ touch A
+  $ hg add A
+  $ hg commit -m "Add A" --config devel.randomseed=42
+  active topic 'panoramic-antelope' grew its first changeset
+
+  $ hg up -r "desc(ROOT)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+  $ touch B
+  $ hg add B
+  $ hg commit -m "Add B" --config devel.randomseed=128
+  active topic 'various-dove' grew its first changeset
+
+Test a merge too
+
+  $ hg phase --public -r .
+  active topic 'various-dove' is now empty
+  $ hg up default
+  clearing empty topic "various-dove"
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -G
+  @  changeset:   2:2d2acb6efad5
+  |  tag:         tip
+  |  parent:      0:ec1d2790416d
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     Add B
+  |
+  | o  changeset:   1:d4b548f35972
+  |/   topic:       panoramic-antelope
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     Add A
+  |
+  o  changeset:   0:ec1d2790416d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     ROOT
+  
+  $ hg merge panoramic-antelope
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m 'merge'  --config devel.randomseed=1337
+  active topic 'omniscient-locust' grew its first changeset
--- a/tests/test-topic-push.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic-push.t	Fri Oct 20 18:43:55 2017 +0200
@@ -212,8 +212,8 @@
   |/
   o  0 default  public CA
   
-  $ hg strip --hidden --config extensions.strip= --no-backup -r 6: --quiet
-  $ hg strip --hidden --config extensions.strip= -R $TESTTMP/draft --no-backup -r 4: --quiet
+  $ hg strip --config extensions.strip= --no-backup -r 7a9e34dbf547: --quiet
+  $ hg strip --config extensions.strip= -R $TESTTMP/draft --no-backup -r 7a9e34dbf547: --quiet
 
 Pushing a new topic to a publishing server should be seen as a new head
 
--- a/tests/test-topic-shelve.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic-shelve.t	Fri Oct 20 18:43:55 2017 +0200
@@ -15,12 +15,12 @@
   $ hg topic "testing-shelve"
   marked working directory as topic: testing-shelve
   $ hg topic
-   * testing-shelve
+   * testing-shelve (0 changesets)
   $ hg ci -m "First commit" -A
   adding a
   active topic 'testing-shelve' grew its first changeset
   $ hg topic
-   * testing-shelve
+   * testing-shelve (1 changesets)
   $ echo " World" >> a
   $ hg stack
   ### topic: testing-shelve
@@ -34,7 +34,7 @@
   shelved as default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg topic
-   * testing-shelve
+   * testing-shelve (1 changesets)
   $ hg stack
   ### topic: testing-shelve
   ### target: default (branch)
@@ -45,7 +45,7 @@
   $ hg unshelve
   unshelving change 'default'
   $ hg topic
-   * testing-shelve
+   * testing-shelve (1 changesets)
   $ hg stack
   ### topic: testing-shelve
   ### target: default (branch)
--- a/tests/test-topic-stack-data.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic-stack-data.t	Fri Oct 20 18:43:55 2017 +0200
@@ -165,18 +165,18 @@
 basic output
 
   $ hg topic
-     bar
-     baz
-   * foo
-     fuz
+     bar (5 changesets, 1 troubled, 2 heads)
+     baz (2 changesets)
+   * foo (2 changesets)
+     fuz (3 changesets, 2 troubled)
 
 quiet version
 
   $ hg topic --quiet
-  bar
-  baz
-  foo
-  fuz
+  bar (5 changesets, 1 troubled, 2 heads)
+  baz (2 changesets)
+  foo (2 changesets)
+  fuz (3 changesets, 2 troubled)
 
 verbose
 
@@ -192,19 +192,26 @@
   [
    {
     "active": false,
-    "topic": "bar"
+    "changesetcount": 5,
+    "headcount": 2,
+    "topic": "bar",
+    "troubledcount": 1
    },
    {
     "active": false,
+    "changesetcount": 2,
     "topic": "baz"
    },
    {
     "active": true,
+    "changesetcount": 2,
     "topic": "foo"
    },
    {
     "active": false,
-    "topic": "fuz"
+    "changesetcount": 3,
+    "topic": "fuz",
+    "troubledcount": 2
    }
   ]
 
--- a/tests/test-topic-stack.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic-stack.t	Fri Oct 20 18:43:55 2017 +0200
@@ -9,7 +9,7 @@
   > [ui]
   > logtemplate = {rev} {branch} \{{get(namespaces, "topics")}} {phase} {desc|firstline}\n
   > [experimental]
-  > evolution=createmarkers,exchange,allowunstable
+  > evolution=all
   > EOF
 
   $ hg init main
@@ -68,13 +68,13 @@
 After changing the phase of all the changesets in "other" to public, the topic should still be active, but is empty. We should be better at informating the user about it and displaying good data in this case.
 
   $ hg topic
-     foo
-   * other
+     foo   (4 changesets)
+   * other (0 changesets)
   $ hg stack
   ### topic: other
   ### target: default (branch)
   (stack is empty)
-  t0^ c_b (base)
+  t0^ c_b (base current)
 
   $ hg up foo
   switching to topic foo
@@ -86,7 +86,7 @@
 'hg stack' list all changeset in the topic
 
   $ hg topic
-   * foo
+   * foo (4 changesets)
   $ hg stack
   ### topic: foo
   ### target: default (branch)
@@ -208,7 +208,7 @@
 check that topics and stack are available even if ui.strict=true
 
   $ hg topics
-   * foo
+   * foo (4 changesets)
   $ hg stack
   ### topic: foo
   ### target: default (branch)
@@ -218,7 +218,7 @@
   t1: c_c
   t0^ c_b (base)
   $ hg topics --config ui.strict=true
-   * foo
+   * foo (4 changesets)
   $ hg stack --config ui.strict=true
   ### topic: foo
   ### target: default (branch)
@@ -234,7 +234,7 @@
   $ hg stack
   ### target: default (branch)
   (stack is empty)
-  b0^ c_f (base)
+  b0^ c_f (base current)
 
 Test "t#" reference
 -------------------
@@ -426,7 +426,7 @@
   ### target: default (branch)
   t6$ c_f (unstable)
   t5$ c_e (unstable)
-  t2^ c_D (base)
+  t2^ c_D (base current)
   t4: c_h
   t3: c_g
   t2@ c_D (current)
@@ -718,7 +718,7 @@
   t2$ c_G (unstable)
     ^ c_F
   t1$ c_D (current unstable)
-  t0^ c_C (base)
+  t0^ c_C (base unstable)
 
 more obsolescence
 
@@ -792,4 +792,126 @@
   t2$ c_G (unstable)
     ^ c_F
   t1$ c_D (current unstable)
-  t0^ c_C (base)
+  t0^ c_C (base unstable)
+
+Test stack behavior with a split
+--------------------------------
+
+get things linear again
+
+  $ hg rebase -r t1 -d default
+  rebasing 16:1d84ec948370 "c_D" (tip)
+  switching to topic blue
+  $ hg rebase -r t2 -d t1
+  rebasing 13:3ab2eedae500 "c_G"
+  $ hg rebase -r t3 -d t2
+  rebasing 8:3bfe800e0486 "c_I"
+  $ hg stack
+  ### topic: blue
+  ### target: default (branch)
+  t3: c_I
+  t2: c_G
+  t1@ c_D (current)
+  t0^ c_A (base)
+
+making a split
+(first get something to split)
+
+  $ hg up t2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg status --change .
+  A ggg
+  $ echo zzz > Z
+  $ hg add Z
+  $ hg commit --amend
+  $ hg status --change .
+  A Z
+  A ggg
+  $ hg stack
+  ### topic: blue
+  ### target: default (branch)
+  t3$ c_I (unstable)
+  t2@ c_G (current)
+  t1: c_D
+  t0^ c_A (base)
+  $ hg --config extensions.evolve=  --config ui.interactive=yes split --date '0 0' << EOF
+  > y
+  > y
+  > n
+  > y
+  > EOF
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  adding Z
+  adding ggg
+  diff --git a/Z b/Z
+  new file mode 100644
+  examine changes to 'Z'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +zzz
+  record change 1/2 to 'Z'? [Ynesfdaq?] y
+  
+  diff --git a/ggg b/ggg
+  new file mode 100644
+  examine changes to 'ggg'? [Ynesfdaq?] n
+  
+  Done splitting? [yN] y
+
+  $ hg --config extensions.evolve= obslog --all
+  o  dde94df880e9 (22) c_G
+  |
+  | @  e7ea874afbd5 (23) c_G
+  |/
+  x  b24bab30ac12 (21) c_G
+  |    rewritten(parent, content) as dde94df880e9, e7ea874afbd5 by test (*) (glob)
+  |
+  x  907f7d3c2333 (18) c_G
+  |    rewritten as b24bab30ac12 by test (*) (glob)
+  |
+  x  3ab2eedae500 (13) c_G
+  |    rewritten as 907f7d3c2333 by test (*) (glob)
+  |
+  x  c7d60a180d05 (6) c_G
+       rewritten as 3ab2eedae500 by test (*) (glob)
+  
+  $ hg export .
+  # HG changeset patch
+  # User test3
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID e7ea874afbd5c17aeee366d39a828dbcb01682ce
+  # Parent  dde94df880e97f4a1ee8c5408254b429b3d90204
+  # EXP-Topic blue
+  c_G
+  
+  diff -r dde94df880e9 -r e7ea874afbd5 ggg
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/ggg	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +ggg
+  $ hg export .^
+  # HG changeset patch
+  # User test3
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID dde94df880e97f4a1ee8c5408254b429b3d90204
+  # Parent  f3328cd199dc389b850ca952f65a15a8e6dbc79b
+  # EXP-Topic blue
+  c_G
+  
+  diff -r f3328cd199dc -r dde94df880e9 Z
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/Z	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +zzz
+
+Check that stack ouput still make sense
+
+  $ hg stack
+  ### topic: blue
+  ### target: default (branch)
+  t4$ c_I (unstable)
+  t3@ c_G (current)
+  t2: c_G
+  t1: c_D
+  t0^ c_A (base)
--- a/tests/test-topic-tutorial.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic-tutorial.t	Fri Oct 20 18:43:55 2017 +0200
@@ -101,7 +101,7 @@
 changeset yet:
 
   $ hg topics
-   * food
+   * food (0 changesets)
 
   $ hg summary
   parent: 0:38da43f0a2ea tip
@@ -259,7 +259,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg topics
-     food
+     food (2 changesets)
 
 Note that ``default`` (name of the branch) now refers to the tipmost
 changeset of default without a topic:
@@ -336,7 +336,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg topics
-   * food
+   * food (2 changesets)
 
 Updating to any changeset that is part of a topic activates the topic
 regardless of how the revision was specified:
@@ -349,7 +349,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg topics
-   * food
+   * food (2 changesets)
 
 .. Server side activity:
 
@@ -575,7 +575,7 @@
 The topic information will disappear when we publish the changesets:
 
   $ hg topics
-   * food
+   * food (2 changesets)
 
   $ hg push
   pushing to $TESTTMP/server (glob)
@@ -588,7 +588,7 @@
   active topic 'food' is now empty
 
   $ hg topics
-   * food
+   * food (0 changesets)
 
 The topic still exists, and any new commit will be in the topic. But
 note that it is now devoid of any commit.
@@ -597,7 +597,7 @@
   ### topic: food
   ### target: default (branch)
   (stack is empty)
-  t0^ adding fruits (base)
+  t0^ adding fruits (base current)
 
   $ hg log --graph
   @  changeset:   5:2d50db8b5b4c
@@ -703,7 +703,7 @@
 
   $ cat << EOF >> .hg/hgrc
   > [experimental]
-  > enforce-topic = yes
+  > topic-mode = enforce
   > EOF
 
 You can also use `hg config --edit` to update your mercurial configuration.
@@ -714,7 +714,7 @@
   $ echo sickle >> shopping
   $ hg commit -m 'Adding sickle'
   abort: no active topic
-  (set a current topic or use '--config experimental.enforce-topic=no' to commit without a topic)
+  (see 'hg help -e topic.topic-mode' for details)
   [255]
 
 Ok, let's clean this up and delve into multiple topics.
@@ -764,8 +764,8 @@
 We now have two topics:
 
   $ hg topics
-   * drinks
-     tools
+   * drinks (2 changesets)
+     tools  (3 changesets)
 
 The information displayed by ``hg stack`` adapts to the active topic:
 
--- a/tests/test-topic.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-topic.t	Fri Oct 20 18:43:55 2017 +0200
@@ -1,6 +1,6 @@
   $ . "$TESTDIR/testlib/topic_setup.sh"
 
-  $ hg init pinky --traceback
+  $ hg init pinky
   $ cd pinky
   $ cat <<EOF >> .hg/hgrc
   > [phases]
@@ -132,20 +132,20 @@
   [255]
   $ hg revert alpha
   $ hg topic
-   * topicflag
+   * topicflag (0 changesets)
 
 Make a topic
 
   $ hg topic narf
   $ hg topics
-   * narf
+   * narf (0 changesets)
   $ hg topics -v
    * narf (on branch: default, 0 changesets)
   $ hg stack
   ### topic: narf
   ### target: default (branch)
   (stack is empty)
-  t0^ Add file delta (base)
+  t0^ Add file delta (base current)
 
 Add commits to topic
 
@@ -157,8 +157,8 @@
   $ hg topic fran
   marked working directory as topic: fran
   $ hg topics
-   * fran
-     narf
+   * fran (0 changesets)
+     narf (1 changesets)
   $ hg topics --current
   fran
   $ echo >> fran work >> beta
@@ -168,8 +168,8 @@
   switching to topic narf
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg topic
-     fran
-   * narf
+     fran (1 changesets)
+   * narf (1 changesets)
   $ hg log -r . -T '{topics}\n'
   narf
   $ echo 'narf!!!' >> alpha
@@ -373,7 +373,7 @@
   |
 
   $ hg topics
-   * query
+   * query (1 changesets)
   $ cd ../pinky
   $ hg co query
   switching to topic query
@@ -392,9 +392,9 @@
   $ hg topic narf
   $ hg ci -m 'Finish narf'
   $ hg topics
-     fran
-   * narf
-     query
+     fran  (1 changesets)
+   * narf  (2 changesets)
+     query (2 changesets)
   $ hg debugnamecomplete # branch:topic here is a buggy side effect
   default
   default:fran
@@ -411,8 +411,8 @@
 narf commits public:
 
   $ hg topics
-     fran
-   * narf
+     fran (1 changesets)
+   * narf (0 changesets)
   $ hg log -Gl 6
   @    changeset:   9:ae074045b7a7
   |\   tag:         tip
@@ -454,7 +454,7 @@
 
   $ cd ../brain
   $ hg topics
-   * query
+   * query (1 changesets)
   $ hg pull ../pinky -r narf
   pulling from ../pinky
   abort: unknown revision 'narf'!
@@ -469,7 +469,7 @@
   active topic 'query' is now empty
   (run 'hg update' to get a working copy)
   $ hg topics
-   * query
+   * query (0 changesets)
 
 We can pull in the draft-phase change and we get the new topic
 
@@ -482,8 +482,8 @@
   added 1 changesets with 1 changes to 1 files (+1 heads)
   (run 'hg heads' to see heads)
   $ hg topics
-     fran
-   * query
+     fran  (1 changesets)
+   * query (0 changesets)
   $ hg log -Gr 'draft()'
   o  changeset:   9:0469d521db49
   |  tag:         tip
@@ -500,11 +500,7 @@
   $ hg topics --clear
   clearing empty topic "query"
   $ hg topics
-     fran
-
---clear when we don't have an active topic isn't an error:
-
-  $ hg topics --clear
+     fran (1 changesets)
 
 Topic revset
   $ hg log -r 'topic()' -G
@@ -591,7 +587,7 @@
 
 Match current topic:
   $ hg topic
-     fran
+     fran (1 changesets)
   $ hg log -r 'topic(.)'
 (no output is expected)
   $ hg co fran
@@ -609,7 +605,7 @@
 
 Deactivate the topic.
   $ hg topics
-   * fran
+   * fran (1 changesets)
   $ hg topics --clear
   $ echo fran? >> beta
   $ hg ci -m 'fran?'
@@ -628,281 +624,36 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     start on fran
   |
+
   $ hg topics
-     fran
-Changing topic fails if we don't give a topic
-  $ hg topic --rev 9
-  abort: changing topic requires a topic name or --clear
-  [255]
-
-Can't change topic of a public change
-  $ hg topic --rev 1:: --clear
-  abort: can't change topic of a public change
-  [255]
-
-Can clear topics
-  $ hg topic --rev 9 --clear
-  changed topic on 1 changes
-  $ hg log -Gr 'draft() and not obsolete()'
-  o  changeset:   11:0beca5ab56c3
-  |  tag:         tip
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-  | @  changeset:   10:4073470c35e1
-  | |  user:        test
-  | |  date:        Thu Jan 01 00:00:00 1970 +0000
-  | |  summary:     fran?
-  | |
-
-Normally you'd do this with evolve, but we'll use rebase to avoid
-bonus deps in the testsuite.
-
-  $ hg rebase -d tip -s .
-  rebasing 10:4073470c35e1 "fran?"
-
-Can add a topic to an existing change
-  $ hg topic
-  $ hg sum
-  parent: 12:18b70b8de1f0 tip
-   fran?
-  branch: default
-  commit: (clean)
-  update: 5 new changesets, 2 branch heads (merge)
-  phases: 2 draft
-  $ hg topic --rev 11 wat
-  changed topic on 1 changes
-  $ hg log -r .
-  changeset:   12:18b70b8de1f0
-  user:        test
-  date:        Thu Jan 01 00:00:00 1970 +0000
-  summary:     fran?
-  
-  $ hg sum
-  parent: 12:18b70b8de1f0 
-   fran?
-  branch: default
-  commit: (clean)
-  update: 5 new changesets, 2 branch heads (merge)
-  phases: 3 draft
-  unstable: 1 changesets
-  $ hg topic
-     wat
-  $ hg log -Gr 'draft() and not obsolete()'
-  o  changeset:   13:686a642006db
-  |  tag:         tip
-  |  topic:       wat
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-  | @  changeset:   12:18b70b8de1f0
-  | |  user:        test
-  | |  date:        Thu Jan 01 00:00:00 1970 +0000
-  | |  summary:     fran?
-  | |
-
-Normally you'd do this with evolve, but we'll use rebase to avoid
-bonus deps in the testsuite.
-
-  $ hg topic
-     wat
-  $ hg rebase -d tip -s .
-  rebasing 12:18b70b8de1f0 "fran?"
-  switching to topic wat
-  $ hg topic
-     wat
-
-  $ hg log -Gr 'draft()'
-  @  changeset:   14:45358f7a5892
-  |  tag:         tip
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     fran?
-  |
-  o  changeset:   13:686a642006db
-  |  topic:       wat
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-
-Amend a topic
-
-  $ hg topic watwat
-  marked working directory as topic: watwat
-  $ hg ci --amend
-  active topic 'watwat' grew its first changeset
-  $ hg log -Gr 'draft()'
-  @  changeset:   16:6c40a4c21bbe
-  |  tag:         tip
-  |  topic:       watwat
-  |  parent:      13:686a642006db
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     fran?
-  |
-  o  changeset:   13:686a642006db
-  |  topic:       wat
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-
-Clear and amend:
-
-  $ hg topic --clear
-  $ hg ci --amend
-  $ hg log -r .
-  changeset:   18:0f9cd5070654
-  tag:         tip
-  parent:      13:686a642006db
-  user:        test
-  date:        Thu Jan 01 00:00:00 1970 +0000
-  summary:     fran?
-  
-Reading the same topic with topic --rev should work:
-  $ hg topic --rev . watwat
-  switching to topic watwat
-  changed topic on 1 changes
-
-Testing issue5441
-  $ hg co 19
-  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg log -Gr 'draft()'
-  @  changeset:   19:980a0f608481
-  |  tag:         tip
-  |  topic:       watwat
-  |  parent:      13:686a642006db
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     fran?
-  |
-  o  changeset:   13:686a642006db
-  |  topic:       wat
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-
-Using the current flag
-
-  $ hg topic changewat
-  $ hg topics --rev '13::19' --current
-  active topic 'changewat' grew its 2 first changesets
-  changed topic on 2 changes
-
-  $ hg log -Gr 'draft()'
-  @  changeset:   21:56c83be6105f
-  |  tag:         tip
-  |  topic:       changewat
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     fran?
-  |
-  o  changeset:   20:ceba5be9d56f
-  |  topic:       changewat
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-
-Case with branching:
-
-  $ hg up changewat
-  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg up t1
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ echo gamma >> gamma
-  $ hg ci -m gamma
-
-  $ hg log -Gr 'draft()'
-  @  changeset:   22:0d3d805542b4
-  |  tag:         tip
-  |  topic:       changewat
-  |  parent:      20:ceba5be9d56f
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     gamma
-  |
-  | o  changeset:   21:56c83be6105f
-  |/   topic:       changewat
-  |    user:        test
-  |    date:        Thu Jan 01 00:00:00 1970 +0000
-  |    summary:     fran?
-  |
-  o  changeset:   20:ceba5be9d56f
-  |  topic:       changewat
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
-
-  $ hg topics --rev 't1::' changewut
-  switching to topic changewut
-  active topic 'changewat' is now empty
-  changed topic on 3 changes
-
-  $ hg log -Gr 'draft()'
-  @  changeset:   25:729ed5717393
-  |  tag:         tip
-  |  topic:       changewut
-  |  parent:      23:62e49f09f883
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     gamma
-  |
-  | o  changeset:   24:369c6e2e5474
-  |/   topic:       changewut
-  |    user:        test
-  |    date:        Thu Jan 01 00:00:00 1970 +0000
-  |    summary:     fran?
-  |
-  o  changeset:   23:62e49f09f883
-  |  topic:       changewut
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
+     fran (1 changesets)
 
 Testing for updating to t0
 ==========================
 
+  $ hg up fran
+  switching to topic fran
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg stack
-  ### topic: changewut (2 heads)
-  ### target: default (branch), 5 behind
-  t3: fran?
-  t1^ start on fran (base)
-  t2@ gamma (current)
-  t1: start on fran
+  ### topic: fran
+  ### target: default (branch), ambigious rebase destination - branch 'default' has 2 heads
+  t1@ start on fran (current)
   t0^ Add file delta (base)
 
   $ hg up t0
-  preserving the current topic 'changewut'
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  preserving the current topic 'fran'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg topic
-   * changewut
+   * fran (1 changesets)
   $ hg stack
-  ### topic: changewut (2 heads)
-  ### target: default (branch), 5 behind
-  t3: fran?
-  t1^ start on fran (base)
-  t2: gamma
+  ### topic: fran
+  ### target: default (branch), ambigious rebase destination - branch 'default' has 2 heads
   t1: start on fran
-  t0^ Add file delta (base)
+  t0^ Add file delta (base current)
 
   $ hg topics --age
-   * changewut (* by test) (glob)
+   * fran (* by test) (glob)
 
   $ cd ..
 
@@ -917,22 +668,22 @@
   > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
-  > enforce-topic = yes
+  > topic-mode = enforce
   > EOF
   $ touch a b c d
   $ hg add a
   $ hg ci -m "Added a"
   abort: no active topic
-  (set a current topic or use '--config experimental.enforce-topic=no' to commit without a topic)
+  (see 'hg help -e topic.topic-mode' for details)
   [255]
 
 (same test, checking we abort before the editor)
 
   $ EDITOR=cat hg ci -m "Added a" --edit
   abort: no active topic
-  (set a current topic or use '--config experimental.enforce-topic=no' to commit without a topic)
+  (see 'hg help -e topic.topic-mode' for details)
   [255]
-  $ hg ci -m "added a" --config experimental.enforce-topic=no
+  $ hg ci -m "added a" --config experimental.topic-mode=off
   $ hg log
   changeset:   0:a154386e50d1
   tag:         tip
@@ -940,6 +691,7 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     added a
   
+
 Testing the --age flag for `hg topics`
 ======================================
 
@@ -978,12 +730,12 @@
      summary:     added a
   
   $ hg topics
-     topic1970
-     topic1990
-   * topic2010
+     topic1970 (1 changesets)
+     topic1990 (1 changesets)
+   * topic2010 (1 changesets)
 
   $ hg topics --age
-     topic1970 (* second ago by test) (glob)
+     topic1970 (* by test) (glob)
    * topic2010 (* by bar) (glob)
      topic1990 (* by foo) (glob)
 
--- a/tests/test-touch.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-touch.t	Fri Oct 20 18:43:55 2017 +0200
@@ -18,7 +18,7 @@
 Basic usage
 
   $ hg log -G
-  @  0:[0-9a-f]{12} a (re)
+  @  0:e93df3427f45 a
   
   $ hg touch .
   $ hg log -G
@@ -50,18 +50,16 @@
   
   o  3:[0-9a-f]{12} ab (re)
   
-  $ hg prune 4
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  working directory now at 000000000000
+  $ hg prune 3
   1 changesets pruned
 
 Duplicate
 
   $ hg touch --duplicate .
   $ hg log -G
-  @  5:[0-9a-f]{12} (re)
+  @  5:[0-9a-f]{12} a (re)
   
-  o  3:[0-9a-f]{12} ab (re)
+  o  4:[0-9a-f]{12} a (re)
   
 
 Multiple touch
@@ -77,19 +75,19 @@
   |
   o  6:[0-9a-f]{12} c (re)
   |
-  o  5:[0-9a-f]{12} (re)
+  o  5:[0-9a-f]{12} a (re)
   
-  o  3:[0-9a-f]{12} ab (re)
+  o  4:[0-9a-f]{12} a (re)
   
-  $ hg touch .^:.
+  $ 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} (re)
+  o  5:[0-9a-f]{12} a (re)
   
-  o  3:[0-9a-f]{12} ab (re)
+  o  4:[0-9a-f]{12} a (re)
   
 
 check move data kept after rebase on touch:
@@ -109,36 +107,8 @@
   $ hg touch
   1 new unstable changesets
 
-  $ hg log -G --hidden
-  | o  10:[0-9a-f]{12} move (re)
-  |
-  | x  9:[0-9a-f]{12} gna1 (re)
-  | |
-  | x  6:[0-9a-f]{12} d (re)
-  |/
-  | x  5:[0-9a-f]{12} c (re)
-  |
-  o  8:[0-9a-f]{12} c (re)
-  |
-  | x  7:[0-9a-f]{12} d (re)
-  | |
-  | x  6:[0-9a-f]{12} c (re)
-  |/
-  o  5:[0-9a-f]{12} (re)
-  
-  x  4:[0-9a-f]{12} a (re)
-  
-  o  3:[0-9a-f]{12} ab (re)
-  
-  x  2:[0-9a-f]{12} temporary amend commit for [0-9a-f]{12} (re)
-  |
-  x  1:[0-9a-f]{12} a (re)
-  
-  x  0:[0-9a-f]{12} a (re)
-  
-
   $ hg rebase -s 11 -d 12
-  rebasing 11:[0-9a-f]{12} "move" (re)
+  rebasing 11:* "move" (glob)
   $ hg st -C --change=tip
   A gna2
     gna1
--- a/tests/test-tutorial.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-tutorial.t	Fri Oct 20 18:43:55 2017 +0200
@@ -1800,11 +1800,11 @@
       }
 #endif
 
-  $ hg log -r "unstable()"
+  $ hg log -r "orphan()"
   99f039c5ec9e (draft): SPAM SPAM SPAM
 
 #if docgraph-ext
-  $ hg docgraph -r "unstable()" --sphinx-directive --rankdir LR #rest-ignore
+  $ hg docgraph -r "orphan()" --sphinx-directive --rankdir LR #rest-ignore
   .. graphviz::
   
       strict digraph  {
--- a/tests/test-userguide.t	Wed Sep 27 01:18:39 2017 +0200
+++ b/tests/test-userguide.t	Fri Oct 20 18:43:55 2017 +0200
@@ -71,7 +71,7 @@
   1 changesets pruned
   $ hg parents --template '{rev}:{node|short}  {desc|firstline}\n'
   3:934359450037  implement feature Y
-  $ hg --hidden shortlog -G -r 3:
+  $ hg --hidden shortlog -G -r 934359450037:
   x  4:a3e0ef24aaf0  draft  debug hack
   |
   @  3:934359450037  draft  implement feature Y
@@ -85,7 +85,7 @@
   $ hg uncommit file2.c
   $ hg status
   M file2.c
-  $ hg --hidden shortlog -G -r 'descendants(3) - 4'
+  $ hg --hidden shortlog -G -r 'descendants(934359450037) - a3e0ef24aaf0'
   @  6:c8defeecf7a4  draft  fix bug 234
   |
   | x  5:da4331967f5f  draft  fix bug 234
@@ -105,14 +105,14 @@
   $ 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::
+  $ hg log --template '{rev}:{node|short}  {desc|firstline}\n' -r 05e61aab8294::
   7:05e61aab8294  step 1
   8:be6d5bc8e4cc  step 2
   9:35f432d9f7c1  step 3
-  $ hg fold -d '0 0' -m 'fix bug 64' --from -r 7::
+  $ hg fold -d '0 0' -m 'fix bug 64' --from -r 05e61aab8294::
   3 changesets folded
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg --hidden shortlog -G -r 6::
+  $ hg --hidden shortlog -G -r c8defeecf7a4::
   @  10:171c6a79a27b  draft  fix bug 64
   |
   | x  9:35f432d9f7c1  draft  step 3
@@ -124,13 +124,13 @@
   o  6:c8defeecf7a4  draft  fix bug 234
   |
   ~
-  $ hg --hidden log -q -r 'successors(7) | successors(8) | successors(9)'
+  $ hg --hidden log -q -r 'successors(05e61aab8294) | successors(be6d5bc8e4cc) | successors(35f432d9f7c1)'
   10:171c6a79a27b
-  $ hg --hidden log -q -r 'precursors(10)'
+  $ hg --hidden log -q -r 'precursors(171c6a79a27b)'
   7:05e61aab8294
   8:be6d5bc8e4cc
   9:35f432d9f7c1
-  $ hg diff -c 10 -U 0
+  $ hg diff -c 171c6a79a27b -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
@@ -150,7 +150,7 @@
   $ 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::
+  $ hg --hidden shortlog -G -r 171c6a79a27b::
   @  13:dadcbba2d606  draft  feature 23
   |
   o  12:debd46bb29dc  draft  cleanup
@@ -162,16 +162,16 @@
   ~
 
 example 7: amend an older changeset (figures 6, 7)
-  $ hg update -q 11
+  $ hg update -q -r 3e1cb8f70c02
   $ 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()'
+  $ hg shortlog -r "orphan()"
   12:debd46bb29dc  draft  cleanup
   13:dadcbba2d606  draft  feature 23
-  $ hg --hidden shortlog -G -r 10::
+  $ hg --hidden shortlog -G -r 171c6a79a27b::
   @  15:395cbeda3a06  draft  fix bug 17
   |
   | x  14:f7fab707e247  draft  temporary amend commit for 3e1cb8f70c02
@@ -186,7 +186,7 @@
   |
   ~
   $ hg evolve -q --all
-  $ hg shortlog -G -r 10::
+  $ hg shortlog -G -r 171c6a79a27b::
   @  17:91b4b0f8b5c5  draft  feature 23
   |
   o  16:fe8858bd9bc2  draft  cleanup
@@ -204,7 +204,7 @@
   $ 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::
+  $ hg shortlog -G -r 91b4b0f8b5c5::
   @  20:ea8fafca914b  draft  more work
   |
   o  19:b23d06b457a8  draft  debug hack
@@ -216,19 +216,17 @@
   ~
 
 example 8: prune an older changeset (figures 8, 9)
-  $ hg prune 19
+  $ hg prune b23d06b457a8
   1 changesets pruned
   1 new unstable changesets
-  $ hg --hidden shortlog -G -r 18::
+  $ hg --hidden shortlog -G -r b23d06b457a8::
   @  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::
+  $ hg --hidden shortlog -G -r 1f33e68b18b9::
   @  21:4393e5877437  draft  more work
   |
   | x  20:ea8fafca914b  draft  more work
@@ -246,9 +244,9 @@
   $ 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
+  $ hg update -r f84357446753
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg shortlog -G -r 21::
+  $ hg shortlog -G -r 4393e5877437::
   o  23:4db2428c8ae3  draft  fix bug 67
   |
   @  22:f84357446753  draft  fix bug 53
@@ -265,7 +263,7 @@
   move:[23] fix bug 67
   atop:[24] fix bug 53
   working directory is now at 0d972d6888e6
-  $ hg --hidden shortlog -G -r 21::
+  $ hg --hidden shortlog -G -r 4393e5877437::
   @  25:0d972d6888e6  draft  fix bug 67
   |
   o  24:71bb83d674c5  draft  fix bug 53
@@ -286,9 +284,9 @@
   $ 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
+  $ hg update 5b31a1239ab9
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg --hidden shortlog -G -r 25::
+  $ hg --hidden shortlog -G -r 0d972d6888e6::
   o  27:fbb3c6d50427  draft  new feature
   |
   @  26:5b31a1239ab9  draft  fix a bug