diff mercurial/commands.py @ 15198:62dc0e7ab092

import: wrap a transaction around the whole command Now 'rollback' after 'import' is less surprising: it rolls back all of the imported changesets, not just the last one. As an extra added benefit, you don't need 'rollback -f' after 'import --bypass', which was an undesired side effect of fixing issue2998 (59e8bc22506e).. Note that this is a different take on issue963, which complained that rollback after importing multiple patches returned the working dir parent to the starting point, not to the second-last patch applied. Since we now rollback the entire import, returning the working dir to the starting point is entirely logical. So this change also undoes a732eebf1958, the fix to issue963, and updates its tests accordingly. Bottom line: rollback after import was weird before issue963, understandable since the fix for issue963, and even better now.
author Greg Ward <greg@gerg.ca>
date Sun, 02 Oct 2011 14:34:28 -0400
parents 7f65ce5cc011
children 797bf1dc1ff8
line wrap: on
line diff
--- a/mercurial/commands.py	Sat Oct 01 21:52:44 2011 -0400
+++ b/mercurial/commands.py	Sun Oct 02 14:34:28 2011 -0400
@@ -3263,7 +3263,7 @@
 
     base = opts["base"]
     strip = opts["strip"]
-    wlock = lock = None
+    wlock = lock = tr = None
     msgs = []
 
     def checkexact(repo, n, nodeid):
@@ -3334,9 +3334,6 @@
                                     opts.get('date') or date, match=m,
                                     editor=cmdutil.commiteditor)
                     checkexact(repo, n, nodeid)
-                    # Force a dirstate write so that the next transaction
-                    # backups an up-to-date file.
-                    repo.dirstate.write()
             else:
                 if opts.get('exact') or opts.get('import_branch'):
                     branch = branch or 'default'
@@ -3370,6 +3367,7 @@
     try:
         wlock = repo.wlock()
         lock = repo.lock()
+        tr = repo.transaction('import')
         parents = repo.parents()
         for patchurl in patches:
             if patchurl == '-':
@@ -3395,9 +3393,18 @@
             if not haspatch:
                 raise util.Abort(_('%s: no diffs found') % patchurl)
 
+        tr.close()
         if msgs:
             repo.savecommitmessage('\n* * *\n'.join(msgs))
+    except:
+        # 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:
+        if tr:
+            tr.release()
         release(lock, wlock)
 
 @command('incoming|in',