416 raise util.Abort(_("Local changes found, refresh first")) |
416 raise util.Abort(_("Local changes found, refresh first")) |
417 else: |
417 else: |
418 commitfiles = c + a + r |
418 commitfiles = c + a + r |
419 self.check_toppatch(repo) |
419 self.check_toppatch(repo) |
420 wlock = repo.wlock() |
420 wlock = repo.wlock() |
421 insert = self.series_end() |
421 insert = self.full_series_end() |
422 if msg: |
422 if msg: |
423 n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True, |
423 n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True, |
424 wlock=wlock) |
424 wlock=wlock) |
425 else: |
425 else: |
426 n = repo.commit(commitfiles, |
426 n = repo.commit(commitfiles, |
528 # TODO delete the undo files, and handle undo of merge sets |
528 # TODO delete the undo files, and handle undo of merge sets |
529 pp = chlog.parents(rev) |
529 pp = chlog.parents(rev) |
530 revnum = chlog.rev(rev) |
530 revnum = chlog.rev(rev) |
531 |
531 |
532 if update: |
532 if update: |
|
533 (c, a, r, d, u) = repo.changes(None, None) |
|
534 if c or a or d or r: |
|
535 raise util.Abort(_("Local changes found")) |
533 urev = self.qparents(repo, rev) |
536 urev = self.qparents(repo, rev) |
534 repo.update(urev, allow=False, force=True, wlock=wlock) |
537 repo.update(urev, allow=False, force=True, wlock=wlock) |
535 repo.dirstate.write() |
538 repo.dirstate.write() |
536 |
539 |
537 # save is a list of all the branches we are truncating away |
540 # save is a list of all the branches we are truncating away |
596 a = p.split(':') |
599 a = p.split(':') |
597 if a[1] == patch: |
600 if a[1] == patch: |
598 return (i, a[0], a[1]) |
601 return (i, a[0], a[1]) |
599 return None |
602 return None |
600 |
603 |
601 def lookup(self, patch): |
604 # if the exact patch name does not exist, we try a few |
|
605 # variations. If strict is passed, we try only #1 |
|
606 # |
|
607 # 1) a number to indicate an offset in the series file |
|
608 # 2) a unique substring of the patch name was given |
|
609 # 3) patchname[-+]num to indicate an offset in the series file |
|
610 def lookup(self, patch, strict=False): |
|
611 def partial_name(s): |
|
612 count = 0 |
|
613 if s in self.series: |
|
614 return s |
|
615 for x in self.series: |
|
616 if s in x: |
|
617 count += 1 |
|
618 last = x |
|
619 if count > 1: |
|
620 return None |
|
621 if count: |
|
622 return last |
|
623 if len(self.series) > 0 and len(self.applied) > 0: |
|
624 if s == 'qtip': |
|
625 return self.series[self.series_end()-1] |
|
626 if s == 'qbase': |
|
627 return self.series[0] |
|
628 return None |
602 if patch == None: |
629 if patch == None: |
603 return None |
630 return None |
604 if patch in self.series: |
631 |
605 return patch |
632 # we don't want to return a partial match until we make |
|
633 # sure the file name passed in does not exist (checked below) |
|
634 res = partial_name(patch) |
|
635 if res and res == patch: |
|
636 return res |
|
637 |
606 if not os.path.isfile(os.path.join(self.path, patch)): |
638 if not os.path.isfile(os.path.join(self.path, patch)): |
607 try: |
639 try: |
608 sno = int(patch) |
640 sno = int(patch) |
609 except(ValueError, OverflowError): |
641 except(ValueError, OverflowError): |
610 self.ui.warn("patch %s not in series\n" % patch) |
642 pass |
611 sys.exit(1) |
643 else: |
612 if sno >= len(self.series): |
644 if sno < len(self.series): |
613 self.ui.warn("patch number %d is out of range\n" % sno) |
645 patch = self.series[sno] |
614 sys.exit(1) |
646 return patch |
615 patch = self.series[sno] |
647 if not strict: |
616 else: |
648 # return any partial match made above |
617 self.ui.warn("patch %s not in series\n" % patch) |
649 if res: |
618 sys.exit(1) |
650 return res |
619 return patch |
651 minus = patch.rsplit('-', 1) |
|
652 if len(minus) > 1: |
|
653 res = partial_name(minus[0]) |
|
654 if res: |
|
655 i = self.series.index(res) |
|
656 try: |
|
657 off = int(minus[1] or 1) |
|
658 except(ValueError, OverflowError): |
|
659 pass |
|
660 else: |
|
661 if i - off >= 0: |
|
662 return self.series[i - off] |
|
663 plus = patch.rsplit('+', 1) |
|
664 if len(plus) > 1: |
|
665 res = partial_name(plus[0]) |
|
666 if res: |
|
667 i = self.series.index(res) |
|
668 try: |
|
669 off = int(plus[1] or 1) |
|
670 except(ValueError, OverflowError): |
|
671 pass |
|
672 else: |
|
673 if i + off < len(self.series): |
|
674 return self.series[i + off] |
|
675 self.ui.warn("patch %s not in series\n" % patch) |
|
676 sys.exit(1) |
620 |
677 |
621 def push(self, repo, patch=None, force=False, list=False, |
678 def push(self, repo, patch=None, force=False, list=False, |
622 mergeq=None, wlock=None): |
679 mergeq=None, wlock=None): |
623 if not wlock: |
680 if not wlock: |
624 wlock = repo.wlock() |
681 wlock = repo.wlock() |
737 self.ui.write("No patches applied\n") |
805 self.ui.write("No patches applied\n") |
738 return |
806 return |
739 qp = self.qparents(repo, top) |
807 qp = self.qparents(repo, top) |
740 commands.dodiff(sys.stdout, self.ui, repo, qp, None, files) |
808 commands.dodiff(sys.stdout, self.ui, repo, qp, None, files) |
741 |
809 |
742 def refresh(self, repo, short=False): |
810 def refresh(self, repo, msg=None, short=False): |
743 if len(self.applied) == 0: |
811 if len(self.applied) == 0: |
744 self.ui.write("No patches applied\n") |
812 self.ui.write("No patches applied\n") |
745 return |
813 return |
746 wlock = repo.wlock() |
814 wlock = repo.wlock() |
747 self.check_toppatch(repo) |
815 self.check_toppatch(repo) |
820 repo.dirstate.update(a, 'a') |
888 repo.dirstate.update(a, 'a') |
821 repo.dirstate.update(r, 'r') |
889 repo.dirstate.update(r, 'r') |
822 repo.dirstate.update(c, 'n') |
890 repo.dirstate.update(c, 'n') |
823 repo.dirstate.forget(forget) |
891 repo.dirstate.forget(forget) |
824 |
892 |
825 if not message: |
893 if not msg: |
826 message = "patch queue: %s\n" % patch |
894 if not message: |
|
895 message = "patch queue: %s\n" % patch |
|
896 else: |
|
897 message = "\n".join(message) |
827 else: |
898 else: |
828 message = "\n".join(message) |
899 message = msg |
|
900 |
829 self.strip(repo, top, update=False, backup='strip', wlock=wlock) |
901 self.strip(repo, top, update=False, backup='strip', wlock=wlock) |
830 n = repo.commit(filelist, message, changes[1], force=1, wlock=wlock) |
902 n = repo.commit(filelist, message, changes[1], force=1, wlock=wlock) |
831 self.applied[-1] = revlog.hex(n) + ':' + patch |
903 self.applied[-1] = revlog.hex(n) + ':' + patch |
832 self.applied_dirty = 1 |
904 self.applied_dirty = 1 |
833 else: |
905 else: |
972 self.ui.warn("repo commit failed\n") |
1046 self.ui.warn("repo commit failed\n") |
973 return 1 |
1047 return 1 |
974 self.applied.append(revlog.hex(n) + ":" + '.hg.patches.save.line') |
1048 self.applied.append(revlog.hex(n) + ":" + '.hg.patches.save.line') |
975 self.applied_dirty = 1 |
1049 self.applied_dirty = 1 |
976 |
1050 |
|
1051 def full_series_end(self): |
|
1052 if len(self.applied) > 0: |
|
1053 (top, p) = self.applied[-1].split(':') |
|
1054 end = self.find_series(p) |
|
1055 if end == None: |
|
1056 return len(self.full_series) |
|
1057 return end + 1 |
|
1058 return 0 |
|
1059 |
977 def series_end(self): |
1060 def series_end(self): |
978 end = 0 |
1061 end = 0 |
979 if len(self.applied) > 0: |
1062 if len(self.applied) > 0: |
980 (top, p) = self.applied[-1].split(':') |
1063 (top, p) = self.applied[-1].split(':') |
981 try: |
1064 try: |
997 p = self.appliedname(x) |
1080 p = self.appliedname(x) |
998 self.ui.write("%s\n" % p) |
1081 self.ui.write("%s\n" % p) |
999 |
1082 |
1000 def appliedname(self, index): |
1083 def appliedname(self, index): |
1001 p = self.applied[index] |
1084 p = self.applied[index] |
|
1085 pname = p.split(':')[1] |
1002 if not self.ui.verbose: |
1086 if not self.ui.verbose: |
1003 p = p.split(':')[1] |
1087 p = pname |
|
1088 else: |
|
1089 p = str(self.series.index(pname)) + " " + p |
1004 return p |
1090 return p |
1005 |
1091 |
1006 def top(self, repo): |
1092 def top(self, repo): |
1007 if len(self.applied): |
1093 if len(self.applied): |
1008 p = self.appliedname(-1) |
1094 p = self.appliedname(-1) |
1013 def next(self, repo): |
1099 def next(self, repo): |
1014 end = self.series_end() |
1100 end = self.series_end() |
1015 if end == len(self.series): |
1101 if end == len(self.series): |
1016 self.ui.write("All patches applied\n") |
1102 self.ui.write("All patches applied\n") |
1017 else: |
1103 else: |
1018 self.ui.write(self.series[end] + '\n') |
1104 p = self.series[end] |
|
1105 if self.ui.verbose: |
|
1106 self.ui.write("%d " % self.series.index(p)) |
|
1107 self.ui.write(p + '\n') |
1019 |
1108 |
1020 def prev(self, repo): |
1109 def prev(self, repo): |
1021 if len(self.applied) > 1: |
1110 if len(self.applied) > 1: |
1022 p = self.appliedname(-2) |
1111 p = self.appliedname(-2) |
1023 self.ui.write(p + '\n') |
1112 self.ui.write(p + '\n') |
1134 return 0 |
1223 return 0 |
1135 |
1224 |
1136 def new(ui, repo, patch, **opts): |
1225 def new(ui, repo, patch, **opts): |
1137 """create a new patch""" |
1226 """create a new patch""" |
1138 q = repomap[repo] |
1227 q = repomap[repo] |
1139 q.new(repo, patch, msg=opts['message'], force=opts['force']) |
1228 message=commands.logmessage(**opts) |
|
1229 q.new(repo, patch, msg=message, force=opts['force']) |
1140 q.save_dirty() |
1230 q.save_dirty() |
1141 return 0 |
1231 return 0 |
1142 |
1232 |
1143 def refresh(ui, repo, **opts): |
1233 def refresh(ui, repo, **opts): |
1144 """update the current patch""" |
1234 """update the current patch""" |
1145 q = repomap[repo] |
1235 q = repomap[repo] |
1146 q.refresh(repo, short=opts['short']) |
1236 message=commands.logmessage(**opts) |
|
1237 q.refresh(repo, msg=message, short=opts['short']) |
1147 q.save_dirty() |
1238 q.save_dirty() |
1148 return 0 |
1239 return 0 |
1149 |
1240 |
1150 def diff(ui, repo, *files, **opts): |
1241 def diff(ui, repo, *files, **opts): |
1151 """diff of the current patch""" |
1242 """diff of the current patch""" |
1206 q = queue(ui, repo.join(""), repo.join(opts['name'])) |
1297 q = queue(ui, repo.join(""), repo.join(opts['name'])) |
1207 ui.warn('using patch queue: %s\n' % q.path) |
1298 ui.warn('using patch queue: %s\n' % q.path) |
1208 localupdate = False |
1299 localupdate = False |
1209 else: |
1300 else: |
1210 q = repomap[repo] |
1301 q = repomap[repo] |
1211 if opts['all'] and len(q.applied) > 0: |
1302 q.pop(repo, patch, force=opts['force'], update=localupdate, all=opts['all']) |
1212 patch = q.applied[0].split(':')[1] |
|
1213 q.pop(repo, patch, force=opts['force'], update=localupdate) |
|
1214 q.save_dirty() |
1303 q.save_dirty() |
1215 return 0 |
1304 return 0 |
1216 |
1305 |
1217 def restore(ui, repo, rev, **opts): |
1306 def restore(ui, repo, rev, **opts): |
1218 """restore the queue state saved by a rev""" |
1307 """restore the queue state saved by a rev""" |
1270 ui.write("mq version %s\n" % versionstr) |
1360 ui.write("mq version %s\n" % versionstr) |
1271 return 0 |
1361 return 0 |
1272 |
1362 |
1273 def reposetup(ui, repo): |
1363 def reposetup(ui, repo): |
1274 repomap[repo] = queue(ui, repo.join("")) |
1364 repomap[repo] = queue(ui, repo.join("")) |
1275 oldlookup = repo.lookup |
1365 oldtags = repo.tags |
1276 |
1366 |
1277 def qlookup(key): |
1367 def qtags(): |
1278 try: |
1368 if repo.tagscache: |
1279 return oldlookup(key) |
1369 return repo.tagscache |
1280 except hg.RepoError: |
1370 |
1281 q = repomap[repo] |
1371 tagscache = oldtags() |
1282 |
1372 |
1283 qpatchnames = { 'qtip': -1, 'qbase': 0 } |
1373 q = repomap[repo] |
1284 if key in qpatchnames: |
1374 if len(q.applied) == 0: |
1285 if len(q.applied) == 0: |
1375 return tagscache |
1286 self.ui.warn('No patches applied\n') |
1376 |
1287 raise |
1377 mqtags = [patch.split(':') for patch in q.applied] |
1288 patch = q.applied[qpatchnames[key]].split(':')[0] |
1378 mqtags.append((mqtags[-1][0], 'qtip')) |
1289 return revlog.bin(patch) |
1379 mqtags.append((mqtags[0][0], 'qbase')) |
1290 |
1380 for patch in mqtags: |
1291 patch = q.isapplied(key) |
1381 if patch[1] in tagscache: |
1292 if not patch: |
1382 repo.ui.warn('Tag %s overrides mq patch of the same name\n' % patch[1]) |
1293 raise |
1383 else: |
1294 return revlog.bin(patch[1]) |
1384 tagscache[patch[1]] = revlog.bin(patch[0]) |
1295 |
1385 |
1296 repo.lookup = qlookup |
1386 return tagscache |
|
1387 |
|
1388 repo.tags = qtags |
1297 |
1389 |
1298 cmdtable = { |
1390 cmdtable = { |
1299 "qapplied": (applied, [], 'hg qapplied [PATCH]'), |
1391 "qapplied": (applied, [], 'hg qapplied [PATCH]'), |
1300 "qcommit|qci": |
1392 "qcommit|qci": |
1301 (commit, |
1393 (commit, |
1313 (init, |
1405 (init, |
1314 [('c', 'create-repo', None, 'create queue repository')], |
1406 [('c', 'create-repo', None, 'create queue repository')], |
1315 'hg qinit [-c]'), |
1407 'hg qinit [-c]'), |
1316 "qnew": |
1408 "qnew": |
1317 (new, |
1409 (new, |
1318 [('m', 'message', '', 'commit message'), |
1410 [('m', 'message', '', _('use <text> as commit message')), |
|
1411 ('l', 'logfile', '', _('read the commit message from <file>')), |
1319 ('f', 'force', None, 'force')], |
1412 ('f', 'force', None, 'force')], |
1320 'hg qnew [-m TEXT] [-f] PATCH'), |
1413 'hg qnew [-m TEXT] [-l FILE] [-f] PATCH'), |
1321 "qnext": (next, [], 'hg qnext'), |
1414 "qnext": (next, [], 'hg qnext'), |
1322 "qprev": (prev, [], 'hg qprev'), |
1415 "qprev": (prev, [], 'hg qprev'), |
1323 "^qpop": |
1416 "^qpop": |
1324 (pop, |
1417 (pop, |
1325 [('a', 'all', None, 'pop all patches'), |
1418 [('a', 'all', None, 'pop all patches'), |
1334 ('m', 'merge', None, 'merge from another queue'), |
1427 ('m', 'merge', None, 'merge from another queue'), |
1335 ('n', 'name', '', 'merge queue name')], |
1428 ('n', 'name', '', 'merge queue name')], |
1336 'hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]'), |
1429 'hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]'), |
1337 "^qrefresh": |
1430 "^qrefresh": |
1338 (refresh, |
1431 (refresh, |
1339 [('s', 'short', None, 'short refresh')], |
1432 [('m', 'message', '', _('change commit message with <text>')), |
1340 'hg qrefresh [-s]'), |
1433 ('l', 'logfile', '', _('change commit message with <file> content')), |
|
1434 ('s', 'short', None, 'short refresh')], |
|
1435 'hg qrefresh [-m TEXT] [-l FILE] [-s]'), |
1341 "qrestore": |
1436 "qrestore": |
1342 (restore, |
1437 (restore, |
1343 [('d', 'delete', None, 'delete save entry'), |
1438 [('d', 'delete', None, 'delete save entry'), |
1344 ('u', 'update', None, 'update queue working dir')], |
1439 ('u', 'update', None, 'update queue working dir')], |
1345 'hg qrestore [-d] [-u] REV'), |
1440 'hg qrestore [-d] [-u] REV'), |
1346 "qsave": |
1441 "qsave": |
1347 (save, |
1442 (save, |
1348 [('m', 'message', '', 'commit message'), |
1443 [('m', 'message', '', _('use <text> as commit message')), |
|
1444 ('l', 'logfile', '', _('read the commit message from <file>')), |
1349 ('c', 'copy', None, 'copy patch directory'), |
1445 ('c', 'copy', None, 'copy patch directory'), |
1350 ('n', 'name', '', 'copy directory name'), |
1446 ('n', 'name', '', 'copy directory name'), |
1351 ('e', 'empty', None, 'clear queue status file'), |
1447 ('e', 'empty', None, 'clear queue status file'), |
1352 ('f', 'force', None, 'force copy')], |
1448 ('f', 'force', None, 'force copy')], |
1353 'hg qsave [-m TEXT] [-c] [-n NAME] [-e] [-f]'), |
1449 'hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'), |
1354 "qseries": |
1450 "qseries": |
1355 (series, |
1451 (series, |
1356 [('m', 'missing', None, 'print patches not in series')], |
1452 [('m', 'missing', None, 'print patches not in series')], |
1357 'hg qseries [-m]'), |
1453 'hg qseries [-m]'), |
1358 "^strip": |
1454 "^strip": |