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: