tryimportone: use dirstateguard instead of beginparentchange/endparentchange
To fix the issue that the recent (in memory) dirstate isn't visible to
external process (e.g. "precommit" hook), a 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" during a failure even if "dirstate.write()" is executed
before a failure.
This patch uses "lockmod.release(dsguard)" instead of
"dsguard.release()", because processing may be aborted before
assignment to "dsguard" , and the "if dsguard" examination for safety is
redundant.
--- a/mercurial/cmdutil.py Thu May 07 12:07:10 2015 +0900
+++ b/mercurial/cmdutil.py Thu May 07 12:07:11 2015 +0900
@@ -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,