Patchwork [4,of,9,V3] import: use dirstateguard instead of dirstate.invalidate

login
register
mail settings
Submitter Katsunori FUJIWARA
Date May 7, 2015, 3:15 a.m.
Message ID <c5501296931984d29e39.1430968551@feefifofum>
Download mbox | patch
Permalink /patch/8939/
State Accepted
Delegated to: Pierre-Yves David
Headers show

Comments

Katsunori FUJIWARA - May 7, 2015, 3:15 a.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1430968030 -32400
#      Thu May 07 12:07:10 2015 +0900
# Node ID c5501296931984d29e39afcb40e552a490482eea
# Parent  e9ae08dbe0177b828b694a7d6afe9a65a60e981f
import: use dirstateguard instead of dirstate.invalidate

Before this patch, "commands.import()" uses "dirstate.invalidate()" as
a kind of "restore .hg/dirstate to the original status" at failure.

But it just discards changes in memory, and doesn't actually restore
".hg/dirstate". Then, it can't work as expected, if "dirstate.write()"
is executed while processing.

This patch uses "dirstateguard" instead of "dirstate.invalidate()" to
restore ".hg/dirstate" at failure even if "dirstate.write()" is
executed before failure.

This patch also removes "beginparentchage()" and "endparentchange()",
because "dirstateguard" makes them useless, too.

This is a part of preparations to fix the issue that recent (in
memory) dirstate isn't visible to external process (e.g. "precommit"
hook).

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4213,7 +4213,7 @@ 
         cmdutil.bailifchanged(repo)
 
     base = opts["base"]
-    wlock = lock = tr = None
+    wlock = dsguard = lock = tr = None
     msgs = []
     ret = 0
 
@@ -4221,7 +4221,7 @@ 
     try:
         try:
             wlock = repo.wlock()
-            repo.dirstate.beginparentchange()
+            dsguard = cmdutil.dirstateguard(repo, 'import')
             if not opts.get('no_commit'):
                 lock = repo.lock()
                 tr = repo.transaction('import')
@@ -4262,18 +4262,16 @@ 
                 tr.close()
             if msgs:
                 repo.savecommitmessage('\n* * *\n'.join(msgs))
-            repo.dirstate.endparentchange()
+            dsguard.close()
             return ret
-        except: # re-raises
-            # wlock.release() indirectly calls dirstate.write(): since
-            # we're crashing, we do not want to change the working dir
-            # parent after all, so make sure it writes nothing
-            repo.dirstate.invalidate()
-            raise
+        finally:
+            # TODO: get rid of this meaningless try/finally enclosing.
+            # this is kept only to reduce changes in a patch.
+            pass
     finally:
         if tr:
             tr.release()
-        release(lock, wlock)
+        release(lock, dsguard, wlock)
 
 @command('incoming|in',
     [('f', 'force', None,