mercurial/commands.py
changeset 2869 8eaaf1321bfe
parent 2868 81f351c5264d
child 2870 ffa2be02c4e5
equal deleted inserted replaced
2868:81f351c5264d 2869:8eaaf1321bfe
  1647 
  1647 
  1648         def __eq__(self, other):
  1648         def __eq__(self, other):
  1649             return self.line == other.line
  1649             return self.line == other.line
  1650 
  1650 
  1651     matches = {}
  1651     matches = {}
       
  1652     copies = {}
  1652     def grepbody(fn, rev, body):
  1653     def grepbody(fn, rev, body):
  1653         matches[rev].setdefault(fn, [])
  1654         matches[rev].setdefault(fn, [])
  1654         m = matches[rev][fn]
  1655         m = matches[rev][fn]
  1655         for lnum, cstart, cend, line in matchlines(body):
  1656         for lnum, cstart, cend, line in matchlines(body):
  1656             s = linestate(line, lnum, cstart, cend)
  1657             s = linestate(line, lnum, cstart, cend)
  1707     fstate = {}
  1708     fstate = {}
  1708     skip = {}
  1709     skip = {}
  1709     changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
  1710     changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
  1710     count = 0
  1711     count = 0
  1711     incrementing = False
  1712     incrementing = False
       
  1713     follow = opts.get('follow')
  1712     for st, rev, fns in changeiter:
  1714     for st, rev, fns in changeiter:
  1713         if st == 'window':
  1715         if st == 'window':
  1714             incrementing = rev
  1716             incrementing = rev
  1715             matches.clear()
  1717             matches.clear()
       
  1718             copies.clear()
  1716         elif st == 'add':
  1719         elif st == 'add':
  1717             change = repo.changelog.read(repo.lookup(str(rev)))
  1720             change = repo.changelog.read(repo.lookup(str(rev)))
  1718             mf = repo.manifest.read(change[0])
  1721             mf = repo.manifest.read(change[0])
  1719             matches[rev] = {}
  1722             matches[rev] = {}
  1720             for fn in fns:
  1723             for fn in fns:
  1721                 if fn in skip:
  1724                 if fn in skip:
  1722                     continue
  1725                     continue
  1723                 fstate.setdefault(fn, {})
  1726                 fstate.setdefault(fn, {})
       
  1727                 copies.setdefault(rev, {})
  1724                 try:
  1728                 try:
  1725                     grepbody(fn, rev, getfile(fn).read(mf[fn]))
  1729                     grepbody(fn, rev, getfile(fn).read(mf[fn]))
       
  1730                     if follow:
       
  1731                         copied = getfile(fn).renamed(mf[fn])
       
  1732                         if copied:
       
  1733                             copies[rev][fn] = copied[0]
  1726                 except KeyError:
  1734                 except KeyError:
  1727                     pass
  1735                     pass
  1728         elif st == 'iter':
  1736         elif st == 'iter':
  1729             states = matches[rev].items()
  1737             states = matches[rev].items()
  1730             states.sort()
  1738             states.sort()
  1731             for fn, m in states:
  1739             for fn, m in states:
       
  1740                 copy = copies[rev].get(fn)
  1732                 if fn in skip:
  1741                 if fn in skip:
       
  1742                     if copy:
       
  1743                         skip[copy] = True
  1733                     continue
  1744                     continue
  1734                 if incrementing or not opts['all'] or fstate[fn]:
  1745                 if incrementing or not opts['all'] or fstate[fn]:
  1735                     pos, neg = display(fn, rev, m, fstate[fn])
  1746                     pos, neg = display(fn, rev, m, fstate[fn])
  1736                     count += pos + neg
  1747                     count += pos + neg
  1737                     if pos and not opts['all']:
  1748                     if pos and not opts['all']:
  1738                         skip[fn] = True
  1749                         skip[fn] = True
       
  1750                         if copy:
       
  1751                             skip[copy] = True
  1739                 fstate[fn] = m
  1752                 fstate[fn] = m
       
  1753                 if copy:
       
  1754                     fstate[copy] = m
  1740                 prev[fn] = rev
  1755                 prev[fn] = rev
  1741 
  1756 
  1742     if not incrementing:
  1757     if not incrementing:
  1743         fstate = fstate.items()
  1758         fstate = fstate.items()
  1744         fstate.sort()
  1759         fstate.sort()
  1745         for fn, state in fstate:
  1760         for fn, state in fstate:
  1746             if fn in skip:
  1761             if fn in skip:
  1747                 continue
  1762                 continue
  1748             display(fn, rev, {}, state)
  1763             if fn not in copies[prev[fn]]:
       
  1764                 display(fn, rev, {}, state)
  1749     return (count == 0 and 1) or 0
  1765     return (count == 0 and 1) or 0
  1750 
  1766 
  1751 def heads(ui, repo, **opts):
  1767 def heads(ui, repo, **opts):
  1752     """show current repository heads
  1768     """show current repository heads
  1753 
  1769 
  3105          _('hg forget [OPTION]... FILE...')),
  3121          _('hg forget [OPTION]... FILE...')),
  3106     "grep":
  3122     "grep":
  3107         (grep,
  3123         (grep,
  3108          [('0', 'print0', None, _('end fields with NUL')),
  3124          [('0', 'print0', None, _('end fields with NUL')),
  3109           ('', 'all', None, _('print all revisions that match')),
  3125           ('', 'all', None, _('print all revisions that match')),
       
  3126           ('f', 'follow', None,
       
  3127            _('follow changeset history, or file history across copies and renames')),
  3110           ('i', 'ignore-case', None, _('ignore case when matching')),
  3128           ('i', 'ignore-case', None, _('ignore case when matching')),
  3111           ('l', 'files-with-matches', None,
  3129           ('l', 'files-with-matches', None,
  3112            _('print only filenames and revs that match')),
  3130            _('print only filenames and revs that match')),
  3113           ('n', 'line-number', None, _('print matching line numbers')),
  3131           ('n', 'line-number', None, _('print matching line numbers')),
  3114           ('r', 'rev', [], _('search in given revision range')),
  3132           ('r', 'rev', [], _('search in given revision range')),