comparison hgext/mq.py @ 2696:be273f6074de

mq: patch naming shortcuts This adds some more options to the mq lookup routine. It allows you to use shortcuts in naming patches to push or pop. You can now use: 1) a full patch name 2) a number to indicate an offset in the series file 3) a unique substring of the patch name 4) patchname[-+]num to indicate an offset from a given patch. For case #3 substrings are allowed. qtip and qbase are aliases for the top and bottom of the applied patch queue, unless they are already in the series file as patch names.
author Chris Mason <mason@suse.com>
date Thu, 27 Jul 2006 09:27:35 -0700
parents 0fb28dbf0dc7
children 6c540dd14c38
comparison
equal deleted inserted replaced
2695:c995d68333cf 2696:be273f6074de
255 self.applied_dirty = 1 255 self.applied_dirty = 1
256 256
257 head = self.qparents(repo) 257 head = self.qparents(repo)
258 258
259 for patch in series: 259 for patch in series:
260 patch = mergeq.lookup(patch) 260 patch = mergeq.lookup(patch, strict=True)
261 if not patch: 261 if not patch:
262 self.ui.warn("patch %s does not exist\n" % patch) 262 self.ui.warn("patch %s does not exist\n" % patch)
263 return (1, None) 263 return (1, None)
264 264
265 info = mergeq.isapplied(patch) 265 info = mergeq.isapplied(patch)
378 tr.close() 378 tr.close()
379 os.chdir(pwd) 379 os.chdir(pwd)
380 return (err, n) 380 return (err, n)
381 381
382 def delete(self, repo, patch): 382 def delete(self, repo, patch):
383 patch = self.lookup(patch) 383 patch = self.lookup(patch, strict=True)
384 info = self.isapplied(patch) 384 info = self.isapplied(patch)
385 if info: 385 if info:
386 self.ui.warn("cannot delete applied patch %s\n" % patch) 386 self.ui.warn("cannot delete applied patch %s\n" % patch)
387 sys.exit(1) 387 sys.exit(1)
388 if patch not in self.series: 388 if patch not in self.series:
596 a = p.split(':') 596 a = p.split(':')
597 if a[1] == patch: 597 if a[1] == patch:
598 return (i, a[0], a[1]) 598 return (i, a[0], a[1])
599 return None 599 return None
600 600
601 def lookup(self, patch): 601 # if the exact patch name does not exist, we try a few
602 # variations. If strict is passed, we try only #1
603 #
604 # 1) a number to indicate an offset in the series file
605 # 2) a unique substring of the patch name was given
606 # 3) patchname[-+]num to indicate an offset in the series file
607 def lookup(self, patch, strict=False):
608 def partial_name(s):
609 count = 0
610 if s in self.series:
611 return s
612 for x in self.series:
613 if s in x:
614 count += 1
615 last = x
616 if count > 1:
617 return None
618 if count:
619 return last
620 if len(self.series) > 0 and len(self.applied) > 0:
621 if s == 'qtip':
622 return self.series[self.series_end()-1]
623 if s == 'qbase':
624 return self.series[0]
625 return None
602 if patch == None: 626 if patch == None:
603 return None 627 return None
604 if patch in self.series: 628
605 return patch 629 # we don't want to return a partial match until we make
630 # sure the file name passed in does not exist (checked below)
631 res = partial_name(patch)
632 if res and res == patch:
633 return res
634
606 if not os.path.isfile(os.path.join(self.path, patch)): 635 if not os.path.isfile(os.path.join(self.path, patch)):
607 try: 636 try:
608 sno = int(patch) 637 sno = int(patch)
609 except(ValueError, OverflowError): 638 except(ValueError, OverflowError):
610 self.ui.warn("patch %s not in series\n" % patch) 639 pass
611 sys.exit(1) 640 else:
612 if sno >= len(self.series): 641 if sno < len(self.series):
613 self.ui.warn("patch number %d is out of range\n" % sno) 642 patch = self.series[sno]
614 sys.exit(1) 643 return patch
615 patch = self.series[sno] 644 if not strict:
616 else: 645 # return any partial match made above
617 self.ui.warn("patch %s not in series\n" % patch) 646 if res:
618 sys.exit(1) 647 return res
619 return patch 648 minus = patch.rsplit('-', 1)
649 if len(minus) > 1:
650 res = partial_name(minus[0])
651 if res:
652 i = self.series.index(res)
653 try:
654 off = int(minus[1] or 1)
655 except(ValueError, OverflowError):
656 pass
657 else:
658 if i - off >= 0:
659 return self.series[i - off]
660 plus = patch.rsplit('+', 1)
661 if len(plus) > 1:
662 res = partial_name(plus[0])
663 if res:
664 i = self.series.index(res)
665 try:
666 off = int(plus[1] or 1)
667 except(ValueError, OverflowError):
668 pass
669 else:
670 if i + off < len(self.series):
671 return self.series[i + off]
672 self.ui.warn("patch %s not in series\n" % patch)
673 sys.exit(1)
620 674
621 def push(self, repo, patch=None, force=False, list=False, 675 def push(self, repo, patch=None, force=False, list=False,
622 mergeq=None, wlock=None): 676 mergeq=None, wlock=None):
623 if not wlock: 677 if not wlock:
624 wlock = repo.wlock() 678 wlock = repo.wlock()