# HG changeset patch # User Brendan Cully # Date 1155420106 25200 # Node ID 8eaaf1321bfeb51cd530474ce3d4bc3efc101bfc # Parent 81f351c5264ddbd829f46f4a35f258e60b3cb4e7 grep: add --follow support. diff -r 81f351c5264d -r 8eaaf1321bfe mercurial/commands.py --- a/mercurial/commands.py Sat Aug 12 13:51:14 2006 -0700 +++ b/mercurial/commands.py Sat Aug 12 15:01:46 2006 -0700 @@ -1649,6 +1649,7 @@ return self.line == other.line matches = {} + copies = {} def grepbody(fn, rev, body): matches[rev].setdefault(fn, []) m = matches[rev][fn] @@ -1709,10 +1710,12 @@ changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) count = 0 incrementing = False + follow = opts.get('follow') for st, rev, fns in changeiter: if st == 'window': incrementing = rev matches.clear() + copies.clear() elif st == 'add': change = repo.changelog.read(repo.lookup(str(rev))) mf = repo.manifest.read(change[0]) @@ -1721,22 +1724,34 @@ if fn in skip: continue fstate.setdefault(fn, {}) + copies.setdefault(rev, {}) try: grepbody(fn, rev, getfile(fn).read(mf[fn])) + if follow: + copied = getfile(fn).renamed(mf[fn]) + if copied: + copies[rev][fn] = copied[0] except KeyError: pass elif st == 'iter': states = matches[rev].items() states.sort() for fn, m in states: + copy = copies[rev].get(fn) if fn in skip: + if copy: + skip[copy] = True continue if incrementing or not opts['all'] or fstate[fn]: pos, neg = display(fn, rev, m, fstate[fn]) count += pos + neg if pos and not opts['all']: skip[fn] = True + if copy: + skip[copy] = True fstate[fn] = m + if copy: + fstate[copy] = m prev[fn] = rev if not incrementing: @@ -1745,7 +1760,8 @@ for fn, state in fstate: if fn in skip: continue - display(fn, rev, {}, state) + if fn not in copies[prev[fn]]: + display(fn, rev, {}, state) return (count == 0 and 1) or 0 def heads(ui, repo, **opts): @@ -3107,6 +3123,8 @@ (grep, [('0', 'print0', None, _('end fields with NUL')), ('', 'all', None, _('print all revisions that match')), + ('f', 'follow', None, + _('follow changeset history, or file history across copies and renames')), ('i', 'ignore-case', None, _('ignore case when matching')), ('l', 'files-with-matches', None, _('print only filenames and revs that match')), diff -r 81f351c5264d -r 8eaaf1321bfe tests/test-grep --- a/tests/test-grep Sat Aug 12 13:51:14 2006 -0700 +++ b/tests/test-grep Sat Aug 12 15:01:46 2006 -0700 @@ -20,3 +20,11 @@ hg grep port port hg grep --all -nu port port hg grep import port + +hg cp port port2 +hg commit -m 4 -u spam -d '5 0' +echo '% follow' +hg grep -f 'import$' port2 +echo deport >> port2 +hg commit -m 5 -u eggs -d '6 0' +hg grep -f --all -nu port port2 diff -r 81f351c5264d -r 8eaaf1321bfe tests/test-grep.out --- a/tests/test-grep.out Sat Aug 12 13:51:14 2006 -0700 +++ b/tests/test-grep.out Sat Aug 12 15:01:46 2006 -0700 @@ -11,3 +11,15 @@ port:1:2:+:eggs:export port:0:1:+:eggs:import port:4:import/export +% follow +port:0:import +port2:6:4:+:eggs:deport +port:4:4:-:spam:import/export +port:3:4:+:eggs:import/export +port:2:1:-:spam:import +port:2:2:-:spam:export +port:2:1:+:spam:export +port:2:2:+:spam:vaportight +port:2:3:+:spam:import/export +port:1:2:+:eggs:export +port:0:1:+:eggs:import