diff --git a/mercurial/commands.py b/mercurial/commands.py
index 7f65ce5cc0112b6ce63392192049bdb1ea186358_bWVyY3VyaWFsL2NvbW1hbmRzLnB5..62dc0e7ab092e10cb8dee3eac16108073dd71cea_bWVyY3VyaWFsL2NvbW1hbmRzLnB5 100644
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -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,5 +3393,6 @@
             if not haspatch:
                 raise util.Abort(_('%s: no diffs found') % patchurl)
 
+        tr.close()
         if msgs:
             repo.savecommitmessage('\n* * *\n'.join(msgs))
@@ -3398,3 +3397,9 @@
         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:
@@ -3400,4 +3405,6 @@
     finally:
+        if tr:
+            tr.release()
         release(lock, wlock)
 
 @command('incoming|in',
diff --git a/tests/test-import-bypass.t b/tests/test-import-bypass.t
index 7f65ce5cc0112b6ce63392192049bdb1ea186358_dGVzdHMvdGVzdC1pbXBvcnQtYnlwYXNzLnQ=..62dc0e7ab092e10cb8dee3eac16108073dd71cea_dGVzdHMvdGVzdC1pbXBvcnQtYnlwYXNzLnQ= 100644
--- a/tests/test-import-bypass.t
+++ b/tests/test-import-bypass.t
@@ -60,8 +60,8 @@
   |/
   @  0:07f494440405 test 0 0 - default - adda
   
-  $ hg rollback -f
-  repository tip rolled back to revision 1 (undo commit)
+  $ hg rollback
+  repository tip rolled back to revision 1 (undo import)
 
 Test --import-branch
 
@@ -72,8 +72,8 @@
   |
   @  0:07f494440405 test 0 0 - default - adda
   
-  $ hg rollback -f
-  repository tip rolled back to revision 1 (undo commit)
+  $ hg rollback
+  repository tip rolled back to revision 1 (undo import)
 
 Test --strip
 
@@ -94,8 +94,8 @@
   > +a
   > EOF
   applying patch from stdin
-  $ hg rollback -f
-  repository tip rolled back to revision 1 (undo commit)
+  $ hg rollback
+  repository tip rolled back to revision 1 (undo import)
 
 Test unsupported combinations
 
diff --git a/tests/test-import.t b/tests/test-import.t
index 7f65ce5cc0112b6ce63392192049bdb1ea186358_dGVzdHMvdGVzdC1pbXBvcnQudA==..62dc0e7ab092e10cb8dee3eac16108073dd71cea_dGVzdHMvdGVzdC1pbXBvcnQudA== 100644
--- a/tests/test-import.t
+++ b/tests/test-import.t
@@ -365,6 +365,6 @@
   a
   created 6d019af21222
   $ hg --cwd b rollback
-  repository tip rolled back to revision 1 (undo commit)
-  working directory now based on revision 1
+  repository tip rolled back to revision 0 (undo import)
+  working directory now based on revision 0
   $ hg --cwd b parents --template 'parent: {rev}\n'
@@ -370,5 +370,5 @@
   $ hg --cwd b parents --template 'parent: {rev}\n'
-  parent: 1
+  parent: 0
   $ rm -r b
 
 
@@ -688,6 +688,7 @@
   adding a
   $ hg ci -m "commit"
   $ cat > a.patch <<EOF
+  > add a, b
   > diff --git a/a b/a
   > --- a/a
   > +++ b/a
@@ -698,5 +699,22 @@
   > EOF
   $ hg import --no-commit a.patch
   applying a.patch
+
+apply a good patch followed by an empty patch (mainly to ensure
+that dirstate is *not* updated when import crashes)
+  $ hg update -q -C .
+  $ rm b
+  $ touch empty.patch
+  $ hg import a.patch empty.patch
+  applying a.patch
+  applying empty.patch
+  transaction abort!
+  rollback completed
+  abort: empty.patch: no diffs found
+  [255]
+  $ hg tip --template '{rev}  {desc|firstline}\n'
+  0  commit
+  $ hg -q status
+  M a
   $ cd ..
 
@@ -701,6 +719,5 @@
   $ cd ..
 
-
 create file when source is not /dev/null
 
   $ cat > create.patch <<EOF
diff --git a/tests/test-keyword.t b/tests/test-keyword.t
index 7f65ce5cc0112b6ce63392192049bdb1ea186358_dGVzdHMvdGVzdC1rZXl3b3JkLnQ=..62dc0e7ab092e10cb8dee3eac16108073dd71cea_dGVzdHMvdGVzdC1rZXl3b3JkLnQ= 100644
--- a/tests/test-keyword.t
+++ b/tests/test-keyword.t
@@ -825,7 +825,7 @@
   ignore $Id$
 
   $ hg rollback
-  repository tip rolled back to revision 2 (undo commit)
+  repository tip rolled back to revision 2 (undo import)
   working directory now based on revision 2
   $ hg update --clean
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved