diff --git a/hgext/transplant.py b/hgext/transplant.py --- a/hgext/transplant.py +++ b/hgext/transplant.py @@ -125,9 +125,10 @@ class transplanter(object): diffopts = patch.difffeatureopts(self.ui, opts) diffopts.git = True - lock = wlock = tr = None + lock = wlock = tr = dsguard = None try: wlock = repo.wlock() + dsguard = cmdutil.dirstateguard(repo, 'transplant') lock = repo.lock() tr = repo.transaction('transplant') for rev in revs: @@ -200,6 +201,7 @@ class transplanter(object): # Do not rollback, it is up to the user to # fix the merge or cancel everything tr.close() + dsguard.close() raise if n and domerge: self.ui.status(_('%s merged at %s\n') % (revstr, @@ -212,6 +214,7 @@ class transplanter(object): if patchfile: os.unlink(patchfile) tr.close() + dsguard.close() if pulls: exchange.pull(repo, source.peer(), heads=pulls) merge.update(repo, pulls[-1], False, False, None) @@ -220,7 +223,10 @@ class transplanter(object): self.transplants.write() if tr: tr.release() - lock.release() + if lock: + lock.release() + if dsguard: + dsguard.release() wlock.release() def filter(self, filter, node, changelog, patchfile): diff --git a/tests/test-transplant.t b/tests/test-transplant.t --- a/tests/test-transplant.t +++ b/tests/test-transplant.t @@ -867,6 +867,7 @@ timestamp of them isn't changed on the f > [hooks] > fakedirstatewritetime = ! > fakepatchtime = ! + > [extensions] > abort = ! > EOF @@ -877,4 +878,41 @@ timestamp of them isn't changed on the f $ hg status -A r1 M r1 +Test that rollback by unexpected failure after transplanting the first +revision restores dirstate correctly. + + $ hg rollback -q + $ rm -f abort + $ hg update -q -C d11e3596cc1a + $ hg parents -T "{node|short}\n" + d11e3596cc1a + $ hg status -A + C r1 + C r2 + + $ cat >> .hg/hgrc < [hooks] + > # emulate failure at transplanting the 2nd revision + > pretxncommit.abort = test ! -f abort + > EOF + $ hg transplant "22c515968f13::" + applying 22c515968f13 + 22c515968f13 transplanted to * (glob) + applying e38700ba9dd3 + transaction abort! + rollback completed + abort: pretxncommit.abort hook exited with status 1 + [255] + $ cat >> .hg/hgrc < [hooks] + > pretxncommit.abort = ! + > EOF + + $ hg parents -T "{node|short}\n" + d11e3596cc1a + $ hg status -A + M r1 + ? abort + C r2 + $ cd ..