Mercurial > hg
comparison hgext/mq.py @ 7639:ae7a614a6a57
mq: remove import of revlog
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 12 Jan 2009 10:59:08 -0600 |
parents | 1d54e2f6c0b7 |
children | dd08e1e0cea1 |
comparison
equal
deleted
inserted
replaced
7638:f83a2b1d1a71 | 7639:ae7a614a6a57 |
---|---|
28 remove patch from applied stack qpop | 28 remove patch from applied stack qpop |
29 refresh contents of top applied patch qrefresh | 29 refresh contents of top applied patch qrefresh |
30 ''' | 30 ''' |
31 | 31 |
32 from mercurial.i18n import _ | 32 from mercurial.i18n import _ |
33 from mercurial.node import bin, hex, short | 33 from mercurial.node import bin, hex, short, nullid, nullrev |
34 from mercurial import commands, cmdutil, hg, patch, revlog, util | 34 from mercurial import commands, cmdutil, hg, patch, util |
35 from mercurial import repair, extensions, url, error | 35 from mercurial import repair, extensions, url, error |
36 import os, sys, re, errno | 36 import os, sys, re, errno |
37 | 37 |
38 commands.norepo += " qclone" | 38 commands.norepo += " qclone" |
39 | 39 |
425 return (0, n) | 425 return (0, n) |
426 | 426 |
427 def qparents(self, repo, rev=None): | 427 def qparents(self, repo, rev=None): |
428 if rev is None: | 428 if rev is None: |
429 (p1, p2) = repo.dirstate.parents() | 429 (p1, p2) = repo.dirstate.parents() |
430 if p2 == revlog.nullid: | 430 if p2 == nullid: |
431 return p1 | 431 return p1 |
432 if len(self.applied) == 0: | 432 if len(self.applied) == 0: |
433 return None | 433 return None |
434 return revlog.bin(self.applied[-1].rev) | 434 return bin(self.applied[-1].rev) |
435 pp = repo.changelog.parents(rev) | 435 pp = repo.changelog.parents(rev) |
436 if pp[1] != revlog.nullid: | 436 if pp[1] != nullid: |
437 arevs = [ x.rev for x in self.applied ] | 437 arevs = [ x.rev for x in self.applied ] |
438 p0 = revlog.hex(pp[0]) | 438 p0 = hex(pp[0]) |
439 p1 = revlog.hex(pp[1]) | 439 p1 = hex(pp[1]) |
440 if p0 in arevs: | 440 if p0 in arevs: |
441 return pp[0] | 441 return pp[0] |
442 if p1 in arevs: | 442 if p1 in arevs: |
443 return pp[1] | 443 return pp[1] |
444 return pp[0] | 444 return pp[0] |
452 # the first patch in the queue is never a merge patch | 452 # the first patch in the queue is never a merge patch |
453 # | 453 # |
454 pname = ".hg.patches.merge.marker" | 454 pname = ".hg.patches.merge.marker" |
455 n = repo.commit(None, '[mq]: merge marker', user=None, force=1) | 455 n = repo.commit(None, '[mq]: merge marker', user=None, force=1) |
456 self.removeundo(repo) | 456 self.removeundo(repo) |
457 self.applied.append(statusentry(revlog.hex(n), pname)) | 457 self.applied.append(statusentry(hex(n), pname)) |
458 self.applied_dirty = 1 | 458 self.applied_dirty = 1 |
459 | 459 |
460 head = self.qparents(repo) | 460 head = self.qparents(repo) |
461 | 461 |
462 for patch in series: | 462 for patch in series: |
470 continue | 470 continue |
471 info = mergeq.isapplied(patch) | 471 info = mergeq.isapplied(patch) |
472 if not info: | 472 if not info: |
473 self.ui.warn(_("patch %s is not applied\n") % patch) | 473 self.ui.warn(_("patch %s is not applied\n") % patch) |
474 return (1, None) | 474 return (1, None) |
475 rev = revlog.bin(info[1]) | 475 rev = bin(info[1]) |
476 (err, head) = self.mergeone(repo, mergeq, head, patch, rev) | 476 (err, head) = self.mergeone(repo, mergeq, head, patch, rev) |
477 if head: | 477 if head: |
478 self.applied.append(statusentry(revlog.hex(head), patch)) | 478 self.applied.append(statusentry(hex(head), patch)) |
479 self.applied_dirty = 1 | 479 self.applied_dirty = 1 |
480 if err: | 480 if err: |
481 return (err, head) | 481 return (err, head) |
482 self.save_dirty() | 482 self.save_dirty() |
483 return (0, head) | 483 return (0, head) |
578 | 578 |
579 if n == None: | 579 if n == None: |
580 raise util.Abort(_("repo commit failed")) | 580 raise util.Abort(_("repo commit failed")) |
581 | 581 |
582 if update_status: | 582 if update_status: |
583 self.applied.append(statusentry(revlog.hex(n), patchname)) | 583 self.applied.append(statusentry(hex(n), patchname)) |
584 | 584 |
585 if patcherr: | 585 if patcherr: |
586 if not ph.haspatch: | 586 if not ph.haspatch: |
587 self.ui.warn(_("patch %s is empty\n") % patchname) | 587 self.ui.warn(_("patch %s is empty\n") % patchname) |
588 err = 0 | 588 err = 0 |
610 appliedbase = 0 | 610 appliedbase = 0 |
611 patches = [] | 611 patches = [] |
612 for rev in util.sort(revs): | 612 for rev in util.sort(revs): |
613 if rev < firstrev: | 613 if rev < firstrev: |
614 raise util.Abort(_('revision %d is not managed') % rev) | 614 raise util.Abort(_('revision %d is not managed') % rev) |
615 base = revlog.bin(self.applied[appliedbase].rev) | 615 base = bin(self.applied[appliedbase].rev) |
616 node = repo.changelog.node(rev) | 616 node = repo.changelog.node(rev) |
617 if node != base: | 617 if node != base: |
618 raise util.Abort(_('cannot delete revision %d above ' | 618 raise util.Abort(_('cannot delete revision %d above ' |
619 'applied patches') % rev) | 619 'applied patches') % rev) |
620 patches.append(self.applied[appliedbase].name) | 620 patches.append(self.applied[appliedbase].name) |
655 revs.reverse() | 655 revs.reverse() |
656 for rev in revs: | 656 for rev in revs: |
657 if appliedbase >= len(self.applied): | 657 if appliedbase >= len(self.applied): |
658 raise util.Abort(_("revision %d is not managed") % rev) | 658 raise util.Abort(_("revision %d is not managed") % rev) |
659 | 659 |
660 base = revlog.bin(self.applied[appliedbase].rev) | 660 base = bin(self.applied[appliedbase].rev) |
661 node = repo.changelog.node(rev) | 661 node = repo.changelog.node(rev) |
662 if node != base: | 662 if node != base: |
663 raise util.Abort(_("cannot delete revision %d above " | 663 raise util.Abort(_("cannot delete revision %d above " |
664 "applied patches") % rev) | 664 "applied patches") % rev) |
665 realpatches.append(self.applied[appliedbase].name) | 665 realpatches.append(self.applied[appliedbase].name) |
678 self.applied_dirty = 1 | 678 self.applied_dirty = 1 |
679 self._clean_series(realpatches) | 679 self._clean_series(realpatches) |
680 | 680 |
681 def check_toppatch(self, repo): | 681 def check_toppatch(self, repo): |
682 if len(self.applied) > 0: | 682 if len(self.applied) > 0: |
683 top = revlog.bin(self.applied[-1].rev) | 683 top = bin(self.applied[-1].rev) |
684 pp = repo.dirstate.parents() | 684 pp = repo.dirstate.parents() |
685 if top not in pp: | 685 if top not in pp: |
686 raise util.Abort(_("working directory revision is not qtip")) | 686 raise util.Abort(_("working directory revision is not qtip")) |
687 return top | 687 return top |
688 return None | 688 return None |
748 n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True) | 748 n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True) |
749 if n == None: | 749 if n == None: |
750 raise util.Abort(_("repo commit failed")) | 750 raise util.Abort(_("repo commit failed")) |
751 try: | 751 try: |
752 self.full_series[insert:insert] = [patchfn] | 752 self.full_series[insert:insert] = [patchfn] |
753 self.applied.append(statusentry(revlog.hex(n), patchfn)) | 753 self.applied.append(statusentry(hex(n), patchfn)) |
754 self.parse_series() | 754 self.parse_series() |
755 self.series_dirty = 1 | 755 self.series_dirty = 1 |
756 self.applied_dirty = 1 | 756 self.applied_dirty = 1 |
757 if msg: | 757 if msg: |
758 msg = msg + "\n\n" | 758 msg = msg + "\n\n" |
1003 self.ui.warn(_("qpop: %s is already at the top\n") % patch) | 1003 self.ui.warn(_("qpop: %s is already at the top\n") % patch) |
1004 return | 1004 return |
1005 | 1005 |
1006 if not update: | 1006 if not update: |
1007 parents = repo.dirstate.parents() | 1007 parents = repo.dirstate.parents() |
1008 rr = [ revlog.bin(x.rev) for x in self.applied ] | 1008 rr = [ bin(x.rev) for x in self.applied ] |
1009 for p in parents: | 1009 for p in parents: |
1010 if p in rr: | 1010 if p in rr: |
1011 self.ui.warn(_("qpop: forcing dirstate update\n")) | 1011 self.ui.warn(_("qpop: forcing dirstate update\n")) |
1012 update = True | 1012 update = True |
1013 else: | 1013 else: |
1022 if not force and update: | 1022 if not force and update: |
1023 self.check_localchanges(repo) | 1023 self.check_localchanges(repo) |
1024 | 1024 |
1025 self.applied_dirty = 1 | 1025 self.applied_dirty = 1 |
1026 end = len(self.applied) | 1026 end = len(self.applied) |
1027 rev = revlog.bin(self.applied[start].rev) | 1027 rev = bin(self.applied[start].rev) |
1028 if update: | 1028 if update: |
1029 top = self.check_toppatch(repo) | 1029 top = self.check_toppatch(repo) |
1030 | 1030 |
1031 try: | 1031 try: |
1032 heads = repo.changelog.heads(rev) | 1032 heads = repo.changelog.heads(rev) |
1033 except revlog.LookupError: | 1033 except error.LookupError: |
1034 node = short(rev) | 1034 node = short(rev) |
1035 raise util.Abort(_('trying to pop unknown node %s') % node) | 1035 raise util.Abort(_('trying to pop unknown node %s') % node) |
1036 | 1036 |
1037 if heads != [revlog.bin(self.applied[-1].rev)]: | 1037 if heads != [bin(self.applied[-1].rev)]: |
1038 raise util.Abort(_("popping would remove a revision not " | 1038 raise util.Abort(_("popping would remove a revision not " |
1039 "managed by this patch queue")) | 1039 "managed by this patch queue")) |
1040 | 1040 |
1041 # we know there are no local changes, so we can make a simplified | 1041 # we know there are no local changes, so we can make a simplified |
1042 # form of hg.update. | 1042 # form of hg.update. |
1060 if e.errno != errno.ENOENT: | 1060 if e.errno != errno.ENOENT: |
1061 raise | 1061 raise |
1062 try: os.removedirs(os.path.dirname(repo.wjoin(f))) | 1062 try: os.removedirs(os.path.dirname(repo.wjoin(f))) |
1063 except: pass | 1063 except: pass |
1064 repo.dirstate.forget(f) | 1064 repo.dirstate.forget(f) |
1065 repo.dirstate.setparents(qp, revlog.nullid) | 1065 repo.dirstate.setparents(qp, nullid) |
1066 del self.applied[start:end] | 1066 del self.applied[start:end] |
1067 self.strip(repo, rev, update=False, backup='strip') | 1067 self.strip(repo, rev, update=False, backup='strip') |
1068 if len(self.applied): | 1068 if len(self.applied): |
1069 self.ui.write(_("now at: %s\n") % self.applied[-1].name) | 1069 self.ui.write(_("now at: %s\n") % self.applied[-1].name) |
1070 else: | 1070 else: |
1092 newdate = '%d %d' % util.parsedate(newdate) | 1092 newdate = '%d %d' % util.parsedate(newdate) |
1093 wlock = repo.wlock() | 1093 wlock = repo.wlock() |
1094 try: | 1094 try: |
1095 self.check_toppatch(repo) | 1095 self.check_toppatch(repo) |
1096 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name) | 1096 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name) |
1097 top = revlog.bin(top) | 1097 top = bin(top) |
1098 if repo.changelog.heads(top) != [top]: | 1098 if repo.changelog.heads(top) != [top]: |
1099 raise util.Abort(_("cannot refresh a revision with children")) | 1099 raise util.Abort(_("cannot refresh a revision with children")) |
1100 cparents = repo.changelog.parents(top) | 1100 cparents = repo.changelog.parents(top) |
1101 patchparent = self.qparents(repo, top) | 1101 patchparent = self.qparents(repo, top) |
1102 ph = self.readheaders(patchfn) | 1102 ph = self.readheaders(patchfn) |
1266 try: | 1266 try: |
1267 # might be nice to attempt to roll back strip after this | 1267 # might be nice to attempt to roll back strip after this |
1268 patchf.rename() | 1268 patchf.rename() |
1269 n = repo.commit(match.files(), message, user, ph.date, | 1269 n = repo.commit(match.files(), message, user, ph.date, |
1270 match=match, force=1) | 1270 match=match, force=1) |
1271 self.applied.append(statusentry(revlog.hex(n), patchfn)) | 1271 self.applied.append(statusentry(hex(n), patchfn)) |
1272 except: | 1272 except: |
1273 ctx = repo[cparents[0]] | 1273 ctx = repo[cparents[0]] |
1274 repo.dirstate.rebuild(ctx.node(), ctx.manifest()) | 1274 repo.dirstate.rebuild(ctx.node(), ctx.manifest()) |
1275 self.save_dirty() | 1275 self.save_dirty() |
1276 self.ui.warn(_('refresh interrupted while patch was popped! ' | 1276 self.ui.warn(_('refresh interrupted while patch was popped! ' |
1454 "\n".join(ar) + '\n' or "") | 1454 "\n".join(ar) + '\n' or "") |
1455 n = repo.commit(None, text, user=None, force=1) | 1455 n = repo.commit(None, text, user=None, force=1) |
1456 if not n: | 1456 if not n: |
1457 self.ui.warn(_("repo commit failed\n")) | 1457 self.ui.warn(_("repo commit failed\n")) |
1458 return 1 | 1458 return 1 |
1459 self.applied.append(statusentry(revlog.hex(n),'.hg.patches.save.line')) | 1459 self.applied.append(statusentry(hex(n),'.hg.patches.save.line')) |
1460 self.applied_dirty = 1 | 1460 self.applied_dirty = 1 |
1461 self.removeundo(repo) | 1461 self.removeundo(repo) |
1462 | 1462 |
1463 def full_series_end(self): | 1463 def full_series_end(self): |
1464 if len(self.applied) > 0: | 1464 if len(self.applied) > 0: |
1532 heads = repo.changelog.heads(repo.changelog.node(rev[-1])) | 1532 heads = repo.changelog.heads(repo.changelog.node(rev[-1])) |
1533 if len(heads) > 1: | 1533 if len(heads) > 1: |
1534 raise util.Abort(_('revision %d is the root of more than one ' | 1534 raise util.Abort(_('revision %d is the root of more than one ' |
1535 'branch') % rev[-1]) | 1535 'branch') % rev[-1]) |
1536 if self.applied: | 1536 if self.applied: |
1537 base = revlog.hex(repo.changelog.node(rev[0])) | 1537 base = hex(repo.changelog.node(rev[0])) |
1538 if base in [n.rev for n in self.applied]: | 1538 if base in [n.rev for n in self.applied]: |
1539 raise util.Abort(_('revision %d is already managed') | 1539 raise util.Abort(_('revision %d is already managed') |
1540 % rev[0]) | 1540 % rev[0]) |
1541 if heads != [revlog.bin(self.applied[-1].rev)]: | 1541 if heads != [bin(self.applied[-1].rev)]: |
1542 raise util.Abort(_('revision %d is not the parent of ' | 1542 raise util.Abort(_('revision %d is not the parent of ' |
1543 'the queue') % rev[0]) | 1543 'the queue') % rev[0]) |
1544 base = repo.changelog.rev(revlog.bin(self.applied[0].rev)) | 1544 base = repo.changelog.rev(bin(self.applied[0].rev)) |
1545 lastparent = repo.changelog.parentrevs(base)[0] | 1545 lastparent = repo.changelog.parentrevs(base)[0] |
1546 else: | 1546 else: |
1547 if heads != [repo.changelog.node(rev[0])]: | 1547 if heads != [repo.changelog.node(rev[0])]: |
1548 raise util.Abort(_('revision %d has unmanaged children') | 1548 raise util.Abort(_('revision %d has unmanaged children') |
1549 % rev[0]) | 1549 % rev[0]) |
1553 self.diffopts().git = True | 1553 self.diffopts().git = True |
1554 | 1554 |
1555 for r in rev: | 1555 for r in rev: |
1556 p1, p2 = repo.changelog.parentrevs(r) | 1556 p1, p2 = repo.changelog.parentrevs(r) |
1557 n = repo.changelog.node(r) | 1557 n = repo.changelog.node(r) |
1558 if p2 != revlog.nullrev: | 1558 if p2 != nullrev: |
1559 raise util.Abort(_('cannot import merge revision %d') % r) | 1559 raise util.Abort(_('cannot import merge revision %d') % r) |
1560 if lastparent and lastparent != r: | 1560 if lastparent and lastparent != r: |
1561 raise util.Abort(_('revision %d is not the parent of %d') | 1561 raise util.Abort(_('revision %d is not the parent of %d') |
1562 % (r, lastparent)) | 1562 % (r, lastparent)) |
1563 lastparent = p1 | 1563 lastparent = p1 |
1571 | 1571 |
1572 patchf = self.opener(patchname, "w") | 1572 patchf = self.opener(patchname, "w") |
1573 patch.export(repo, [n], fp=patchf, opts=self.diffopts()) | 1573 patch.export(repo, [n], fp=patchf, opts=self.diffopts()) |
1574 patchf.close() | 1574 patchf.close() |
1575 | 1575 |
1576 se = statusentry(revlog.hex(n), patchname) | 1576 se = statusentry(hex(n), patchname) |
1577 self.applied.insert(0, se) | 1577 self.applied.insert(0, se) |
1578 | 1578 |
1579 added.append(patchname) | 1579 added.append(patchname) |
1580 patchname = None | 1580 patchname = None |
1581 self.parse_series() | 1581 self.parse_series() |
1744 raise util.Abort(_('versioned patch repository not found' | 1744 raise util.Abort(_('versioned patch repository not found' |
1745 ' (see qinit -c)')) | 1745 ' (see qinit -c)')) |
1746 qbase, destrev = None, None | 1746 qbase, destrev = None, None |
1747 if sr.local(): | 1747 if sr.local(): |
1748 if sr.mq.applied: | 1748 if sr.mq.applied: |
1749 qbase = revlog.bin(sr.mq.applied[0].rev) | 1749 qbase = bin(sr.mq.applied[0].rev) |
1750 if not hg.islocal(dest): | 1750 if not hg.islocal(dest): |
1751 heads = dict.fromkeys(sr.heads()) | 1751 heads = dict.fromkeys(sr.heads()) |
1752 for h in sr.heads(qbase): | 1752 for h in sr.heads(qbase): |
1753 del heads[h] | 1753 del heads[h] |
1754 destrev = heads.keys() | 1754 destrev = heads.keys() |
2219 | 2219 |
2220 rev = repo.lookup(rev) | 2220 rev = repo.lookup(rev) |
2221 p = repo.dirstate.parents() | 2221 p = repo.dirstate.parents() |
2222 cl = repo.changelog | 2222 cl = repo.changelog |
2223 update = True | 2223 update = True |
2224 if p[0] == revlog.nullid: | 2224 if p[0] == nullid: |
2225 update = False | 2225 update = False |
2226 elif p[1] == revlog.nullid and rev != cl.ancestor(p[0], rev): | 2226 elif p[1] == nullid and rev != cl.ancestor(p[0], rev): |
2227 update = False | 2227 update = False |
2228 elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)): | 2228 elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)): |
2229 update = False | 2229 update = False |
2230 | 2230 |
2231 repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force']) | 2231 repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force']) |
2364 | 2364 |
2365 def reposetup(ui, repo): | 2365 def reposetup(ui, repo): |
2366 class mqrepo(repo.__class__): | 2366 class mqrepo(repo.__class__): |
2367 def abort_if_wdir_patched(self, errmsg, force=False): | 2367 def abort_if_wdir_patched(self, errmsg, force=False): |
2368 if self.mq.applied and not force: | 2368 if self.mq.applied and not force: |
2369 parent = revlog.hex(self.dirstate.parents()[0]) | 2369 parent = hex(self.dirstate.parents()[0]) |
2370 if parent in [s.rev for s in self.mq.applied]: | 2370 if parent in [s.rev for s in self.mq.applied]: |
2371 raise util.Abort(errmsg) | 2371 raise util.Abort(errmsg) |
2372 | 2372 |
2373 def commit(self, *args, **opts): | 2373 def commit(self, *args, **opts): |
2374 if len(args) >= 6: | 2374 if len(args) >= 6: |
2394 | 2394 |
2395 q = self.mq | 2395 q = self.mq |
2396 if not q.applied: | 2396 if not q.applied: |
2397 return tagscache | 2397 return tagscache |
2398 | 2398 |
2399 mqtags = [(revlog.bin(patch.rev), patch.name) for patch in q.applied] | 2399 mqtags = [(bin(patch.rev), patch.name) for patch in q.applied] |
2400 | 2400 |
2401 if mqtags[-1][0] not in self.changelog.nodemap: | 2401 if mqtags[-1][0] not in self.changelog.nodemap: |
2402 self.ui.warn(_('mq status file refers to unknown node %s\n') | 2402 self.ui.warn(_('mq status file refers to unknown node %s\n') |
2403 % revlog.short(mqtags[-1][0])) | 2403 % short(mqtags[-1][0])) |
2404 return tagscache | 2404 return tagscache |
2405 | 2405 |
2406 mqtags.append((mqtags[-1][0], 'qtip')) | 2406 mqtags.append((mqtags[-1][0], 'qtip')) |
2407 mqtags.append((mqtags[0][0], 'qbase')) | 2407 mqtags.append((mqtags[0][0], 'qbase')) |
2408 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent')) | 2408 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent')) |
2419 q = self.mq | 2419 q = self.mq |
2420 if not q.applied: | 2420 if not q.applied: |
2421 return super(mqrepo, self)._branchtags(partial, lrev) | 2421 return super(mqrepo, self)._branchtags(partial, lrev) |
2422 | 2422 |
2423 cl = self.changelog | 2423 cl = self.changelog |
2424 qbasenode = revlog.bin(q.applied[0].rev) | 2424 qbasenode = bin(q.applied[0].rev) |
2425 if qbasenode not in cl.nodemap: | 2425 if qbasenode not in cl.nodemap: |
2426 self.ui.warn(_('mq status file refers to unknown node %s\n') | 2426 self.ui.warn(_('mq status file refers to unknown node %s\n') |
2427 % revlog.short(qbasenode)) | 2427 % short(qbasenode)) |
2428 return super(mqrepo, self)._branchtags(partial, lrev) | 2428 return super(mqrepo, self)._branchtags(partial, lrev) |
2429 | 2429 |
2430 qbase = cl.rev(qbasenode) | 2430 qbase = cl.rev(qbasenode) |
2431 start = lrev + 1 | 2431 start = lrev + 1 |
2432 if start < qbase: | 2432 if start < qbase: |