##// END OF EJS Templates
graphlog: paths/-I/-X handling requires a new revset...
Patrick Mezard -
r16161:5a627b49 default
parent child Browse files
Show More
@@ -255,9 +255,6 b' def revset(repo, pats, opts):'
255 'removed': ('removes("*")', None),
255 'removed': ('removes("*")', None),
256 'date': ('date(%(val)r)', None),
256 'date': ('date(%(val)r)', None),
257 'branch': ('branch(%(val)r)', ' or '),
257 'branch': ('branch(%(val)r)', ' or '),
258 'exclude': ('not file(%(val)r)', ' and '),
259 'include': ('file(%(val)r)', ' and '),
260 '_pats': ('file(%(val)r)', ' or '),
261 '_patslog': ('filelog(%(val)r)', ' or '),
258 '_patslog': ('filelog(%(val)r)', ' or '),
262 'keyword': ('keyword(%(val)r)', ' or '),
259 'keyword': ('keyword(%(val)r)', ' or '),
263 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
260 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
@@ -281,8 +278,21 b' def revset(repo, pats, opts):'
281 # try to find matching entries on the slow path.
278 # try to find matching entries on the slow path.
282 slowpath = True
279 slowpath = True
283 if slowpath:
280 if slowpath:
284 # See cmdutil.walkchangerevs() slow path
281 # See cmdutil.walkchangerevs() slow path.
285 opts['_pats'] = list(pats)
282 #
283 # pats/include/exclude cannot be represented as separate
284 # revset expressions as their filtering logic applies at file
285 # level. For instance "-I a -X a" matches a revision touching
286 # "a" and "b" while "file(a) and not file(b)" does not.
287 matchargs = []
288 for p in pats:
289 matchargs.append('p:' + p)
290 for p in opts.get('include', []):
291 matchargs.append('i:' + p)
292 for p in opts.get('exclude', []):
293 matchargs.append('x:' + p)
294 matchargs = ','.join(('%r' % p) for p in matchargs)
295 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
286 else:
296 else:
287 opts['_patslog'] = list(pats)
297 opts['_patslog'] = list(pats)
288
298
@@ -112,7 +112,7 b' def getlist(x):'
112
112
113 def getargs(x, min, max, err):
113 def getargs(x, min, max, err):
114 l = getlist(x)
114 l = getlist(x)
115 if len(l) < min or len(l) > max:
115 if len(l) < min or (max >= 0 and len(l) > max):
116 raise error.ParseError(err)
116 raise error.ParseError(err)
117 return l
117 return l
118
118
@@ -493,23 +493,52 b' def grep(repo, subset, x):'
493 break
493 break
494 return l
494 return l
495
495
496 def _matchfiles(repo, subset, x):
497 # _matchfiles takes a revset list of prefixed arguments:
498 #
499 # [p:foo, i:bar, x:baz]
500 #
501 # builds a match object from them and filters subset. Allowed
502 # prefixes are 'p:' for regular patterns, 'i:' for include
503 # patterns and 'x:' for exclude patterns.
504
505 # i18n: "_matchfiles" is a keyword
506 l = getargs(x, 1, -1, _("_matchfiles requires at least one argument"))
507 pats, inc, exc = [], [], []
508 hasset = False
509 for arg in l:
510 s = getstring(arg, _("_matchfiles requires string arguments"))
511 prefix, value = s[:2], s[2:]
512 if prefix == 'p:':
513 pats.append(value)
514 elif prefix == 'i:':
515 inc.append(value)
516 elif prefix == 'x:':
517 exc.append(value)
518 else:
519 raise error.ParseError(_('invalid _matchfiles prefix: %s') % prefix)
520 if not hasset and matchmod.patkind(value) == 'set':
521 hasset = True
522 m = None
523 s = []
524 for r in subset:
525 c = repo[r]
526 if not m or hasset:
527 m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
528 exclude=exc, ctx=c)
529 for f in c.files():
530 if m(f):
531 s.append(r)
532 break
533 return s
534
496 def hasfile(repo, subset, x):
535 def hasfile(repo, subset, x):
497 """``file(pattern)``
536 """``file(pattern)``
498 Changesets affecting files matched by pattern.
537 Changesets affecting files matched by pattern.
499 """
538 """
500 # i18n: "file" is a keyword
539 # i18n: "file" is a keyword
501 pat = getstring(x, _("file requires a pattern"))
540 pat = getstring(x, _("file requires a pattern"))
502 m = None
541 return _matchfiles(repo, subset, ('string', 'p:' + pat))
503 s = []
504 for r in subset:
505 c = repo[r]
506 if not m or matchmod.patkind(pat) == 'set':
507 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
508 for f in c.files():
509 if m(f):
510 s.append(r)
511 break
512 return s
513
542
514 def head(repo, subset, x):
543 def head(repo, subset, x):
515 """``head()``
544 """``head()``
@@ -943,6 +972,7 b' symbols = {'
943 "keyword": keyword,
972 "keyword": keyword,
944 "last": last,
973 "last": last,
945 "limit": limit,
974 "limit": limit,
975 "_matchfiles": _matchfiles,
946 "max": maxrev,
976 "max": maxrev,
947 "merge": merge,
977 "merge": merge,
948 "min": minrev,
978 "min": minrev,
@@ -1437,7 +1437,6 b' Test log -G options'
1437 ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch')))))
1437 ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch')))))
1438 $ testlog -k expand -k merge
1438 $ testlog -k expand -k merge
1439 ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge')))))
1439 ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge')))))
1440 $ hg log -G --include 'some file' --exclude 'another file'
1441 $ hg log -G --follow --template 'nodetag {rev}\n' | grep nodetag | wc -l
1440 $ hg log -G --follow --template 'nodetag {rev}\n' | grep nodetag | wc -l
1442 \s*36 (re)
1441 \s*36 (re)
1443 $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
1442 $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
@@ -1527,4 +1526,9 b' Dedicated repo for --follow and paths fi'
1527 Test falling back to slow path for non-existing files
1526 Test falling back to slow path for non-existing files
1528
1527
1529 $ testlog a c
1528 $ testlog a c
1530 ('group', ('group', ('or', ('func', ('symbol', 'file'), ('string', 'a')), ('func', ('symbol', 'file'), ('string', 'c')))))
1529 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('string', 'p:a'), ('string', 'p:c')))))
1530
1531 Test multiple --include/--exclude/paths
1532
1533 $ testlog --include a --include e --exclude b --exclude e a e
1534 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('list', ('list', ('list', ('list', ('string', 'p:a'), ('string', 'p:e')), ('string', 'i:a')), ('string', 'i:e')), ('string', 'x:b')), ('string', 'x:e')))))
General Comments 0
You need to be logged in to leave comments. Login now