Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revset.py @ 28424:534f968d33e5
revset: add inspection data to all filter() calls
This is useful for debugging revset construction.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 13 Feb 2016 20:05:57 +0900 |
parents | 0d79d91ba7e3 |
children | 02d7faaf455c |
comparison
equal
deleted
inserted
replaced
28423:0d79d91ba7e3 | 28424:534f968d33e5 |
---|---|
598 """Alias for ``user(string)``. | 598 """Alias for ``user(string)``. |
599 """ | 599 """ |
600 # i18n: "author" is a keyword | 600 # i18n: "author" is a keyword |
601 n = encoding.lower(getstring(x, _("author requires a string"))) | 601 n = encoding.lower(getstring(x, _("author requires a string"))) |
602 kind, pattern, matcher = _substringmatcher(n) | 602 kind, pattern, matcher = _substringmatcher(n) |
603 return subset.filter(lambda x: matcher(encoding.lower(repo[x].user()))) | 603 return subset.filter(lambda x: matcher(encoding.lower(repo[x].user())), |
604 condrepr=('<user %r>', n)) | |
604 | 605 |
605 @predicate('bisect(string)', safe=True) | 606 @predicate('bisect(string)', safe=True) |
606 def bisect(repo, subset, x): | 607 def bisect(repo, subset, x): |
607 """Changesets marked in the specified bisect status: | 608 """Changesets marked in the specified bisect status: |
608 | 609 |
684 kind, pattern, matcher = util.stringmatcher(b) | 685 kind, pattern, matcher = util.stringmatcher(b) |
685 if kind == 'literal': | 686 if kind == 'literal': |
686 # note: falls through to the revspec case if no branch with | 687 # note: falls through to the revspec case if no branch with |
687 # this name exists and pattern kind is not specified explicitly | 688 # this name exists and pattern kind is not specified explicitly |
688 if pattern in repo.branchmap(): | 689 if pattern in repo.branchmap(): |
689 return subset.filter(lambda r: matcher(getbi(r)[0])) | 690 return subset.filter(lambda r: matcher(getbi(r)[0]), |
691 condrepr=('<branch %r>', b)) | |
690 if b.startswith('literal:'): | 692 if b.startswith('literal:'): |
691 raise error.RepoLookupError(_("branch '%s' does not exist") | 693 raise error.RepoLookupError(_("branch '%s' does not exist") |
692 % pattern) | 694 % pattern) |
693 else: | 695 else: |
694 return subset.filter(lambda r: matcher(getbi(r)[0])) | 696 return subset.filter(lambda r: matcher(getbi(r)[0]), |
697 condrepr=('<branch %r>', b)) | |
695 | 698 |
696 s = getset(repo, fullreposet(repo), x) | 699 s = getset(repo, fullreposet(repo), x) |
697 b = set() | 700 b = set() |
698 for r in s: | 701 for r in s: |
699 b.add(getbi(r)[0]) | 702 b.add(getbi(r)[0]) |
700 c = s.__contains__ | 703 c = s.__contains__ |
701 return subset.filter(lambda r: c(r) or getbi(r)[0] in b) | 704 return subset.filter(lambda r: c(r) or getbi(r)[0] in b, |
705 condrepr=lambda: '<branch %r>' % sorted(b)) | |
702 | 706 |
703 @predicate('bumped()', safe=True) | 707 @predicate('bumped()', safe=True) |
704 def bumped(repo, subset, x): | 708 def bumped(repo, subset, x): |
705 """Mutable changesets marked as successors of public changesets. | 709 """Mutable changesets marked as successors of public changesets. |
706 | 710 |
751 else: | 755 else: |
752 for f in files: | 756 for f in files: |
753 if m(f): | 757 if m(f): |
754 return True | 758 return True |
755 | 759 |
756 return subset.filter(matches) | 760 return subset.filter(matches, condrepr=('<status[%r] %r>', field, pat)) |
757 | 761 |
758 def _children(repo, narrow, parentset): | 762 def _children(repo, narrow, parentset): |
759 if not parentset: | 763 if not parentset: |
760 return baseset() | 764 return baseset() |
761 cs = set() | 765 cs = set() |
783 def closed(repo, subset, x): | 787 def closed(repo, subset, x): |
784 """Changeset is closed. | 788 """Changeset is closed. |
785 """ | 789 """ |
786 # i18n: "closed" is a keyword | 790 # i18n: "closed" is a keyword |
787 getargs(x, 0, 0, _("closed takes no arguments")) | 791 getargs(x, 0, 0, _("closed takes no arguments")) |
788 return subset.filter(lambda r: repo[r].closesbranch()) | 792 return subset.filter(lambda r: repo[r].closesbranch(), |
793 condrepr='<branch closed>') | |
789 | 794 |
790 @predicate('contains(pattern)') | 795 @predicate('contains(pattern)') |
791 def contains(repo, subset, x): | 796 def contains(repo, subset, x): |
792 """The revision's manifest contains a file matching pattern (but might not | 797 """The revision's manifest contains a file matching pattern (but might not |
793 modify it). See :hg:`help patterns` for information about file patterns. | 798 modify it). See :hg:`help patterns` for information about file patterns. |
810 for f in c.manifest(): | 815 for f in c.manifest(): |
811 if m(f): | 816 if m(f): |
812 return True | 817 return True |
813 return False | 818 return False |
814 | 819 |
815 return subset.filter(matches) | 820 return subset.filter(matches, condrepr=('<contains %r>', pat)) |
816 | 821 |
817 @predicate('converted([id])', safe=True) | 822 @predicate('converted([id])', safe=True) |
818 def converted(repo, subset, x): | 823 def converted(repo, subset, x): |
819 """Changesets converted from the given identifier in the old repository if | 824 """Changesets converted from the given identifier in the old repository if |
820 present, or all converted changesets if no identifier is specified. | 825 present, or all converted changesets if no identifier is specified. |
832 | 837 |
833 def _matchvalue(r): | 838 def _matchvalue(r): |
834 source = repo[r].extra().get('convert_revision', None) | 839 source = repo[r].extra().get('convert_revision', None) |
835 return source is not None and (rev is None or source.startswith(rev)) | 840 return source is not None and (rev is None or source.startswith(rev)) |
836 | 841 |
837 return subset.filter(lambda r: _matchvalue(r)) | 842 return subset.filter(lambda r: _matchvalue(r), |
843 condrepr=('<converted %r>', rev)) | |
838 | 844 |
839 @predicate('date(interval)', safe=True) | 845 @predicate('date(interval)', safe=True) |
840 def date(repo, subset, x): | 846 def date(repo, subset, x): |
841 """Changesets within the interval, see :hg:`help dates`. | 847 """Changesets within the interval, see :hg:`help dates`. |
842 """ | 848 """ |
843 # i18n: "date" is a keyword | 849 # i18n: "date" is a keyword |
844 ds = getstring(x, _("date requires a string")) | 850 ds = getstring(x, _("date requires a string")) |
845 dm = util.matchdate(ds) | 851 dm = util.matchdate(ds) |
846 return subset.filter(lambda x: dm(repo[x].date()[0])) | 852 return subset.filter(lambda x: dm(repo[x].date()[0]), |
853 condrepr=('<date %r>', ds)) | |
847 | 854 |
848 @predicate('desc(string)', safe=True) | 855 @predicate('desc(string)', safe=True) |
849 def desc(repo, subset, x): | 856 def desc(repo, subset, x): |
850 """Search commit message for string. The match is case-insensitive. | 857 """Search commit message for string. The match is case-insensitive. |
851 """ | 858 """ |
854 | 861 |
855 def matches(x): | 862 def matches(x): |
856 c = repo[x] | 863 c = repo[x] |
857 return ds in encoding.lower(c.description()) | 864 return ds in encoding.lower(c.description()) |
858 | 865 |
859 return subset.filter(matches) | 866 return subset.filter(matches, condrepr=('<desc %r>', ds)) |
860 | 867 |
861 def _descendants(repo, subset, x, followfirst=False): | 868 def _descendants(repo, subset, x, followfirst=False): |
862 roots = getset(repo, fullreposet(repo), x) | 869 roots = getset(repo, fullreposet(repo), x) |
863 if not roots: | 870 if not roots: |
864 return baseset() | 871 return baseset() |
929 break | 936 break |
930 | 937 |
931 r = src | 938 r = src |
932 src = _getrevsource(repo, r) | 939 src = _getrevsource(repo, r) |
933 | 940 |
934 return subset.filter(dests.__contains__) | 941 return subset.filter(dests.__contains__, |
942 condrepr=lambda: '<destination %r>' % sorted(dests)) | |
935 | 943 |
936 @predicate('divergent()', safe=True) | 944 @predicate('divergent()', safe=True) |
937 def divergent(repo, subset, x): | 945 def divergent(repo, subset, x): |
938 """ | 946 """ |
939 Final successors of changesets with an alternative set of final successors. | 947 Final successors of changesets with an alternative set of final successors. |
978 | 986 |
979 def _matchvalue(r): | 987 def _matchvalue(r): |
980 extra = repo[r].extra() | 988 extra = repo[r].extra() |
981 return label in extra and (value is None or matcher(extra[label])) | 989 return label in extra and (value is None or matcher(extra[label])) |
982 | 990 |
983 return subset.filter(lambda r: _matchvalue(r)) | 991 return subset.filter(lambda r: _matchvalue(r), |
992 condrepr=('<extra[%r] %r>', label, value)) | |
984 | 993 |
985 @predicate('filelog(pattern)', safe=True) | 994 @predicate('filelog(pattern)', safe=True) |
986 def filelog(repo, subset, x): | 995 def filelog(repo, subset, x): |
987 """Changesets connected to the specified filelog. | 996 """Changesets connected to the specified filelog. |
988 | 997 |
1116 for e in c.files() + [c.user(), c.description()]: | 1125 for e in c.files() + [c.user(), c.description()]: |
1117 if gr.search(e): | 1126 if gr.search(e): |
1118 return True | 1127 return True |
1119 return False | 1128 return False |
1120 | 1129 |
1121 return subset.filter(matches) | 1130 return subset.filter(matches, condrepr=('<grep %r>', gr.pattern)) |
1122 | 1131 |
1123 @predicate('_matchfiles', safe=True) | 1132 @predicate('_matchfiles', safe=True) |
1124 def _matchfiles(repo, subset, x): | 1133 def _matchfiles(repo, subset, x): |
1125 # _matchfiles takes a revset list of prefixed arguments: | 1134 # _matchfiles takes a revset list of prefixed arguments: |
1126 # | 1135 # |
1177 for f in files: | 1186 for f in files: |
1178 if m(f): | 1187 if m(f): |
1179 return True | 1188 return True |
1180 return False | 1189 return False |
1181 | 1190 |
1182 return subset.filter(matches) | 1191 return subset.filter(matches, |
1192 condrepr=('<matchfiles patterns=%r, include=%r ' | |
1193 'exclude=%r, default=%r, rev=%r>', | |
1194 pats, inc, exc, default, rev)) | |
1183 | 1195 |
1184 @predicate('file(pattern)', safe=True) | 1196 @predicate('file(pattern)', safe=True) |
1185 def hasfile(repo, subset, x): | 1197 def hasfile(repo, subset, x): |
1186 """Changesets affecting files matched by pattern. | 1198 """Changesets affecting files matched by pattern. |
1187 | 1199 |
1238 def matches(r): | 1250 def matches(r): |
1239 c = repo[r] | 1251 c = repo[r] |
1240 return any(kw in encoding.lower(t) | 1252 return any(kw in encoding.lower(t) |
1241 for t in c.files() + [c.user(), c.description()]) | 1253 for t in c.files() + [c.user(), c.description()]) |
1242 | 1254 |
1243 return subset.filter(matches) | 1255 return subset.filter(matches, condrepr=('<keyword %r>', kw)) |
1244 | 1256 |
1245 @predicate('limit(set[, n[, offset]])', safe=True) | 1257 @predicate('limit(set[, n[, offset]])', safe=True) |
1246 def limit(repo, subset, x): | 1258 def limit(repo, subset, x): |
1247 """First n members of set, defaulting to 1, starting from offset. | 1259 """First n members of set, defaulting to 1, starting from offset. |
1248 """ | 1260 """ |
1324 """Changeset is a merge changeset. | 1336 """Changeset is a merge changeset. |
1325 """ | 1337 """ |
1326 # i18n: "merge" is a keyword | 1338 # i18n: "merge" is a keyword |
1327 getargs(x, 0, 0, _("merge takes no arguments")) | 1339 getargs(x, 0, 0, _("merge takes no arguments")) |
1328 cl = repo.changelog | 1340 cl = repo.changelog |
1329 return subset.filter(lambda r: cl.parentrevs(r)[1] != -1) | 1341 return subset.filter(lambda r: cl.parentrevs(r)[1] != -1, |
1342 condrepr='<merge>') | |
1330 | 1343 |
1331 @predicate('branchpoint()', safe=True) | 1344 @predicate('branchpoint()', safe=True) |
1332 def branchpoint(repo, subset, x): | 1345 def branchpoint(repo, subset, x): |
1333 """Changesets with more than one child. | 1346 """Changesets with more than one child. |
1334 """ | 1347 """ |
1343 parentscount = [0]*(len(repo) - baserev) | 1356 parentscount = [0]*(len(repo) - baserev) |
1344 for r in cl.revs(start=baserev + 1): | 1357 for r in cl.revs(start=baserev + 1): |
1345 for p in cl.parentrevs(r): | 1358 for p in cl.parentrevs(r): |
1346 if p >= baserev: | 1359 if p >= baserev: |
1347 parentscount[p - baserev] += 1 | 1360 parentscount[p - baserev] += 1 |
1348 return subset.filter(lambda r: parentscount[r - baserev] > 1) | 1361 return subset.filter(lambda r: parentscount[r - baserev] > 1, |
1362 condrepr='<branchpoint>') | |
1349 | 1363 |
1350 @predicate('min(set)', safe=True) | 1364 @predicate('min(set)', safe=True) |
1351 def minrev(repo, subset, x): | 1365 def minrev(repo, subset, x): |
1352 """Changeset with lowest revision number in set. | 1366 """Changeset with lowest revision number in set. |
1353 """ | 1367 """ |
1600 s.sort() # set are non ordered, so we enforce ascending | 1614 s.sort() # set are non ordered, so we enforce ascending |
1601 return subset & s | 1615 return subset & s |
1602 else: | 1616 else: |
1603 phase = repo._phasecache.phase | 1617 phase = repo._phasecache.phase |
1604 condition = lambda r: phase(repo, r) == target | 1618 condition = lambda r: phase(repo, r) == target |
1605 return subset.filter(condition, cache=False) | 1619 return subset.filter(condition, condrepr=('<phase %r>', target), |
1620 cache=False) | |
1606 | 1621 |
1607 @predicate('draft()', safe=True) | 1622 @predicate('draft()', safe=True) |
1608 def draft(repo, subset, x): | 1623 def draft(repo, subset, x): |
1609 """Changeset in draft phase.""" | 1624 """Changeset in draft phase.""" |
1610 # i18n: "draft" is a keyword | 1625 # i18n: "draft" is a keyword |
1673 return subset & s | 1688 return subset & s |
1674 else: | 1689 else: |
1675 phase = repo._phasecache.phase | 1690 phase = repo._phasecache.phase |
1676 target = phases.public | 1691 target = phases.public |
1677 condition = lambda r: phase(repo, r) != target | 1692 condition = lambda r: phase(repo, r) != target |
1678 return subset.filter(condition, cache=False) | 1693 return subset.filter(condition, condrepr=('<phase %r>', target), |
1694 cache=False) | |
1679 | 1695 |
1680 @predicate('public()', safe=True) | 1696 @predicate('public()', safe=True) |
1681 def public(repo, subset, x): | 1697 def public(repo, subset, x): |
1682 """Changeset in public phase.""" | 1698 """Changeset in public phase.""" |
1683 # i18n: "public" is a keyword | 1699 # i18n: "public" is a keyword |
1684 getargs(x, 0, 0, _("public takes no arguments")) | 1700 getargs(x, 0, 0, _("public takes no arguments")) |
1685 phase = repo._phasecache.phase | 1701 phase = repo._phasecache.phase |
1686 target = phases.public | 1702 target = phases.public |
1687 condition = lambda r: phase(repo, r) == target | 1703 condition = lambda r: phase(repo, r) == target |
1688 return subset.filter(condition, cache=False) | 1704 return subset.filter(condition, condrepr=('<phase %r>', target), |
1705 cache=False) | |
1689 | 1706 |
1690 @predicate('remote([id [,path]])', safe=True) | 1707 @predicate('remote([id [,path]])', safe=True) |
1691 def remote(repo, subset, x): | 1708 def remote(repo, subset, x): |
1692 """Local revision that corresponds to the given identifier in a | 1709 """Local revision that corresponds to the given identifier in a |
1693 remote repository, if present. Here, the '.' identifier is a | 1710 remote repository, if present. Here, the '.' identifier is a |
1858 match = False | 1875 match = False |
1859 if match: | 1876 if match: |
1860 return True | 1877 return True |
1861 return False | 1878 return False |
1862 | 1879 |
1863 return subset.filter(matches) | 1880 return subset.filter(matches, condrepr=('<matching%r %r>', fields, revs)) |
1864 | 1881 |
1865 @predicate('reverse(set)', safe=True) | 1882 @predicate('reverse(set)', safe=True) |
1866 def reverse(repo, subset, x): | 1883 def reverse(repo, subset, x): |
1867 """Reverse order of set. | 1884 """Reverse order of set. |
1868 """ | 1885 """ |
1879 def filter(r): | 1896 def filter(r): |
1880 for p in parents(r): | 1897 for p in parents(r): |
1881 if 0 <= p and p in s: | 1898 if 0 <= p and p in s: |
1882 return False | 1899 return False |
1883 return True | 1900 return True |
1884 return subset & s.filter(filter) | 1901 return subset & s.filter(filter, condrepr='<roots>') |
1885 | 1902 |
1886 @predicate('sort(set[, [-]key...])', safe=True) | 1903 @predicate('sort(set[, [-]key...])', safe=True) |
1887 def sort(repo, subset, x): | 1904 def sort(repo, subset, x): |
1888 """Sort set by keys. The default sort order is ascending, specify a key | 1905 """Sort set by keys. The default sort order is ascending, specify a key |
1889 as ``-key`` to sort in descending order. | 1906 as ``-key`` to sort in descending order. |
1986 if s.removed: | 2003 if s.removed: |
1987 return any(submatches(c.p1().substate.keys())) | 2004 return any(submatches(c.p1().substate.keys())) |
1988 | 2005 |
1989 return False | 2006 return False |
1990 | 2007 |
1991 return subset.filter(matches) | 2008 return subset.filter(matches, condrepr=('<subrepo %r>', pat)) |
1992 | 2009 |
1993 def _substringmatcher(pattern): | 2010 def _substringmatcher(pattern): |
1994 kind, pattern, matcher = util.stringmatcher(pattern) | 2011 kind, pattern, matcher = util.stringmatcher(pattern) |
1995 if kind == 'literal': | 2012 if kind == 'literal': |
1996 matcher = lambda s: pattern in s | 2013 matcher = lambda s: pattern in s |