Mercurial > hg
comparison hgext/mq.py @ 7414:040484030491
Merge with crew
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 25 Nov 2008 16:24:22 -0600 |
parents | 7e9a15fa6c8f 41e87b4d0c9d |
children | 4c4324476be6 |
comparison
equal
deleted
inserted
replaced
7388:5751631246de | 7414:040484030491 |
---|---|
53 else: | 53 else: |
54 self.rev, self.name = rev, name | 54 self.rev, self.name = rev, name |
55 | 55 |
56 def __str__(self): | 56 def __str__(self): |
57 return self.rev + ':' + self.name | 57 return self.rev + ':' + self.name |
58 | |
59 class patchheader(object): | |
60 def __init__(self, message, comments, user, date, haspatch): | |
61 self.message = message | |
62 self.comments = comments | |
63 self.user = user | |
64 self.date = date | |
65 self.haspatch = haspatch | |
66 | |
67 def setuser(self, user): | |
68 if not self.setheader(['From: ', '# User '], user): | |
69 try: | |
70 patchheaderat = self.comments.index('# HG changeset patch') | |
71 self.comments.insert(patchheaderat + 1,'# User ' + user) | |
72 except ValueError: | |
73 self.comments = ['From: ' + user, ''] + self.comments | |
74 self.user = user | |
75 | |
76 def setdate(self, date): | |
77 if self.setheader(['# Date '], date): | |
78 self.date = date | |
79 | |
80 def setmessage(self, message): | |
81 if self.comments: | |
82 self._delmsg() | |
83 self.message = [message] | |
84 self.comments += self.message | |
85 | |
86 def setheader(self, prefixes, new): | |
87 '''Update all references to a field in the patch header. | |
88 If none found, add it email style.''' | |
89 res = False | |
90 for prefix in prefixes: | |
91 for i in xrange(len(self.comments)): | |
92 if self.comments[i].startswith(prefix): | |
93 self.comments[i] = prefix + new | |
94 res = True | |
95 break | |
96 return res | |
97 | |
98 def __str__(self): | |
99 if not self.comments: | |
100 return '' | |
101 return '\n'.join(self.comments) + '\n\n' | |
102 | |
103 def _delmsg(self): | |
104 '''Remove existing message, keeping the rest of the comments fields. | |
105 If comments contains 'subject: ', message will prepend | |
106 the field and a blank line.''' | |
107 if self.message: | |
108 subj = 'subject: ' + self.message[0].lower() | |
109 for i in xrange(len(self.comments)): | |
110 if subj == self.comments[i].lower(): | |
111 del self.comments[i] | |
112 self.message = self.message[2:] | |
113 break | |
114 ci = 0 | |
115 for mi in xrange(len(self.message)): | |
116 while self.message[mi] != self.comments[ci]: | |
117 ci += 1 | |
118 del self.comments[ci] | |
58 | 119 |
59 class queue: | 120 class queue: |
60 def __init__(self, ui, path, patchdir=None): | 121 def __init__(self, ui, path, patchdir=None): |
61 self.basepath = path | 122 self.basepath = path |
62 self.path = patchdir or os.path.join(path, "patches") | 123 self.path = patchdir or os.path.join(path, "patches") |
305 | 366 |
306 # make sure message isn't empty | 367 # make sure message isn't empty |
307 if format and format.startswith("tag") and subject: | 368 if format and format.startswith("tag") and subject: |
308 message.insert(0, "") | 369 message.insert(0, "") |
309 message.insert(0, subject) | 370 message.insert(0, subject) |
310 return (message, comments, user, date, diffstart > 1) | 371 return patchheader(message, comments, user, date, diffstart > 1) |
311 | 372 |
312 def removeundo(self, repo): | 373 def removeundo(self, repo): |
313 undo = repo.sjoin('undo') | 374 undo = repo.sjoin('undo') |
314 if not os.path.exists(undo): | 375 if not os.path.exists(undo): |
315 return | 376 return |
349 raise util.Abort(_("update returned %d") % ret) | 410 raise util.Abort(_("update returned %d") % ret) |
350 n = repo.commit(None, ctx.description(), ctx.user(), force=1) | 411 n = repo.commit(None, ctx.description(), ctx.user(), force=1) |
351 if n == None: | 412 if n == None: |
352 raise util.Abort(_("repo commit failed")) | 413 raise util.Abort(_("repo commit failed")) |
353 try: | 414 try: |
354 message, comments, user, date, patchfound = mergeq.readheaders(patch) | 415 ph = mergeq.readheaders(patch) |
355 except: | 416 except: |
356 raise util.Abort(_("unable to read %s") % patch) | 417 raise util.Abort(_("unable to read %s") % patch) |
357 | 418 |
358 patchf = self.opener(patch, "w") | 419 patchf = self.opener(patch, "w") |
420 comments = str(ph) | |
359 if comments: | 421 if comments: |
360 comments = "\n".join(comments) + '\n\n' | |
361 patchf.write(comments) | 422 patchf.write(comments) |
362 self.printdiff(repo, head, n, fp=patchf) | 423 self.printdiff(repo, head, n, fp=patchf) |
363 patchf.close() | 424 patchf.close() |
364 self.removeundo(repo) | 425 self.removeundo(repo) |
365 return (0, n) | 426 return (0, n) |
475 continue | 536 continue |
476 self.ui.warn(_("applying %s\n") % patchname) | 537 self.ui.warn(_("applying %s\n") % patchname) |
477 pf = os.path.join(patchdir, patchname) | 538 pf = os.path.join(patchdir, patchname) |
478 | 539 |
479 try: | 540 try: |
480 message, comments, user, date, patchfound = self.readheaders(patchname) | 541 ph = self.readheaders(patchname) |
481 except: | 542 except: |
482 self.ui.warn(_("Unable to read %s\n") % patchname) | 543 self.ui.warn(_("Unable to read %s\n") % patchname) |
483 err = 1 | 544 err = 1 |
484 break | 545 break |
485 | 546 |
547 message = ph.message | |
486 if not message: | 548 if not message: |
487 message = _("imported patch %s\n") % patchname | 549 message = _("imported patch %s\n") % patchname |
488 else: | 550 else: |
489 if list: | 551 if list: |
490 message.append(_("\nimported patch %s") % patchname) | 552 message.append(_("\nimported patch %s") % patchname) |
510 p1, p2 = repo.dirstate.parents() | 572 p1, p2 = repo.dirstate.parents() |
511 repo.dirstate.setparents(p1, merge) | 573 repo.dirstate.setparents(p1, merge) |
512 | 574 |
513 files = patch.updatedir(self.ui, repo, files) | 575 files = patch.updatedir(self.ui, repo, files) |
514 match = cmdutil.matchfiles(repo, files or []) | 576 match = cmdutil.matchfiles(repo, files or []) |
515 n = repo.commit(files, message, user, date, match=match, | 577 n = repo.commit(files, message, ph.user, ph.date, match=match, |
516 force=True) | 578 force=True) |
517 | 579 |
518 if n == None: | 580 if n == None: |
519 raise util.Abort(_("repo commit failed")) | 581 raise util.Abort(_("repo commit failed")) |
520 | 582 |
521 if update_status: | 583 if update_status: |
522 self.applied.append(statusentry(revlog.hex(n), patchname)) | 584 self.applied.append(statusentry(revlog.hex(n), patchname)) |
523 | 585 |
524 if patcherr: | 586 if patcherr: |
525 if not patchfound: | 587 if not ph.haspatch: |
526 self.ui.warn(_("patch %s is empty\n") % patchname) | 588 self.ui.warn(_("patch %s is empty\n") % patchname) |
527 err = 0 | 589 err = 0 |
528 else: | 590 else: |
529 self.ui.warn(_("patch failed, rejects left in working dir\n")) | 591 self.ui.warn(_("patch failed, rejects left in working dir\n")) |
530 err = 1 | 592 err = 1 |
822 if i + off < len(self.series): | 884 if i + off < len(self.series): |
823 return self.series[i + off] | 885 return self.series[i + off] |
824 raise util.Abort(_("patch %s not in series") % patch) | 886 raise util.Abort(_("patch %s not in series") % patch) |
825 | 887 |
826 def push(self, repo, patch=None, force=False, list=False, | 888 def push(self, repo, patch=None, force=False, list=False, |
827 mergeq=None): | 889 mergeq=None, all=False): |
828 wlock = repo.wlock() | 890 wlock = repo.wlock() |
829 if repo.dirstate.parents()[0] != repo.changelog.tip(): | 891 if repo.dirstate.parents()[0] != repo.changelog.tip(): |
830 self.ui.status(_("(working directory not at tip)\n")) | 892 self.ui.status(_("(working directory not at tip)\n")) |
893 | |
894 if not self.series: | |
895 self.ui.warn(_('no patches in series\n')) | |
896 return 0 | |
831 | 897 |
832 try: | 898 try: |
833 patch = self.lookup(patch) | 899 patch = self.lookup(patch) |
834 # Suppose our series file is: A B C and the current 'top' | 900 # Suppose our series file is: A B C and the current 'top' |
835 # patch is B. qpush C should be performed (moving forward) | 901 # patch is B. qpush C should be performed (moving forward) |
839 info = self.isapplied(patch) | 905 info = self.isapplied(patch) |
840 if info: | 906 if info: |
841 if info[0] < len(self.applied) - 1: | 907 if info[0] < len(self.applied) - 1: |
842 raise util.Abort( | 908 raise util.Abort( |
843 _("cannot push to a previous patch: %s") % patch) | 909 _("cannot push to a previous patch: %s") % patch) |
844 if info[0] < len(self.series) - 1: | 910 self.ui.warn( |
845 self.ui.warn( | 911 _('qpush: %s is already at the top\n') % patch) |
846 _('qpush: %s is already at the top\n') % patch) | 912 return |
913 pushable, reason = self.pushable(patch) | |
914 if not pushable: | |
915 if reason: | |
916 reason = _('guarded by %r') % reason | |
847 else: | 917 else: |
848 self.ui.warn(_('all patches are currently applied\n')) | 918 reason = _('no matching guards') |
849 return | 919 self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason)) |
920 return 1 | |
921 elif all: | |
922 patch = self.series[-1] | |
923 if self.isapplied(patch): | |
924 self.ui.warn(_('all patches are currently applied\n')) | |
925 return 0 | |
850 | 926 |
851 # Following the above example, starting at 'top' of B: | 927 # Following the above example, starting at 'top' of B: |
852 # qpush should be performed (pushes C), but a subsequent | 928 # qpush should be performed (pushes C), but a subsequent |
853 # qpush without an argument is an error (nothing to | 929 # qpush without an argument is an error (nothing to |
854 # apply). This allows a loop of "...while hg qpush..." to | 930 # apply). This allows a loop of "...while hg qpush..." to |
855 # work as it detects an error when done | 931 # work as it detects an error when done |
856 if self.series_end() == len(self.series): | 932 start = self.series_end() |
933 if start == len(self.series): | |
857 self.ui.warn(_('patch series already fully applied\n')) | 934 self.ui.warn(_('patch series already fully applied\n')) |
858 return 1 | 935 return 1 |
859 if not force: | 936 if not force: |
860 self.check_localchanges(repo) | 937 self.check_localchanges(repo) |
861 | 938 |
862 self.applied_dirty = 1; | 939 self.applied_dirty = 1 |
863 start = self.series_end() | |
864 if start > 0: | 940 if start > 0: |
865 self.check_toppatch(repo) | 941 self.check_toppatch(repo) |
866 if not patch: | 942 if not patch: |
867 patch = self.series[start] | 943 patch = self.series[start] |
868 end = start + 1 | 944 end = start + 1 |
999 | 1075 |
1000 def refresh(self, repo, pats=None, **opts): | 1076 def refresh(self, repo, pats=None, **opts): |
1001 if len(self.applied) == 0: | 1077 if len(self.applied) == 0: |
1002 self.ui.write(_("No patches applied\n")) | 1078 self.ui.write(_("No patches applied\n")) |
1003 return 1 | 1079 return 1 |
1080 msg = opts.get('msg', '').rstrip() | |
1081 newuser = opts.get('user') | |
1004 newdate = opts.get('date') | 1082 newdate = opts.get('date') |
1005 if newdate: | 1083 if newdate: |
1006 newdate = '%d %d' % util.parsedate(newdate) | 1084 newdate = '%d %d' % util.parsedate(newdate) |
1007 wlock = repo.wlock() | 1085 wlock = repo.wlock() |
1008 try: | 1086 try: |
1011 top = revlog.bin(top) | 1089 top = revlog.bin(top) |
1012 if repo.changelog.heads(top) != [top]: | 1090 if repo.changelog.heads(top) != [top]: |
1013 raise util.Abort(_("cannot refresh a revision with children")) | 1091 raise util.Abort(_("cannot refresh a revision with children")) |
1014 cparents = repo.changelog.parents(top) | 1092 cparents = repo.changelog.parents(top) |
1015 patchparent = self.qparents(repo, top) | 1093 patchparent = self.qparents(repo, top) |
1016 message, comments, user, date, patchfound = self.readheaders(patchfn) | 1094 ph = self.readheaders(patchfn) |
1017 | 1095 |
1018 patchf = self.opener(patchfn, 'r+') | 1096 patchf = self.opener(patchfn, 'r') |
1019 | 1097 |
1020 # if the patch was a git patch, refresh it as a git patch | 1098 # if the patch was a git patch, refresh it as a git patch |
1021 for line in patchf: | 1099 for line in patchf: |
1022 if line.startswith('diff --git'): | 1100 if line.startswith('diff --git'): |
1023 self.diffopts().git = True | 1101 self.diffopts().git = True |
1024 break | 1102 break |
1025 | 1103 |
1026 msg = opts.get('msg', '').rstrip() | 1104 if msg: |
1027 if msg and comments: | 1105 ph.setmessage(msg) |
1028 # Remove existing message, keeping the rest of the comments | |
1029 # fields. | |
1030 # If comments contains 'subject: ', message will prepend | |
1031 # the field and a blank line. | |
1032 if message: | |
1033 subj = 'subject: ' + message[0].lower() | |
1034 for i in xrange(len(comments)): | |
1035 if subj == comments[i].lower(): | |
1036 del comments[i] | |
1037 message = message[2:] | |
1038 break | |
1039 ci = 0 | |
1040 for mi in xrange(len(message)): | |
1041 while message[mi] != comments[ci]: | |
1042 ci += 1 | |
1043 del comments[ci] | |
1044 | |
1045 def setheaderfield(comments, prefixes, new): | |
1046 # Update all references to a field in the patch header. | |
1047 # If none found, add it email style. | |
1048 res = False | |
1049 for prefix in prefixes: | |
1050 for i in xrange(len(comments)): | |
1051 if comments[i].startswith(prefix): | |
1052 comments[i] = prefix + new | |
1053 res = True | |
1054 break | |
1055 return res | |
1056 | |
1057 newuser = opts.get('user') | |
1058 if newuser: | 1106 if newuser: |
1059 if not setheaderfield(comments, ['From: ', '# User '], newuser): | 1107 ph.setuser(newuser) |
1060 try: | |
1061 patchheaderat = comments.index('# HG changeset patch') | |
1062 comments.insert(patchheaderat + 1,'# User ' + newuser) | |
1063 except ValueError: | |
1064 comments = ['From: ' + newuser, ''] + comments | |
1065 user = newuser | |
1066 | |
1067 if newdate: | 1108 if newdate: |
1068 if setheaderfield(comments, ['# Date '], newdate): | 1109 ph.setdate(newdate) |
1069 date = newdate | 1110 |
1070 | 1111 # only commit new patch when write is complete |
1071 if msg: | 1112 patchf = self.opener(patchfn, 'w', atomictemp=True) |
1072 comments.append(msg) | |
1073 | 1113 |
1074 patchf.seek(0) | 1114 patchf.seek(0) |
1075 patchf.truncate() | 1115 patchf.truncate() |
1076 | 1116 |
1117 comments = str(ph) | |
1077 if comments: | 1118 if comments: |
1078 comments = "\n".join(comments) + '\n\n' | |
1079 patchf.write(comments) | 1119 patchf.write(comments) |
1080 | 1120 |
1081 if opts.get('git'): | 1121 if opts.get('git'): |
1082 self.diffopts().git = True | 1122 self.diffopts().git = True |
1083 tip = repo.changelog.tip() | 1123 tip = repo.changelog.tip() |
1146 match = cmdutil.matchfiles(repo, util.unique(c[0] + c[1] + c[2])) | 1186 match = cmdutil.matchfiles(repo, util.unique(c[0] + c[1] + c[2])) |
1147 chunks = patch.diff(repo, patchparent, match=match, | 1187 chunks = patch.diff(repo, patchparent, match=match, |
1148 changes=c, opts=self.diffopts()) | 1188 changes=c, opts=self.diffopts()) |
1149 for chunk in chunks: | 1189 for chunk in chunks: |
1150 patchf.write(chunk) | 1190 patchf.write(chunk) |
1151 patchf.close() | 1191 |
1152 | 1192 try: |
1153 repo.dirstate.setparents(*cparents) | 1193 copies = {} |
1154 copies = {} | 1194 for dst in a: |
1155 for dst in a: | 1195 src = repo.dirstate.copied(dst) |
1156 src = repo.dirstate.copied(dst) | 1196 if src is not None: |
1157 if src is not None: | 1197 copies.setdefault(src, []).append(dst) |
1158 copies.setdefault(src, []).append(dst) | 1198 repo.dirstate.add(dst) |
1159 repo.dirstate.add(dst) | 1199 # remember the copies between patchparent and tip |
1160 # remember the copies between patchparent and tip | 1200 # this may be slow, so don't do it if we're not tracking copies |
1161 # this may be slow, so don't do it if we're not tracking copies | 1201 if self.diffopts().git: |
1162 if self.diffopts().git: | 1202 for dst in aaa: |
1163 for dst in aaa: | 1203 f = repo.file(dst) |
1164 f = repo.file(dst) | 1204 src = f.renamed(man[dst]) |
1165 src = f.renamed(man[dst]) | 1205 if src: |
1166 if src: | 1206 copies.setdefault(src[0], []).extend(copies.get(dst, [])) |
1167 copies.setdefault(src[0], []).extend(copies.get(dst, [])) | 1207 if dst in a: |
1168 if dst in a: | 1208 copies[src[0]].append(dst) |
1169 copies[src[0]].append(dst) | 1209 # we can't copy a file created by the patch itself |
1170 # we can't copy a file created by the patch itself | 1210 if dst in copies: |
1171 if dst in copies: | 1211 del copies[dst] |
1172 del copies[dst] | 1212 for src, dsts in copies.iteritems(): |
1173 for src, dsts in copies.iteritems(): | 1213 for dst in dsts: |
1174 for dst in dsts: | 1214 repo.dirstate.copy(src, dst) |
1175 repo.dirstate.copy(src, dst) | 1215 for f in r: |
1176 for f in r: | 1216 repo.dirstate.remove(f) |
1177 repo.dirstate.remove(f) | 1217 # if the patch excludes a modified file, mark that |
1178 # if the patch excludes a modified file, mark that | 1218 # file with mtime=0 so status can see it. |
1179 # file with mtime=0 so status can see it. | 1219 mm = [] |
1180 mm = [] | 1220 for i in xrange(len(m)-1, -1, -1): |
1181 for i in xrange(len(m)-1, -1, -1): | 1221 if not matchfn(m[i]): |
1182 if not matchfn(m[i]): | 1222 mm.append(m[i]) |
1183 mm.append(m[i]) | 1223 del m[i] |
1184 del m[i] | 1224 for f in m: |
1185 for f in m: | 1225 repo.dirstate.normal(f) |
1186 repo.dirstate.normal(f) | 1226 for f in mm: |
1187 for f in mm: | 1227 repo.dirstate.normallookup(f) |
1188 repo.dirstate.normallookup(f) | 1228 for f in forget: |
1189 for f in forget: | 1229 repo.dirstate.forget(f) |
1190 repo.dirstate.forget(f) | 1230 |
1191 | 1231 if not msg: |
1192 if not msg: | 1232 if not ph.message: |
1193 if not message: | 1233 message = "[mq]: %s\n" % patchfn |
1194 message = "[mq]: %s\n" % patchfn | 1234 else: |
1235 message = "\n".join(ph.message) | |
1195 else: | 1236 else: |
1196 message = "\n".join(message) | 1237 message = msg |
1197 else: | 1238 |
1198 message = msg | 1239 user = ph.user or changes[1] |
1199 | 1240 |
1200 if not user: | 1241 # assumes strip can roll itself back if interrupted |
1201 user = changes[1] | 1242 repo.dirstate.setparents(*cparents) |
1202 | 1243 self.applied.pop() |
1203 self.applied.pop() | 1244 self.applied_dirty = 1 |
1204 self.applied_dirty = 1 | 1245 self.strip(repo, top, update=False, |
1205 self.strip(repo, top, update=False, | 1246 backup='strip') |
1206 backup='strip') | 1247 except: |
1207 n = repo.commit(match.files(), message, user, date, match=match, | 1248 repo.dirstate.invalidate() |
1208 force=1) | 1249 raise |
1209 self.applied.append(statusentry(revlog.hex(n), patchfn)) | 1250 |
1210 self.removeundo(repo) | 1251 try: |
1252 # might be nice to attempt to roll back strip after this | |
1253 patchf.rename() | |
1254 n = repo.commit(match.files(), message, user, ph.date, | |
1255 match=match, force=1) | |
1256 self.applied.append(statusentry(revlog.hex(n), patchfn)) | |
1257 except: | |
1258 ctx = repo[cparents[0]] | |
1259 repo.dirstate.rebuild(ctx.node(), ctx.manifest()) | |
1260 self.save_dirty() | |
1261 self.ui.warn(_('refresh interrupted while patch was popped! ' | |
1262 '(revert --all, qpush to recover)\n')) | |
1263 raise | |
1211 else: | 1264 else: |
1212 self.printdiff(repo, patchparent, fp=patchf) | 1265 self.printdiff(repo, patchparent, fp=patchf) |
1213 patchf.close() | 1266 patchf.rename() |
1214 added = repo.status()[1] | 1267 added = repo.status()[1] |
1215 for a in added: | 1268 for a in added: |
1216 f = repo.wjoin(a) | 1269 f = repo.wjoin(a) |
1217 try: | 1270 try: |
1218 os.unlink(f) | 1271 os.unlink(f) |
1226 repo.dirstate.forget(a) | 1279 repo.dirstate.forget(a) |
1227 self.pop(repo, force=True) | 1280 self.pop(repo, force=True) |
1228 self.push(repo, force=True) | 1281 self.push(repo, force=True) |
1229 finally: | 1282 finally: |
1230 del wlock | 1283 del wlock |
1284 self.removeundo(repo) | |
1231 | 1285 |
1232 def init(self, repo, create=False): | 1286 def init(self, repo, create=False): |
1233 if not create and os.path.isdir(self.path): | 1287 if not create and os.path.isdir(self.path): |
1234 raise util.Abort(_("patch queue directory already exists")) | 1288 raise util.Abort(_("patch queue directory already exists")) |
1235 try: | 1289 try: |
1257 | 1311 |
1258 def qseries(self, repo, missing=None, start=0, length=None, status=None, | 1312 def qseries(self, repo, missing=None, start=0, length=None, status=None, |
1259 summary=False): | 1313 summary=False): |
1260 def displayname(patchname): | 1314 def displayname(patchname): |
1261 if summary: | 1315 if summary: |
1262 msg = self.readheaders(patchname)[0] | 1316 ph = self.readheaders(patchname) |
1317 msg = ph.message | |
1263 msg = msg and ': ' + msg[0] or ': ' | 1318 msg = msg and ': ' + msg[0] or ': ' |
1264 else: | 1319 else: |
1265 msg = '' | 1320 msg = '' |
1266 return '%s%s' % (patchname, msg) | 1321 return '%s%s' % (patchname, msg) |
1267 | 1322 |
1813 ui.write(_("No patches applied\n")) | 1868 ui.write(_("No patches applied\n")) |
1814 return 1 | 1869 return 1 |
1815 if message: | 1870 if message: |
1816 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"')) | 1871 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"')) |
1817 patch = q.applied[-1].name | 1872 patch = q.applied[-1].name |
1818 (message, comment, user, date, hasdiff) = q.readheaders(patch) | 1873 ph = q.readheaders(patch) |
1819 message = ui.edit('\n'.join(message), user or ui.username()) | 1874 message = ui.edit('\n'.join(ph.message), ph.user or ui.username()) |
1820 setupheaderopts(ui, opts) | 1875 setupheaderopts(ui, opts) |
1821 ret = q.refresh(repo, pats, msg=message, **opts) | 1876 ret = q.refresh(repo, pats, msg=message, **opts) |
1822 q.save_dirty() | 1877 q.save_dirty() |
1823 return ret | 1878 return ret |
1824 | 1879 |
1872 raise util.Abort(_('qfold cannot fold already applied patch %s') % p) | 1927 raise util.Abort(_('qfold cannot fold already applied patch %s') % p) |
1873 patches.append(p) | 1928 patches.append(p) |
1874 | 1929 |
1875 for p in patches: | 1930 for p in patches: |
1876 if not message: | 1931 if not message: |
1877 messages.append(q.readheaders(p)[0]) | 1932 ph = q.readheaders(p) |
1933 messages.append(ph.message) | |
1878 pf = q.join(p) | 1934 pf = q.join(p) |
1879 (patchsuccess, files, fuzz) = q.patch(repo, pf) | 1935 (patchsuccess, files, fuzz) = q.patch(repo, pf) |
1880 if not patchsuccess: | 1936 if not patchsuccess: |
1881 raise util.Abort(_('Error folding patch %s') % p) | 1937 raise util.Abort(_('Error folding patch %s') % p) |
1882 patch.updatedir(ui, repo, files) | 1938 patch.updatedir(ui, repo, files) |
1883 | 1939 |
1884 if not message: | 1940 if not message: |
1885 message, comments, user = q.readheaders(parent)[0:3] | 1941 ph = q.readheaders(parent) |
1942 message, user = ph.message, ph.user | |
1886 for msg in messages: | 1943 for msg in messages: |
1887 message.append('* * *') | 1944 message.append('* * *') |
1888 message.extend(msg) | 1945 message.extend(msg) |
1889 message = '\n'.join(message) | 1946 message = '\n'.join(message) |
1890 | 1947 |
1963 else: | 2020 else: |
1964 if not q.applied: | 2021 if not q.applied: |
1965 ui.write('No patches applied\n') | 2022 ui.write('No patches applied\n') |
1966 return 1 | 2023 return 1 |
1967 patch = q.lookup('qtip') | 2024 patch = q.lookup('qtip') |
1968 message = repo.mq.readheaders(patch)[0] | 2025 ph = repo.mq.readheaders(patch) |
1969 | 2026 |
1970 ui.write('\n'.join(message) + '\n') | 2027 ui.write('\n'.join(ph.message) + '\n') |
1971 | 2028 |
1972 def lastsavename(path): | 2029 def lastsavename(path): |
1973 (directory, base) = os.path.split(path) | 2030 (directory, base) = os.path.split(path) |
1974 names = os.listdir(directory) | 2031 names = os.listdir(directory) |
1975 namere = re.compile("%s.([0-9]+)" % base) | 2032 namere = re.compile("%s.([0-9]+)" % base) |
1999 When --force is applied, all local changes in patched files will be lost. | 2056 When --force is applied, all local changes in patched files will be lost. |
2000 """ | 2057 """ |
2001 q = repo.mq | 2058 q = repo.mq |
2002 mergeq = None | 2059 mergeq = None |
2003 | 2060 |
2004 if opts['all']: | |
2005 if not q.series: | |
2006 ui.warn(_('no patches in series\n')) | |
2007 return 0 | |
2008 patch = q.series[-1] | |
2009 if opts['merge']: | 2061 if opts['merge']: |
2010 if opts['name']: | 2062 if opts['name']: |
2011 newpath = repo.join(opts['name']) | 2063 newpath = repo.join(opts['name']) |
2012 else: | 2064 else: |
2013 newpath, i = lastsavename(q.path) | 2065 newpath, i = lastsavename(q.path) |
2015 ui.warn(_("no saved queues found, please use -n\n")) | 2067 ui.warn(_("no saved queues found, please use -n\n")) |
2016 return 1 | 2068 return 1 |
2017 mergeq = queue(ui, repo.join(""), newpath) | 2069 mergeq = queue(ui, repo.join(""), newpath) |
2018 ui.warn(_("merging with queue at: %s\n") % mergeq.path) | 2070 ui.warn(_("merging with queue at: %s\n") % mergeq.path) |
2019 ret = q.push(repo, patch, force=opts['force'], list=opts['list'], | 2071 ret = q.push(repo, patch, force=opts['force'], list=opts['list'], |
2020 mergeq=mergeq) | 2072 mergeq=mergeq, all=opts.get('all')) |
2021 return ret | 2073 return ret |
2022 | 2074 |
2023 def pop(ui, repo, patch=None, **opts): | 2075 def pop(ui, repo, patch=None, **opts): |
2024 """pop the current patch off the stack | 2076 """pop the current patch off the stack |
2025 | 2077 |