Patchwork [5,of,9,V3] tryimportone: use dirstateguard instead of beginparentchange/endparentchange

login
register
mail settings
Submitter Katsunori FUJIWARA
Date May 7, 2015, 3:15 a.m.
Message ID <26d5bc8c6fc244c808e1.1430968552@feefifofum>
Download mbox | patch
Permalink /patch/8938/
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 1430968031 -32400
#      Thu May 07 12:07:11 2015 +0900
# Node ID 26d5bc8c6fc244c808e12e8dab4e78a6e78664f6
# Parent  c5501296931984d29e39afcb40e552a490482eea
tryimportone: use dirstateguard instead of beginparentchange/endparentchange

To fix the issue that recent (in memory) dirstate isn't visible to
external process (e.g. "precommit" hook), subsequent patch makes
"localrepository.commit()" invoke "dirstate.write()" in it.

This change will make "beginparentchange()" and "endparentchange()" on
dirstate in "cmdutil.tryimportone()" meaningless, because:

  - "dirstate.write()" writes changed data into ".hg/dirstate", but

  - aborting between "beginparentchange()" and "endparentchange()"
    doesn't cause any restoring ".hg/dirstate"

    it just discards changes in memory.

This patch uses "dirstateguard" instead of "beginparentchange()" and
"endparentchange()" in "cmdutil.tryimportone()" to restore
".hg/dirstate" at failure even if "dirstate.write()" is executed
before failure.

This patch uses "lockmod.release(dsguard)" instead of
"dsguard.relese()", because processing may be aborted before
assignment to "dsguard" , and "if dsguard" examination for safety is
redundant.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -818,6 +818,7 @@ 
     msg = _('applied to working directory')
 
     rejects = False
+    dsguard = None
 
     try:
         cmdline_message = logmessage(ui, opts)
@@ -859,7 +860,7 @@ 
 
         n = None
         if update:
-            repo.dirstate.beginparentchange()
+            dsguard = dirstateguard(repo, 'tryimportone')
             if p1 != parents[0]:
                 updatefunc(repo, p1.node())
             if p2 != parents[1]:
@@ -899,7 +900,7 @@ 
                 n = repo.commit(message, opts.get('user') or user,
                                 opts.get('date') or date, match=m,
                                 editor=editor, force=partial)
-            repo.dirstate.endparentchange()
+            dsguard.close()
         else:
             if opts.get('exact') or opts.get('import_branch'):
                 branch = branch or 'default'
@@ -937,6 +938,7 @@ 
             msg = _('created %s') % short(n)
         return (msg, n, rejects)
     finally:
+        lockmod.release(dsguard)
         os.unlink(tmpname)
 
 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,