Patchwork [4,of,4] shelve: use rollback instead of aborting a current transaction for unshelve

mail settings
Submitter Katsunori FUJIWARA
Date Oct. 4, 2015, 12:44 p.m.
Message ID <5e606f7cab085bac88ee.1443962660@feefifofum>
Download mbox | patch
Permalink /patch/10773/
State Changes Requested
Delegated to: Pierre-Yves David
Headers show


Katsunori FUJIWARA - Oct. 4, 2015, 12:44 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <>
# Date 1443962009 -32400
#      Sun Oct 04 21:33:29 2015 +0900
# Node ID 5e606f7cab085bac88ee7a11d0c35155e0a9f9c1
# Parent  e265a8c85c3873815730921ae2d8ca3c6df3b48a
shelve: use rollback instead of aborting a current transaction for unshelve

Before this patch, "hg unshelve" uses aborting a current transaction
to discard temporary changes while unshelving.

This assumes that dirstate changes in a transaction scope are kept
even after aborting it. But this assumption will be broken by
"transactional dirstate". See the wiki page below for detail about it.

This patch uses 'repo.rollback()' instead of aborting current
transaction to remove the temporary revision.

'dirstate.write()' just before closing a transaction will be removed
soon by subsequent patch, which writes or discards in-memory dirstate
changes at releasing transaction according to the result of it.


diff --git a/hgext/ b/hgext/
--- a/hgext/
+++ b/hgext/
@@ -701,13 +701,20 @@ 
         mergefiles(ui, repo, pctx, shelvectx)
-        # The transaction aborting will strip all the commits for us,
-        # but it doesn't update the inmemory structures, so addchangegroup
-        # hooks still fire and try to operate on the missing commits.
-        # Clean up manually to prevent this.
-        repo.unfiltered().changelog.strip(oldtiprev, tr)
+        repo.dirstate.write() # certainly writes all changes while unshelving
+        tr.close()
+        tr.release() # is ensured to run successfully by previous 'close()'
+        tr = None
         unshelvecleanup(ui, repo, basename, opts)
+        # this rollbacking discards changes while unshelving by
+        # restoring from undo files, but keeps dirstate as it is,
+        # because 'hg.update()' in 'mergefiles()' already updates the
+        # working directory to original parent (= not "parent gone")
+        repo.ui.pushbuffer()
+        repo.rollback(force=True)
+        repo.ui.popbuffer()
         ui.quiet = oldquiet
         if tr: