# HG changeset patch # User Yuya Nishihara # Date 1514960002 -32400 # Node ID 659dfbd852e28656fad791dce4f2a22646888ba8 # Parent 1c929b4942a3150d371eb2784c2be4b211016d5b log: extract function that processes log file patterns We'll need a matcher to compute revs followed from the given patterns. diff -r 1c929b4942a3 -r 659dfbd852e2 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Sun Dec 10 17:28:44 2017 +0900 +++ b/mercurial/cmdutil.py Wed Jan 03 15:13:22 2018 +0900 @@ -2322,6 +2322,55 @@ return iterate() +def _makelogmatcher(repo, pats, opts): + """Build matcher and expanded patterns from log options + + Returns (match, pats, slowpath) where + - match: a matcher built from the given pats and -I/-X opts + - pats: patterns used (globs are expanded on Windows) + - slowpath: True if patterns aren't as simple as scanning filelogs + """ + # pats/include/exclude are passed to match.match() directly in + # _matchfiles() revset but walkchangerevs() builds its matcher with + # scmutil.match(). The difference is input pats are globbed on + # platforms without shell expansion (windows). + wctx = repo[None] + match, pats = scmutil.matchandpats(wctx, pats, opts) + slowpath = match.anypats() or (not match.always() and opts.get('removed')) + if not slowpath: + follow = opts.get('follow') or opts.get('follow_first') + for f in match.files(): + if follow and f not in wctx: + # If the file exists, it may be a directory, so let it + # take the slow path. + if os.path.exists(repo.wjoin(f)): + slowpath = True + continue + else: + raise error.Abort(_('cannot follow file not in parent ' + 'revision: "%s"') % f) + filelog = repo.file(f) + if not filelog: + # A zero count may be a directory or deleted file, so + # try to find matching entries on the slow path. + if follow: + raise error.Abort( + _('cannot follow nonexistent file: "%s"') % f) + slowpath = True + + # We decided to fall back to the slowpath because at least one + # of the paths was not a file. Check to see if at least one of them + # existed in history - in that case, we'll continue down the + # slowpath; otherwise, we can turn off the slowpath + if slowpath: + for path in match.files(): + if path == '.' or path in repo.store: + break + else: + slowpath = False + + return match, pats, slowpath + def _makefollowlogfilematcher(repo, files, followfirst): # When displaying a revision with --patch --follow FILE, we have # to know which file of the revision must be diffed. With @@ -2370,7 +2419,7 @@ 'user': ('user(%s)', '%lr'), } -def _makelogrevset(repo, pats, opts): +def _makelogrevset(repo, match, pats, slowpath, opts): """Return (expr, filematcher) where expr is a revset string built from log options and file patterns or None. If --stat or --patch are not passed filematcher is None. Otherwise it is a callable @@ -2389,43 +2438,6 @@ # the same time opts['branch'] = opts.get('branch', []) + opts.get('only_branch', []) opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']] - # pats/include/exclude are passed to match.match() directly in - # _matchfiles() revset but walkchangerevs() builds its matcher with - # scmutil.match(). The difference is input pats are globbed on - # platforms without shell expansion (windows). - wctx = repo[None] - match, pats = scmutil.matchandpats(wctx, pats, opts) - slowpath = match.anypats() or (not match.always() and opts.get('removed')) - if not slowpath: - for f in match.files(): - if follow and f not in wctx: - # If the file exists, it may be a directory, so let it - # take the slow path. - if os.path.exists(repo.wjoin(f)): - slowpath = True - continue - else: - raise error.Abort(_('cannot follow file not in parent ' - 'revision: "%s"') % f) - filelog = repo.file(f) - if not filelog: - # A zero count may be a directory or deleted file, so - # try to find matching entries on the slow path. - if follow: - raise error.Abort( - _('cannot follow nonexistent file: "%s"') % f) - slowpath = True - - # We decided to fall back to the slowpath because at least one - # of the paths was not a file. Check to see if at least one of them - # existed in history - in that case, we'll continue down the - # slowpath; otherwise, we can turn off the slowpath - if slowpath: - for path in match.files(): - if path == '.' or path in repo.store: - break - else: - slowpath = False fpats = ('_patsfollow', '_patsfollowfirst') fnopats = ('_ancestors', '_fancestors') @@ -2528,10 +2540,11 @@ revs = _logrevs(repo, opts) if not revs: return smartset.baseset(), None + match, pats, slowpath = _makelogmatcher(repo, pats, opts) if opts.get('rev') and follow: revs = dagop.revancestors(repo, revs, followfirst=followfirst) revs.reverse() - expr, filematcher = _makelogrevset(repo, pats, opts) + expr, filematcher = _makelogrevset(repo, match, pats, slowpath, opts) if opts.get('graph') and opts.get('rev'): # User-specified revs might be unsorted, but don't sort before # _makelogrevset because it might depend on the order of revs diff -r 1c929b4942a3 -r 659dfbd852e2 tests/test-glog.t --- a/tests/test-glog.t Sun Dec 10 17:28:44 2017 +0900 +++ b/tests/test-glog.t Wed Jan 03 15:13:22 2018 +0900 @@ -95,7 +95,8 @@ > revs = cmdutil._logrevs(repo, opts) > if not revs: > return None - > return cmdutil._makelogrevset(repo, pats, opts)[0] + > match, pats, slowpath = cmdutil._makelogmatcher(repo, pats, opts) + > return cmdutil._makelogrevset(repo, match, pats, slowpath, opts)[0] > > def uisetup(ui): > def printrevset(orig, repo, pats, opts):