316 |
316 |
317 aliases, entry = cmdutil.findcmd('commit', commands.table) |
317 aliases, entry = cmdutil.findcmd('commit', commands.table) |
318 commitopts3 = evocommands.commitopts3 |
318 commitopts3 = evocommands.commitopts3 |
319 interactiveopt = evocommands.interactiveopt |
319 interactiveopt = evocommands.interactiveopt |
320 _bookmarksupdater = rewriteutil.bookmarksupdater |
320 _bookmarksupdater = rewriteutil.bookmarksupdater |
|
321 rewrite = rewriteutil.rewrite |
321 |
322 |
322 # This extension contains the following code |
323 # This extension contains the following code |
323 # |
324 # |
324 # - Extension Helper code |
325 # - Extension Helper code |
325 # - Obsolescence cache |
326 # - Obsolescence cache |
804 |
805 |
805 # XXX need clean up and proper sorting in other section |
806 # XXX need clean up and proper sorting in other section |
806 |
807 |
807 ### changeset rewriting logic |
808 ### changeset rewriting logic |
808 ############################# |
809 ############################# |
809 |
|
810 def rewrite(repo, old, updates, head, newbases, commitopts): |
|
811 """Return (nodeid, created) where nodeid is the identifier of the |
|
812 changeset generated by the rewrite process, and created is True if |
|
813 nodeid was actually created. If created is False, nodeid |
|
814 references a changeset existing before the rewrite call. |
|
815 """ |
|
816 wlock = lock = tr = None |
|
817 try: |
|
818 wlock = repo.wlock() |
|
819 lock = repo.lock() |
|
820 tr = repo.transaction('rewrite') |
|
821 if len(old.parents()) > 1: # XXX remove this unnecessary limitation. |
|
822 raise error.Abort(_('cannot amend merge changesets')) |
|
823 base = old.p1() |
|
824 updatebookmarks = _bookmarksupdater(repo, old.node(), tr) |
|
825 |
|
826 # commit a new version of the old changeset, including the update |
|
827 # collect all files which might be affected |
|
828 files = set(old.files()) |
|
829 for u in updates: |
|
830 files.update(u.files()) |
|
831 |
|
832 # Recompute copies (avoid recording a -> b -> a) |
|
833 copied = copies.pathcopies(base, head) |
|
834 |
|
835 # prune files which were reverted by the updates |
|
836 def samefile(f): |
|
837 if f in head.manifest(): |
|
838 a = head.filectx(f) |
|
839 if f in base.manifest(): |
|
840 b = base.filectx(f) |
|
841 return (a.data() == b.data() |
|
842 and a.flags() == b.flags()) |
|
843 else: |
|
844 return False |
|
845 else: |
|
846 return f not in base.manifest() |
|
847 files = [f for f in files if not samefile(f)] |
|
848 # commit version of these files as defined by head |
|
849 headmf = head.manifest() |
|
850 |
|
851 def filectxfn(repo, ctx, path): |
|
852 if path in headmf: |
|
853 fctx = head[path] |
|
854 flags = fctx.flags() |
|
855 mctx = context.memfilectx(repo, fctx.path(), fctx.data(), |
|
856 islink='l' in flags, |
|
857 isexec='x' in flags, |
|
858 copied=copied.get(path)) |
|
859 return mctx |
|
860 return None |
|
861 |
|
862 message = cmdutil.logmessage(repo.ui, commitopts) |
|
863 if not message: |
|
864 message = old.description() |
|
865 |
|
866 user = commitopts.get('user') or old.user() |
|
867 # TODO: In case not date is given, we should take the old commit date |
|
868 # if we are working one one changeset or mimic the fold behavior about |
|
869 # date |
|
870 date = commitopts.get('date') or None |
|
871 extra = dict(commitopts.get('extra', old.extra())) |
|
872 extra['branch'] = head.branch() |
|
873 |
|
874 new = context.memctx(repo, |
|
875 parents=newbases, |
|
876 text=message, |
|
877 files=files, |
|
878 filectxfn=filectxfn, |
|
879 user=user, |
|
880 date=date, |
|
881 extra=extra) |
|
882 |
|
883 if commitopts.get('edit'): |
|
884 new._text = cmdutil.commitforceeditor(repo, new, []) |
|
885 revcount = len(repo) |
|
886 newid = repo.commitctx(new) |
|
887 new = repo[newid] |
|
888 created = len(repo) != revcount |
|
889 updatebookmarks(newid) |
|
890 |
|
891 tr.close() |
|
892 return newid, created |
|
893 finally: |
|
894 lockmod.release(tr, lock, wlock) |
|
895 |
810 |
896 class MergeFailure(error.Abort): |
811 class MergeFailure(error.Abort): |
897 pass |
812 pass |
898 |
813 |
899 def relocate(repo, orig, dest, pctx=None, keepbranch=False): |
814 def relocate(repo, orig, dest, pctx=None, keepbranch=False): |