comparison mercurial/localrepo.py @ 8496:a21605de1509

commit: move editor outside transaction The commit editor is now invoked before files and manifest are committed. The editor is now run with only the wlock held and aborting an edit no longer requires rolling back a transaction. Changes to files during a commit still result in undefined behavior. (This is preliminary work for committing subrepositories)
author Matt Mackall <mpm@selenic.com>
date Mon, 18 May 2009 17:36:24 -0500
parents a9dab5a0f85b
children a5182c39766a
comparison
equal deleted inserted replaced
8495:5b7596b142ad 8496:a21605de1509
808 ms = merge_.mergestate(self) 808 ms = merge_.mergestate(self)
809 for f in changes[0]: 809 for f in changes[0]:
810 if f in ms and ms[f] == 'u': 810 if f in ms and ms[f] == 'u':
811 raise util.Abort(_("unresolved merge conflicts " 811 raise util.Abort(_("unresolved merge conflicts "
812 "(see hg resolve)")) 812 "(see hg resolve)"))
813
813 wctx = context.workingctx(self, (p1, p2), text, user, date, 814 wctx = context.workingctx(self, (p1, p2), text, user, date,
814 extra, changes) 815 extra, changes)
815 ret = self.commitctx(wctx, editor, True) 816 if editor:
817 wctx._text = editor(self, wctx,
818 changes[1], changes[0], changes[2])
819
820 ret = self.commitctx(wctx, True)
816 ms.reset() 821 ms.reset()
817 822
818 # update dirstate 823 # update dirstate
819 for f in changes[0] + changes[1]: 824 for f in changes[0] + changes[1]:
820 self.dirstate.normal(f) 825 self.dirstate.normal(f)
827 finally: 832 finally:
828 if ret == None: 833 if ret == None:
829 self.dirstate.invalidate() # didn't successfully commit 834 self.dirstate.invalidate() # didn't successfully commit
830 wlock.release() 835 wlock.release()
831 836
832 def commitctx(self, ctx, editor=None, error=False): 837 def commitctx(self, ctx, error=False):
833 """Add a new revision to current repository. 838 """Add a new revision to current repository.
834 839
835 Revision information is passed via the context argument. 840 Revision information is passed via the context argument.
836 If editor is supplied, it is called to get a commit message. 841 If editor is supplied, it is called to get a commit message.
837 If working is set, the working directory is affected. 842 If working is set, the working directory is affected.
868 self.ui.warn(_("trouble committing %s!\n") % f) 873 self.ui.warn(_("trouble committing %s!\n") % f)
869 raise 874 raise
870 else: 875 else:
871 remove.append(f) 876 remove.append(f)
872 877
873 updated, added = [], []
874 for f in sorted(changed):
875 if f in m1 or f in m2:
876 updated.append(f)
877 else:
878 added.append(f)
879
880 # update manifest 878 # update manifest
881 m1.update(new) 879 m1.update(new)
882 removed = [f for f in sorted(remove) if f in m1 or f in m2] 880 removed = [f for f in sorted(remove) if f in m1 or f in m2]
883 removed1 = [] 881 removed1 = []
884 882
888 removed1.append(f) 886 removed1.append(f)
889 mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(), 887 mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
890 p2.manifestnode(), (new, removed1)) 888 p2.manifestnode(), (new, removed1))
891 889
892 text = ctx.description() 890 text = ctx.description()
893 if editor:
894 text = editor(self, ctx, added, updated, removed)
895
896 lines = [line.rstrip() for line in text.rstrip().splitlines()] 891 lines = [line.rstrip() for line in text.rstrip().splitlines()]
897 while lines and not lines[0]: 892 while lines and not lines[0]:
898 del lines[0] 893 del lines[0]
899 text = '\n'.join(lines) 894 text = '\n'.join(lines)
900 895