comparison mercurial/localrepo.py @ 5637:bdb81d46b2fb

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.
author Matt Mackall <mpm@selenic.com>
date Mon, 10 Dec 2007 10:24:29 -0600
parents a3df02cd4a35
children 47915bf68c44
comparison
equal deleted inserted replaced
5636:7e6ddde68a23 5637:bdb81d46b2fb
659 659
660 def commit(self, files=None, text="", user=None, date=None, 660 def commit(self, files=None, text="", user=None, date=None,
661 match=util.always, force=False, force_editor=False, 661 match=util.always, force=False, force_editor=False,
662 p1=None, p2=None, extra={}, empty_ok=False): 662 p1=None, p2=None, extra={}, empty_ok=False):
663 wlock = lock = tr = None 663 wlock = lock = tr = None
664 valid = 0 # don't save the dirstate if this isn't set
664 try: 665 try:
665 commit = [] 666 commit = []
666 remove = [] 667 remove = []
667 changed = [] 668 changed = []
668 use_dirstate = (p1 is None) # not rawcommit 669 use_dirstate = (p1 is None) # not rawcommit
745 old_exec = m1.execf(f) 746 old_exec = m1.execf(f)
746 old_link = m1.linkf(f) 747 old_link = m1.linkf(f)
747 if old_exec != new_exec or old_link != new_link: 748 if old_exec != new_exec or old_link != new_link:
748 changed.append(f) 749 changed.append(f)
749 m1.set(f, new_exec, new_link) 750 m1.set(f, new_exec, new_link)
751 if use_dirstate:
752 self.dirstate.normal(f)
753
750 except (OSError, IOError): 754 except (OSError, IOError):
751 if use_dirstate: 755 if use_dirstate:
752 self.ui.warn(_("trouble committing %s!\n") % f) 756 self.ui.warn(_("trouble committing %s!\n") % f)
753 raise 757 raise
754 else: 758 else:
815 self.branchcache[util.tolocal(extra["branch"])] = n 819 self.branchcache[util.tolocal(extra["branch"])] = n
816 820
817 if use_dirstate or update_dirstate: 821 if use_dirstate or update_dirstate:
818 self.dirstate.setparents(n) 822 self.dirstate.setparents(n)
819 if use_dirstate: 823 if use_dirstate:
820 for f in new:
821 self.dirstate.normal(f)
822 for f in removed: 824 for f in removed:
823 self.dirstate.forget(f) 825 self.dirstate.forget(f)
826 valid = 1 # our dirstate updates are complete
824 827
825 self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2) 828 self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
826 return n 829 return n
827 finally: 830 finally:
831 if not valid: # don't save our updated dirstate
832 self.dirstate.invalidate()
828 del tr, lock, wlock 833 del tr, lock, wlock
829 834
830 def walk(self, node=None, files=[], match=util.always, badmatch=None): 835 def walk(self, node=None, files=[], match=util.always, badmatch=None):
831 ''' 836 '''
832 walk recursively through the directory tree or a given 837 walk recursively through the directory tree or a given