Show More
@@ -174,7 +174,7 def revrange(repo, revs): | |||
|
174 | 174 | pass |
|
175 | 175 | |
|
176 | 176 | # fall through to new-style queries if old-style fails |
|
177 | m = revset.match(spec) | |
|
177 | m = revset.match(repo.ui, spec) | |
|
178 | 178 | for r in m(repo, range(len(repo))): |
|
179 | 179 | if r not in seen: |
|
180 | 180 | l.append(r) |
@@ -1296,7 +1296,10 def debugrevspec(ui, repo, expr): | |||
|
1296 | 1296 | if ui.verbose: |
|
1297 | 1297 | tree = revset.parse(expr)[0] |
|
1298 | 1298 | ui.note(tree, "\n") |
|
1299 | func = revset.match(expr) | |
|
1299 | newtree = revset.findaliases(ui, tree) | |
|
1300 | if newtree != tree: | |
|
1301 | ui.note(newtree, "\n") | |
|
1302 | func = revset.match(ui, expr) | |
|
1300 | 1303 | for c in func(repo, range(len(repo))): |
|
1301 | 1304 | ui.write("%s\n" % c) |
|
1302 | 1305 |
@@ -61,6 +61,26 The following predicates are supported: | |||
|
61 | 61 | |
|
62 | 62 | .. predicatesmarker |
|
63 | 63 | |
|
64 | New predicates (known as "aliases") can be defined, using any combination of | |
|
65 | existing predicates or other aliases. An alias definition looks like:: | |
|
66 | ||
|
67 | <alias> = <definition> | |
|
68 | ||
|
69 | in the ``revsetalias`` section of ``.hgrc``. Arguments of the form `$1`, `$2`, | |
|
70 | etc. are substituted from the alias into the definition. | |
|
71 | ||
|
72 | For example, | |
|
73 | ||
|
74 | :: | |
|
75 | ||
|
76 | [revsetalias] | |
|
77 | h = heads() | |
|
78 | d($1) = sort($1, date) | |
|
79 | rs($1, $2) = reverse(sort($1, $2)) | |
|
80 | ||
|
81 | defines three aliases, ``h``, ``d``, and ``rs``. ``rs(0:tip, author)`` is | |
|
82 | exactly equivalent to ``reverse(sort(0:tip, author))``. | |
|
83 | ||
|
64 | 84 | Command line equivalents for :hg:`log`:: |
|
65 | 85 | |
|
66 | 86 | -f -> ::. |
@@ -889,14 +889,89 def optimize(x, small): | |||
|
889 | 889 | return w + wa, (op, x[1], ta) |
|
890 | 890 | return 1, x |
|
891 | 891 | |
|
892 | class revsetalias(object): | |
|
893 | funcre = re.compile('^([^(]+)\(([^)]+)\)$') | |
|
894 | args = () | |
|
895 | ||
|
896 | def __init__(self, token, value): | |
|
897 | '''Aliases like: | |
|
898 | ||
|
899 | h = heads(default) | |
|
900 | b($1) = ancestors($1) - ancestors(default) | |
|
901 | ''' | |
|
902 | if isinstance(token, tuple): | |
|
903 | self.type, self.name = token | |
|
904 | else: | |
|
905 | m = self.funcre.search(token) | |
|
906 | if m: | |
|
907 | self.type = 'func' | |
|
908 | self.name = m.group(1) | |
|
909 | self.args = [x.strip() for x in m.group(2).split(',')] | |
|
910 | else: | |
|
911 | self.type = 'symbol' | |
|
912 | self.name = token | |
|
913 | ||
|
914 | if isinstance(value, str): | |
|
915 | for arg in self.args: | |
|
916 | value = value.replace(arg, repr(arg)) | |
|
917 | self.replacement, pos = parse(value) | |
|
918 | if pos != len(value): | |
|
919 | raise error.ParseError('invalid token', pos) | |
|
920 | else: | |
|
921 | self.replacement = value | |
|
922 | ||
|
923 | def match(self, tree): | |
|
924 | if not tree: | |
|
925 | return False | |
|
926 | if tree == (self.type, self.name): | |
|
927 | return True | |
|
928 | if tree[0] != self.type: | |
|
929 | return False | |
|
930 | if len(tree) > 1 and tree[1] != ('symbol', self.name): | |
|
931 | return False | |
|
932 | # 'func' + funcname + args | |
|
933 | if ((self.args and len(tree) != 3) or | |
|
934 | (len(self.args) == 1 and tree[2][0] == 'list') or | |
|
935 | (len(self.args) > 1 and (tree[2][0] != 'list' or | |
|
936 | len(tree[2]) - 1 != len(self.args)))): | |
|
937 | raise error.ParseError('invalid amount of arguments', len(tree) - 2) | |
|
938 | return True | |
|
939 | ||
|
940 | def replace(self, tree): | |
|
941 | if tree == (self.type, self.name): | |
|
942 | return self.replacement | |
|
943 | result = self.replacement | |
|
944 | def getsubtree(i): | |
|
945 | if tree[2][0] == 'list': | |
|
946 | return tree[2][i + 1] | |
|
947 | return tree[i + 2] | |
|
948 | for i, v in enumerate(self.args): | |
|
949 | valalias = revsetalias(('string', v), getsubtree(i)) | |
|
950 | result = valalias.process(result) | |
|
951 | return result | |
|
952 | ||
|
953 | def process(self, tree): | |
|
954 | if self.match(tree): | |
|
955 | return self.replace(tree) | |
|
956 | if isinstance(tree, tuple): | |
|
957 | return tuple(map(self.process, tree)) | |
|
958 | return tree | |
|
959 | ||
|
960 | def findaliases(ui, tree): | |
|
961 | for k, v in ui.configitems('revsetalias'): | |
|
962 | alias = revsetalias(k, v) | |
|
963 | tree = alias.process(tree) | |
|
964 | return tree | |
|
965 | ||
|
892 | 966 | parse = parser.parser(tokenize, elements).parse |
|
893 | 967 | |
|
894 | def match(spec): | |
|
968 | def match(ui, spec): | |
|
895 | 969 | if not spec: |
|
896 | 970 | raise error.ParseError(_("empty query")) |
|
897 | 971 | tree, pos = parse(spec) |
|
898 | 972 | if (pos != len(spec)): |
|
899 | 973 | raise error.ParseError("invalid token", pos) |
|
974 | tree = findaliases(ui, tree) | |
|
900 | 975 | weight, tree = optimize(tree, True) |
|
901 | 976 | def mfunc(repo, subset): |
|
902 | 977 | return getset(repo, subset, tree) |
@@ -2,7 +2,7 | |||
|
2 | 2 | $ export HGENCODING |
|
3 | 3 | |
|
4 | 4 | $ try() { |
|
5 |
> hg debugrevspec --debug |
|
|
5 | > hg debugrevspec --debug "$@" | |
|
6 | 6 | > } |
|
7 | 7 | |
|
8 | 8 | $ log() { |
@@ -411,3 +411,27 parentrevspec | |||
|
411 | 411 | $ log 'tip^foo' |
|
412 | 412 | hg: parse error: ^ expects a number 0, 1, or 2 |
|
413 | 413 | [255] |
|
414 | ||
|
415 | aliases: | |
|
416 | ||
|
417 | $ echo '[revsetalias]' >> .hg/hgrc | |
|
418 | $ echo 'm = merge()' >> .hg/hgrc | |
|
419 | $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc | |
|
420 | $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc | |
|
421 | ||
|
422 | $ try m | |
|
423 | ('symbol', 'm') | |
|
424 | ('func', ('symbol', 'merge'), None) | |
|
425 | 6 | |
|
426 | $ try 'd(2:5)' | |
|
427 | ('func', ('symbol', 'd'), ('range', ('symbol', '2'), ('symbol', '5'))) | |
|
428 | ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('range', ('symbol', '2'), ('symbol', '5')), ('symbol', 'date')))) | |
|
429 | 4 | |
|
430 | 5 | |
|
431 | 3 | |
|
432 | 2 | |
|
433 | $ try 'rs(2 or 3, date)' | |
|
434 | ('func', ('symbol', 'rs'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date'))) | |
|
435 | ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date')))) | |
|
436 | 3 | |
|
437 | 2 |
General Comments 0
You need to be logged in to leave comments.
Login now