# HG changeset patch # User Matt Mackall # Date 1197303869 21600 # Node ID bdb81d46b2fbde4456f225daf206969dc9a7df9f # Parent 7e6ddde68a2359c3c6d40bd4c740c3496d4be93b 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. diff -r 7e6ddde68a23 -r bdb81d46b2fb 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):