cmdstate: introduce a "saver" contextmanager and use it in place of save()
Previously, the state was only saved in some paths out of these functions. This
can be problematic, if the user ctrl-c's (or `kill -9`'s) the process, or we
exit out of `relocate` for anything besides the "expected" reason, we won't
record that we were in the middle of an evolve.
One of our users has discovered that this leaves hg in a weird state; the user
did something like this:
```
$ hg evolve
<something goes wrong with the merge tool, hits ctrl-c>
<deals with the merge conflicts>
$ hg evolve --continue
abort: no interrupted evolve to continue
$ hg evolve
abort: uncommitted changes
# Note: commands.status.verbose=True is set.
$ hg status
M foo
# The repository is in an unfinished *update* state.
# No unresolved merge conflicts
# To continue: hg update
```
The user did an `hg update`, but it didn't actually do anything besides take it
out of the unfinished update state (the files were still dirty in the working
directory).
============================
Testing extensions isolation
============================
In this test case, we check that a repository using the extensions can co-exist
with a repository not using the extension.
$ . $TESTDIR/testlib/common.sh
Setup
=====
Create repo
$ hg init repo-evo
$ cat > repo-evo/.hg/hgrc << EOF
> [extensions]
> evolve=
> EOF
$ hg init repo-topic
$ cat > repo-topic/.hg/hgrc << EOF
> [extensions]
> topic=
> EOF
$ hg init repo-both
$ cat > repo-both/.hg/hgrc << EOF
> [extensions]
> evolve=
> topic=
> EOF
$ hg init repo-no-ext
check setup
$ hg -R repo-evo help -e evolve | head -n 1
warning: --repository ignored
evolve extension - extends Mercurial feature related to Changeset Evolution
$ hg -R repo-both help -e evolve | head -n 1
warning: --repository ignored
evolve extension - extends Mercurial feature related to Changeset Evolution
$ hg -R repo-no-ext help -e evolve
warning: --repository ignored
abort: no such help topic: evolve
(try 'hg help --keyword evolve')
[255]
$ hg -R repo-no-ext help -e topic
warning: --repository ignored
abort: no such help topic: topic
(try 'hg help --keyword topic')
[255]
start hgweb dir for all repo
$ cat > hgweb.conf << EOF
> [paths]
> / = *
> EOF
$ hg serve -p $HGPORT -d --pid-file=hg.pid --web-conf hgweb.conf -A access.log -E error.log
$ cat hg.pid >> $DAEMON_PIDS
Test isolation
--------------
As of 4.9 (and previous version). It seems like extensions are displayed as
enabled even for repository where they are not supposed to be. See the output
tagged `no-false`.
(however, topic and evolve are not supposed to affect other repository as shown
in the rest of this test).
$ get-with-headers.py $LOCALIP:$HGPORT 'repo-no-ext/help/extensions' | grep 'enabled extensions' -A 7
[1]
$ get-with-headers.py $LOCALIP:$HGPORT 'repo-evo/help/extensions' | grep 'enabled extensions' -A 7
enabled extensions:
</p>
<dl>
<dt>evolve
<dd>extends Mercurial feature related to Changeset Evolution
</dl>
<p>
disabled extensions:
$ get-with-headers.py $LOCALIP:$HGPORT 'repo-topic/help/extensions' | grep 'enabled extensions' -A 7
enabled extensions:
</p>
<dl>
<dt>evolve (no-false !)
<dd>extends Mercurial feature related to Changeset Evolution (no-false !)
<dt>topic
<dd>support for topic branches
</dl>
$ get-with-headers.py $LOCALIP:$HGPORT 'repo-both/help/extensions' | grep 'enabled extensions' -A 9
enabled extensions:
</p>
<dl>
<dt>evolve
<dd>extends Mercurial feature related to Changeset Evolution
<dt>topic
<dd>support for topic branches
</dl>
<p>
disabled extensions:
$ get-with-headers.py $LOCALIP:$HGPORT 'repo-no-ext/help/extensions' | grep 'enabled extensions' -A 9
enabled extensions: (no-false !)
</p> (no-false !)
<dl> (no-false !)
<dt>evolve (no-false !)
<dd>extends Mercurial feature related to Changeset Evolution (no-false !)
<dt>topic (no-false !)
<dd>support for topic branches (no-false !)
</dl> (no-false !)
<p> (no-false !)
disabled extensions: (no-false !)
make sure repos don't affect each other (and check both ways)
Check evolve isolation
-----------------------
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
[1]
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
_evoext_getbundle_obscommon
_evoext_obshashrange_v1
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
[1]
Check topic isolation
---------------------
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
[1]
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | egrep 'topics|evoext'
topics
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
[1]
Check coupled isolation
-----------------------
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
[1]
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-both | egrep 'topics|evoext'
_evoext_getbundle_obscommon
_evoext_obshashrange_v1
topics
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
_evoext_getbundle_obscommon
_evoext_obshashrange_v1
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | egrep 'topics|evoext'
topics
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
_evoext_getbundle_obscommon
_evoext_obshashrange_v1
$ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
[1]
Final cleanup
-------------
$ cat error.log
$ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS