commit: avoid losing edits during commit
authorMatt Mackall <mpm@selenic.com>
Mon, 10 Dec 2007 10:24:29 -0600
changeset 5637 bdb81d46b2fb
parent 5636 7e6ddde68a23
child 5638 a9b7e425674f
commit: avoid losing edits during commit If a file is edited between the time we record file states in the repo and update the dirstate, that change can be lost to hg status. Because we invoke the editor between these two points, that window can be arbitrarily large. This greatly shrinks the window by recording the commit change immediately. If our checkin fails, we simply invalidate the dirstate.
mercurial/localrepo.py
--- a/mercurial/localrepo.py	Mon Dec 10 10:24:21 2007 -0600
+++ b/mercurial/localrepo.py	Mon Dec 10 10:24:29 2007 -0600
@@ -661,6 +661,7 @@
                match=util.always, force=False, force_editor=False,
                p1=None, p2=None, extra={}, empty_ok=False):
         wlock = lock = tr = None
+        valid = 0 # don't save the dirstate if this isn't set
         try:
             commit = []
             remove = []
@@ -747,6 +748,9 @@
                         if old_exec != new_exec or old_link != new_link:
                             changed.append(f)
                     m1.set(f, new_exec, new_link)
+                    if use_dirstate:
+                        self.dirstate.normal(f)
+
                 except (OSError, IOError):
                     if use_dirstate:
                         self.ui.warn(_("trouble committing %s!\n") % f)
@@ -817,14 +821,15 @@
             if use_dirstate or update_dirstate:
                 self.dirstate.setparents(n)
                 if use_dirstate:
-                    for f in new:
-                        self.dirstate.normal(f)
                     for f in removed:
                         self.dirstate.forget(f)
+            valid = 1 # our dirstate updates are complete
 
             self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
             return n
         finally:
+            if not valid: # don't save our updated dirstate
+                self.dirstate.invalidate()
             del tr, lock, wlock
 
     def walk(self, node=None, files=[], match=util.always, badmatch=None):