Mercurial > hg
view tests/test-strip.t @ 26623:5a95fe44121d
clonebundles: support for seeding clones from pre-generated bundles
Cloning can be an expensive operation for servers because the server
generates a bundle from existing repository data at request time. For
a large repository like mozilla-central, this consumes 4+ minutes
of CPU time on the server. It also results in significant network
utilization. Multiplied by hundreds or even thousands of clients and
the ensuing load can result in difficulties scaling the Mercurial server.
Despite generation of bundles being deterministic until the next
changeset is added, the generation of bundles to service a clone request
is not cached. Each clone thus performs redundant work. This is
wasteful.
This patch introduces the "clonebundles" extension and related
client-side functionality to help alleviate this deficiency. The
client-side feature is behind an experimental flag and is not enabled by
default.
It works as follows:
1) Server operator generates a bundle and makes it available on a
server (likely HTTP).
2) Server operator defines the URL of a bundle file in a
.hg/clonebundles.manifest file.
3) Client `hg clone`ing sees the server is advertising bundle URLs.
4) Client fetches and applies the advertised bundle.
5) Client performs equivalent of `hg pull` to fetch changes made since
the bundle was created.
Essentially, the server performs the expensive work of generating a
bundle once and all subsequent clones fetch a static file from
somewhere. Scaling static file serving is a much more manageable
problem than scaling a Python application like Mercurial. Assuming your
repository grows less than 1% per day, the end result is 99+% of CPU
and network load from clones is eliminated, allowing Mercurial servers
to scale more easily. Serving static files also means data can be
transferred to clients as fast as they can consume it, rather than as
fast as servers can generate it. This makes clones faster.
Mozilla has implemented similar functionality of this patch on
hg.mozilla.org using a custom extension. We are hosting bundle files in
Amazon S3 and CloudFront (a CDN) and have successfully offloaded
>1 TB/day in data transfer from hg.mozilla.org, freeing up significant
bandwidth and CPU resources. The positive impact has been stellar and
I believe it has proved its value to be included in Mercurial core. I
feel it is important for the client-side support to be enabled in core
by default because it means that clients will get faster, more reliable
clones and will enable server operators to reduce load without
requiring any client-side configuration changes (assuming clients are
up to date, of course).
The scope of this feature is narrowly and specifically tailored to
cloning, despite "serve pulls from pre-generated bundles" being a valid
and useful feature. I would eventually like for Mercurial servers to
support transferring *all* repository data via statically hosted files.
You could imagine a server that siphons all pushed data to bundle files
and instructs clients to apply a stream of bundles to reconstruct all
repository data. This feature, while useful and powerful, is
significantly more work to implement because it requires the server
component have awareness of discovery and a mapping of which changesets
are in which files. Full, clone bundles, by contrast, are much simpler.
The wire protocol command is named "clonebundles" instead of something
more generic like "staticbundles" to leave the door open for a new, more
powerful and more generic server-side component with minimal backwards
compatibility implications. The name "bundleclone" is used by Mozilla's
extension and would cause problems since there are subtle differences
in Mozilla's extension.
Mozilla's experience with this idea has taught us that some form of
"content negotiation" is required. Not all clients will support all
bundle formats or even URLs (advanced TLS requirements, etc). To ensure
the highest uptake possible, a server needs to advertise multiple
versions of bundles and clients need to be able to choose the most
appropriate from that list one. The "attributes" in each
server-advertised entry facilitate this filtering and sorting. Their
use will become apparent in subsequent patches.
Initial inspiration and credit for the idea of cloning from static files
belongs to Augie Fackler and his "lookaside clone" extension proof of
concept.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 09 Oct 2015 11:22:01 -0700 |
parents | 703d331c44ac |
children | 143b52fce68e |
line wrap: on
line source
$ echo "[extensions]" >> $HGRCPATH $ echo "strip=" >> $HGRCPATH $ restore() { > hg unbundle -q .hg/strip-backup/* > rm .hg/strip-backup/* > } $ teststrip() { > hg up -C $1 > echo % before update $1, strip $2 > hg parents > hg --traceback strip $2 > echo % after update $1, strip $2 > hg parents > restore > } $ hg init test $ cd test $ echo foo > bar $ hg ci -Ama adding bar $ echo more >> bar $ hg ci -Amb $ echo blah >> bar $ hg ci -Amc $ hg up 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo blah >> bar $ hg ci -Amd created new head $ echo final >> bar $ hg ci -Ame $ hg log changeset: 4:443431ffac4f tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: e changeset: 3:65bd5f99a4a3 parent: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: d changeset: 2:264128213d29 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: c changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ teststrip 4 4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved % before update 4, strip 4 changeset: 4:443431ffac4f tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: e 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) % after update 4, strip 4 changeset: 3:65bd5f99a4a3 tag: tip parent: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: d $ teststrip 4 3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved % before update 4, strip 3 changeset: 4:443431ffac4f tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: e 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) % after update 4, strip 3 changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b $ teststrip 1 4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved % before update 1, strip 4 changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) % after update 1, strip 4 changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b $ teststrip 4 2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved % before update 4, strip 2 changeset: 4:443431ffac4f tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: e saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) % after update 4, strip 2 changeset: 3:443431ffac4f tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: e $ teststrip 4 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved % before update 4, strip 1 changeset: 4:264128213d29 tag: tip parent: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: c 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) % after update 4, strip 1 changeset: 0:9ab35a2d17cb tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ teststrip null 4 0 files updated, 0 files merged, 1 files removed, 0 files unresolved % before update null, strip 4 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) % after update null, strip 4 $ hg log changeset: 4:264128213d29 tag: tip parent: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: c changeset: 3:443431ffac4f user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: e changeset: 2:65bd5f99a4a3 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: d changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ hg up -C 4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg parents changeset: 4:264128213d29 tag: tip parent: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: c $ hg --traceback strip 4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg (glob) $ hg parents changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b $ hg debugbundle .hg/strip-backup/* 264128213d290d868c54642d13aeaa3675551a78 $ hg pull .hg/strip-backup/* pulling from .hg/strip-backup/264128213d29-0b39d6bf-backup.hg searching for changes adding changesets adding manifests adding file changes added 1 changesets with 0 changes to 0 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) $ rm .hg/strip-backup/* $ hg log --graph o changeset: 4:264128213d29 | tag: tip | parent: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: c | | o changeset: 3:443431ffac4f | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: e | | | o changeset: 2:65bd5f99a4a3 |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: d | @ changeset: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: b | o changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ hg up -C 2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge 4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) before strip of merge parent $ hg parents changeset: 2:65bd5f99a4a3 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: d changeset: 4:264128213d29 tag: tip parent: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: c $ hg strip 4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) after strip of merge parent $ hg parents changeset: 1:ef3a871183d7 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: b $ restore $ hg up 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log -G @ changeset: 4:264128213d29 | tag: tip | parent: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: c | | o changeset: 3:443431ffac4f | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: e | | | o changeset: 2:65bd5f99a4a3 |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: d | o changeset: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: b | o changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a 2 is parent of 3, only one strip should happen $ hg strip "roots(2)" 3 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) $ hg log -G @ changeset: 2:264128213d29 | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: c | o changeset: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: b | o changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ restore $ hg log -G o changeset: 4:443431ffac4f | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: e | o changeset: 3:65bd5f99a4a3 | parent: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: d | | @ changeset: 2:264128213d29 |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: c | o changeset: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: b | o changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a 2 different branches: 2 strips $ hg strip 2 4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) $ hg log -G o changeset: 2:65bd5f99a4a3 | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: d | @ changeset: 1:ef3a871183d7 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: b | o changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ restore 2 different branches and a common ancestor: 1 strip $ hg strip 1 "2|4" 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) $ restore verify fncache is kept up-to-date $ touch a $ hg ci -qAm a $ cat .hg/store/fncache | sort data/a.i data/bar.i $ hg strip tip 0 files updated, 0 files merged, 1 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) $ cat .hg/store/fncache data/bar.i stripping an empty revset $ hg strip "1 and not 1" abort: empty revision set [255] remove branchy history for qimport tests $ hg strip 3 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) strip of applied mq should cleanup status file $ echo "mq=" >> $HGRCPATH $ hg up -C 3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo fooagain >> bar $ hg ci -mf $ hg qimport -r tip:2 applied patches before strip $ hg qapplied 2.diff 3.diff 4.diff stripping revision in queue $ hg strip 3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) applied patches after stripping rev in queue $ hg qapplied 2.diff stripping ancestor of queue $ hg strip 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) applied patches after stripping ancestor of queue $ hg qapplied Verify strip protects against stripping wc parent when there are uncommitted mods $ echo b > b $ echo bb > bar $ hg add b $ hg ci -m 'b' $ hg log --graph @ changeset: 1:76dcf9fab855 | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: b | o changeset: 0:9ab35a2d17cb user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ hg up 0 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ echo c > bar $ hg up -t false merging bar merging bar failed! 1 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges [1] $ hg sum parent: 1:76dcf9fab855 tip b branch: default commit: 1 modified, 1 unknown, 1 unresolved update: (current) phases: 2 draft mq: 3 unapplied $ echo c > b $ hg strip tip abort: local changes found [255] $ hg strip tip --keep saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) $ hg log --graph @ changeset: 0:9ab35a2d17cb tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ hg status M bar ? b ? bar.orig $ rm bar.orig $ hg sum parent: 0:9ab35a2d17cb tip a branch: default commit: 1 modified, 1 unknown update: (current) phases: 1 draft mq: 3 unapplied Strip adds, removes, modifies with --keep $ touch b $ hg add b $ hg commit -mb $ touch c ... with a clean working dir $ hg add c $ hg rm bar $ hg commit -mc $ hg status $ hg strip --keep tip saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob) $ hg status ! bar ? c ... with a dirty working dir $ hg add c $ hg rm bar $ hg commit -mc $ hg status $ echo b > b $ echo d > d $ hg strip --keep tip saved backup bundle to $TESTTMP/test/.hg/strip-backup/57e364c8a475-4cfed93c-backup.hg (glob) $ hg status M b ! bar ? c ? d $ cd .. stripping many nodes on a complex graph (issue3299) $ hg init issue3299 $ cd issue3299 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a' $ hg strip 'not ancestors(x)' saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob) test hg strip -B bookmark $ cd .. $ hg init bookmarks $ cd bookmarks $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b' $ hg bookmark -r 'a' 'todelete' $ hg bookmark -r 'b' 'B' $ hg bookmark -r 'b' 'nostrip' $ hg bookmark -r 'c' 'delete' $ hg up -C todelete 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (activating bookmark todelete) $ hg strip -B nostrip bookmark 'nostrip' deleted abort: empty revision set [255] $ hg strip -B todelete 0 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob) bookmark 'todelete' deleted $ hg id -ir dcbb326fdec2 abort: unknown revision 'dcbb326fdec2'! [255] $ hg id -ir d62d843c9a01 d62d843c9a01 $ hg bookmarks B 9:ff43616e5d0f delete 6:2702dd0c91e7 $ hg strip -B delete saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob) bookmark 'delete' deleted $ hg id -ir 6:2702dd0c91e7 abort: unknown revision '2702dd0c91e7'! [255] $ hg update B 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (activating bookmark B) $ echo a > a $ hg add a $ hg strip -B B abort: local changes found [255] $ hg bookmarks * B 6:ff43616e5d0f Make sure no one adds back a -b option: $ hg strip -b tip hg strip: option -b not recognized hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV... strip changesets and all their descendants from the repository (use "hg help -e strip" to show help for the strip extension) options ([+] can be repeated): -r --rev REV [+] strip specified revision (optional, can specify revisions without this option) -f --force force removal of changesets, discard uncommitted changes (no backup) --no-backup no backups -k --keep do not modify working directory during strip -B --bookmark VALUE remove revs only reachable from given bookmark --mq operate on patch repository (use "hg strip -h" to show more help) [255] $ cd .. Verify bundles don't get overwritten: $ hg init doublebundle $ cd doublebundle $ touch a $ hg commit -Aqm a $ touch b $ hg commit -Aqm b $ hg strip -r 0 0 files updated, 0 files merged, 2 files removed, 0 files unresolved saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg (glob) $ ls .hg/strip-backup 3903775176ed-e68910bd-backup.hg $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg $ hg strip -r 0 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg (glob) $ ls .hg/strip-backup 3903775176ed-54390173-backup.hg 3903775176ed-e68910bd-backup.hg $ cd .. Test that we only bundle the stripped changesets (issue4736) ------------------------------------------------------------ initialization (previous repo is empty anyway) $ hg init issue4736 $ cd issue4736 $ echo a > a $ hg add a $ hg commit -m commitA $ echo b > b $ hg add b $ hg commit -m commitB $ echo c > c $ hg add c $ hg commit -m commitC $ hg up 'desc(commitB)' 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ echo d > d $ hg add d $ hg commit -m commitD created new head $ hg up 'desc(commitC)' 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg merge 'desc(commitD)' 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m 'mergeCD' $ hg log -G @ changeset: 4:d8db9d137221 |\ tag: tip | | parent: 2:5c51d8d6557d | | parent: 3:6625a5168474 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: mergeCD | | | o changeset: 3:6625a5168474 | | parent: 1:eca11cf91c71 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: commitD | | o | changeset: 2:5c51d8d6557d |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: commitC | o changeset: 1:eca11cf91c71 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: commitB | o changeset: 0:105141ef12d0 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: commitA Check bundle behavior: $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg 2 changesets found $ hg log -r 'bundle()' -R ../issue4736.hg changeset: 3:6625a5168474 parent: 1:eca11cf91c71 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: commitD changeset: 4:d8db9d137221 tag: tip parent: 2:5c51d8d6557d parent: 3:6625a5168474 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: mergeCD check strip behavior $ hg --config extensions.strip= strip 'desc(commitD)' --debug resolving manifests branchmerge: False, force: True, partial: False ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71 c: other deleted -> r removing c d: other deleted -> r removing d 0 files updated, 0 files merged, 2 files removed, 0 files unresolved 2 changesets found list of changesets: 6625a516847449b6f0fa3737b9ba56e9f0f3032c d8db9d1372214336d2b5570f20ee468d2c72fa8b saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob) invalid branchheads cache (served): tip differs truncating cache/rbc-revs-v1 to 24 $ hg log -G o changeset: 2:5c51d8d6557d | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: commitC | @ changeset: 1:eca11cf91c71 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: commitB | o changeset: 0:105141ef12d0 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: commitA strip backup content $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg changeset: 3:6625a5168474 parent: 1:eca11cf91c71 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: commitD changeset: 4:d8db9d137221 tag: tip parent: 2:5c51d8d6557d parent: 3:6625a5168474 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: mergeCD Error during post-close callback of the strip transaction (They should be gracefully handled and reported) $ cat > ../crashstrip.py << EOF > from mercurial import error > def reposetup(ui, repo): > class crashstriprepo(repo.__class__): > def transaction(self, desc, *args, **kwargs): > tr = super(crashstriprepo, self).transaction(self, desc, *args, **kwargs) > if desc == 'strip': > def crash(tra): raise error.Abort('boom') > tr.addpostclose('crash', crash) > return tr > repo.__class__ = crashstriprepo > EOF $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg (glob) strip failed, full bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob) abort: boom [255]