Mercurial > hg > mercurial-crew-with-dirclash
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() |