531 pp = repo.dirstate.parents() |
531 pp = repo.dirstate.parents() |
532 if top not in pp: |
532 if top not in pp: |
533 raise util.Abort(_("queue top not at same revision as working directory")) |
533 raise util.Abort(_("queue top not at same revision as working directory")) |
534 return top |
534 return top |
535 return None |
535 return None |
536 def check_localchanges(self, repo): |
536 def check_localchanges(self, repo, force=False, refresh=True): |
537 (c, a, r, d, u) = repo.changes(None, None) |
537 m, a, r, d = repo.status()[:4] |
538 if c or a or d or r: |
538 if m or a or r or d: |
539 raise util.Abort(_("local changes found, refresh first")) |
539 if not force: |
|
540 if refresh: |
|
541 raise util.Abort(_("local changes found, refresh first")) |
|
542 else: |
|
543 raise util.Abort(_("local changes found")) |
|
544 return m, a, r, d |
540 def new(self, repo, patch, msg=None, force=None): |
545 def new(self, repo, patch, msg=None, force=None): |
541 if os.path.exists(self.join(patch)): |
546 if os.path.exists(self.join(patch)): |
542 raise util.Abort(_('patch "%s" already exists') % patch) |
547 raise util.Abort(_('patch "%s" already exists') % patch) |
543 commitfiles = [] |
548 m, a, r, d = self.check_localchanges(repo, force) |
544 (c, a, r, d, u) = repo.changes(None, None) |
549 commitfiles = m + a + r |
545 if c or a or d or r: |
|
546 if not force: |
|
547 raise util.Abort(_("local changes found, refresh first")) |
|
548 commitfiles = c + a + r |
|
549 self.check_toppatch(repo) |
550 self.check_toppatch(repo) |
550 wlock = repo.wlock() |
551 wlock = repo.wlock() |
551 insert = self.full_series_end() |
552 insert = self.full_series_end() |
552 if msg: |
553 if msg: |
553 n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True, |
554 n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True, |
657 # TODO delete the undo files, and handle undo of merge sets |
658 # TODO delete the undo files, and handle undo of merge sets |
658 pp = chlog.parents(rev) |
659 pp = chlog.parents(rev) |
659 revnum = chlog.rev(rev) |
660 revnum = chlog.rev(rev) |
660 |
661 |
661 if update: |
662 if update: |
662 (c, a, r, d, u) = repo.changes(None, None) |
663 self.check_localchanges(repo, refresh=False) |
663 if c or a or d or r: |
|
664 raise util.Abort(_("local changes found")) |
|
665 urev = self.qparents(repo, rev) |
664 urev = self.qparents(repo, rev) |
666 hg.clean(repo, urev, wlock=wlock) |
665 hg.clean(repo, urev, wlock=wlock) |
667 repo.dirstate.write() |
666 repo.dirstate.write() |
668 |
667 |
669 # save is a list of all the branches we are truncating away |
668 # save is a list of all the branches we are truncating away |
897 if update: |
896 if update: |
898 top = self.check_toppatch(repo) |
897 top = self.check_toppatch(repo) |
899 qp = self.qparents(repo, rev) |
898 qp = self.qparents(repo, rev) |
900 changes = repo.changelog.read(qp) |
899 changes = repo.changelog.read(qp) |
901 mmap = repo.manifest.read(changes[0]) |
900 mmap = repo.manifest.read(changes[0]) |
902 (c, a, r, d, u) = repo.changes(qp, top) |
901 m, a, r, d, u = repo.status(qp, top)[:5] |
903 if d: |
902 if d: |
904 raise util.Abort("deletions found between repo revs") |
903 raise util.Abort("deletions found between repo revs") |
905 for f in c: |
904 for f in m: |
906 getfile(f, mmap[f]) |
905 getfile(f, mmap[f]) |
907 for f in r: |
906 for f in r: |
908 getfile(f, mmap[f]) |
907 getfile(f, mmap[f]) |
909 util.set_exec(repo.wjoin(f), mmap.execf(f)) |
908 util.set_exec(repo.wjoin(f), mmap.execf(f)) |
910 repo.dirstate.update(c + r, 'n') |
909 repo.dirstate.update(m + r, 'n') |
911 for f in a: |
910 for f in a: |
912 try: os.unlink(repo.wjoin(f)) |
911 try: os.unlink(repo.wjoin(f)) |
913 except: raise |
912 except: raise |
914 try: os.removedirs(os.path.dirname(repo.wjoin(f))) |
913 try: os.removedirs(os.path.dirname(repo.wjoin(f))) |
915 except: pass |
914 except: pass |
968 # |
967 # |
969 # in short mode, we only diff the files included in the |
968 # in short mode, we only diff the files included in the |
970 # patch already |
969 # patch already |
971 # |
970 # |
972 # this should really read: |
971 # this should really read: |
973 #(cc, dd, aa, aa2, uu) = repo.changes(tip, patchparent) |
972 # mm, dd, aa, aa2, uu = repo.status(tip, patchparent)[:5] |
974 # but we do it backwards to take advantage of manifest/chlog |
973 # but we do it backwards to take advantage of manifest/chlog |
975 # caching against the next repo.changes call |
974 # caching against the next repo.status call |
976 # |
975 # |
977 (cc, aa, dd, aa2, uu) = repo.changes(patchparent, tip) |
976 mm, aa, dd, aa2, uu = repo.status(patchparent, tip)[:5] |
978 if short: |
977 if short: |
979 filelist = cc + aa + dd |
978 filelist = mm + aa + dd |
980 else: |
979 else: |
981 filelist = None |
980 filelist = None |
982 (c, a, r, d, u) = repo.changes(None, None, filelist) |
981 m, a, r, d, u = repo.status(files=filelist)[:5] |
983 |
982 |
984 # we might end up with files that were added between tip and |
983 # we might end up with files that were added between tip and |
985 # the dirstate parent, but then changed in the local dirstate. |
984 # the dirstate parent, but then changed in the local dirstate. |
986 # in this case, we want them to only show up in the added section |
985 # in this case, we want them to only show up in the added section |
987 for x in c: |
986 for x in m: |
988 if x not in aa: |
987 if x not in aa: |
989 cc.append(x) |
988 mm.append(x) |
990 # we might end up with files added by the local dirstate that |
989 # we might end up with files added by the local dirstate that |
991 # were deleted by the patch. In this case, they should only |
990 # were deleted by the patch. In this case, they should only |
992 # show up in the changed section. |
991 # show up in the changed section. |
993 for x in a: |
992 for x in a: |
994 if x in dd: |
993 if x in dd: |
995 del dd[dd.index(x)] |
994 del dd[dd.index(x)] |
996 cc.append(x) |
995 mm.append(x) |
997 else: |
996 else: |
998 aa.append(x) |
997 aa.append(x) |
999 # make sure any files deleted in the local dirstate |
998 # make sure any files deleted in the local dirstate |
1000 # are not in the add or change column of the patch |
999 # are not in the add or change column of the patch |
1001 forget = [] |
1000 forget = [] |
1002 for x in d + r: |
1001 for x in d + r: |
1003 if x in aa: |
1002 if x in aa: |
1004 del aa[aa.index(x)] |
1003 del aa[aa.index(x)] |
1005 forget.append(x) |
1004 forget.append(x) |
1006 continue |
1005 continue |
1007 elif x in cc: |
1006 elif x in mm: |
1008 del cc[cc.index(x)] |
1007 del mm[mm.index(x)] |
1009 dd.append(x) |
1008 dd.append(x) |
1010 |
1009 |
1011 c = list(util.unique(cc)) |
1010 m = list(util.unique(mm)) |
1012 r = list(util.unique(dd)) |
1011 r = list(util.unique(dd)) |
1013 a = list(util.unique(aa)) |
1012 a = list(util.unique(aa)) |
1014 filelist = list(util.unique(c + r + a )) |
1013 filelist = list(util.unique(m + r + a)) |
1015 self.printdiff(repo, patchparent, files=filelist, |
1014 self.printdiff(repo, patchparent, files=filelist, |
1016 changes=(c, a, r, [], u), fp=patchf) |
1015 changes=(m, a, r, [], u), fp=patchf) |
1017 patchf.close() |
1016 patchf.close() |
1018 |
1017 |
1019 changes = repo.changelog.read(tip) |
1018 changes = repo.changelog.read(tip) |
1020 repo.dirstate.setparents(*cparents) |
1019 repo.dirstate.setparents(*cparents) |
1021 repo.dirstate.update(a, 'a') |
1020 repo.dirstate.update(a, 'a') |
1022 repo.dirstate.update(r, 'r') |
1021 repo.dirstate.update(r, 'r') |
1023 repo.dirstate.update(c, 'n') |
1022 repo.dirstate.update(m, 'n') |
1024 repo.dirstate.forget(forget) |
1023 repo.dirstate.forget(forget) |
1025 |
1024 |
1026 if not msg: |
1025 if not msg: |
1027 if not message: |
1026 if not message: |
1028 message = "patch queue: %s\n" % patch |
1027 message = "patch queue: %s\n" % patch |