Mercurial > hg
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 |