mercurial/commands.py
changeset 2741 ae5ce3454ef5
parent 2739 3248aa10b388
child 2743 a31f0f2997e9
equal deleted inserted replaced
2740:386f04d6ecb3 2741:ae5ce3454ef5
   123                 if windowsize < sizelimit:
   123                 if windowsize < sizelimit:
   124                     windowsize *= 2
   124                     windowsize *= 2
   125 
   125 
   126 
   126 
   127     files, matchfn, anypats = matchpats(repo, pats, opts)
   127     files, matchfn, anypats = matchpats(repo, pats, opts)
       
   128     follow = opts.get('follow')
   128 
   129 
   129     if repo.changelog.count() == 0:
   130     if repo.changelog.count() == 0:
   130         return [], False, matchfn
   131         return [], False, matchfn
   131 
   132 
   132     revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
   133     revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
   142         return ch
   143         return ch
   143 
   144 
   144     if not slowpath and not files:
   145     if not slowpath and not files:
   145         # No files, no patterns.  Display all revs.
   146         # No files, no patterns.  Display all revs.
   146         wanted = dict(zip(revs, revs))
   147         wanted = dict(zip(revs, revs))
       
   148     copies = []
   147     if not slowpath:
   149     if not slowpath:
   148         # Only files, no patterns.  Check the history of each file.
   150         # Only files, no patterns.  Check the history of each file.
   149         def filerevgen(filelog):
   151         def filerevgen(filelog, node):
   150             cl_count = repo.changelog.count()
   152             cl_count = repo.changelog.count()
   151             for i, window in increasing_windows(filelog.count()-1, -1):
   153             if node is None:
       
   154                 last = filelog.count() - 1
       
   155             else:
       
   156                 last = filelog.rev(node)
       
   157             for i, window in increasing_windows(last, -1):
   152                 revs = []
   158                 revs = []
   153                 for j in xrange(i - window, i + 1):
   159                 for j in xrange(i - window, i + 1):
   154                     revs.append(filelog.linkrev(filelog.node(j)))
   160                     n = filelog.node(j)
       
   161                     revs.append((filelog.linkrev(n),
       
   162                                  follow and filelog.renamed(n)))
   155                 revs.reverse()
   163                 revs.reverse()
   156                 for rev in revs:
   164                 for rev in revs:
   157                     # only yield rev for which we have the changelog, it can
   165                     # only yield rev for which we have the changelog, it can
   158                     # happen while doing "hg log" during a pull or commit
   166                     # happen while doing "hg log" during a pull or commit
   159                     if rev < cl_count:
   167                     if rev[0] < cl_count:
   160                         yield rev
   168                         yield rev
   161 
   169         def iterfiles():
       
   170             for filename in files:
       
   171                 yield filename, None
       
   172             for filename_node in copies:
       
   173                 yield filename_node
   162         minrev, maxrev = min(revs), max(revs)
   174         minrev, maxrev = min(revs), max(revs)
   163         for file_ in files:
   175         for file_, node in iterfiles():
   164             filelog = repo.file(file_)
   176             filelog = repo.file(file_)
   165             # A zero count may be a directory or deleted file, so
   177             # A zero count may be a directory or deleted file, so
   166             # try to find matching entries on the slow path.
   178             # try to find matching entries on the slow path.
   167             if filelog.count() == 0:
   179             if filelog.count() == 0:
   168                 slowpath = True
   180                 slowpath = True
   169                 break
   181                 break
   170             for rev in filerevgen(filelog):
   182             for rev, copied in filerevgen(filelog, node):
   171                 if rev <= maxrev:
   183                 if rev <= maxrev:
   172                     if rev < minrev:
   184                     if rev < minrev:
   173                         break
   185                         break
   174                     fncache.setdefault(rev, [])
   186                     fncache.setdefault(rev, [])
   175                     fncache[rev].append(file_)
   187                     fncache[rev].append(file_)
   176                     wanted[rev] = 1
   188                     wanted[rev] = 1
       
   189                     if follow and copied:
       
   190                         copies.append(copied)
   177     if slowpath:
   191     if slowpath:
       
   192         if follow:
       
   193             raise util.Abort(_('can only follow copies/renames for explicit '
       
   194                                'file names'))
       
   195 
   178         # The slow path checks files modified in every changeset.
   196         # The slow path checks files modified in every changeset.
   179         def changerevgen():
   197         def changerevgen():
   180             for i, window in increasing_windows(repo.changelog.count()-1, -1):
   198             for i, window in increasing_windows(repo.changelog.count()-1, -1):
   181                 for j in xrange(i - window, i + 1):
   199                 for j in xrange(i - window, i + 1):
   182                     yield j, getchange(j)[3]
   200                     yield j, getchange(j)[3]
  1928             ui.write(((pats and rel) or abs), end)
  1946             ui.write(((pats and rel) or abs), end)
  1929 
  1947 
  1930 def log(ui, repo, *pats, **opts):
  1948 def log(ui, repo, *pats, **opts):
  1931     """show revision history of entire repository or files
  1949     """show revision history of entire repository or files
  1932 
  1950 
  1933     Print the revision history of the specified files or the entire project.
  1951     Print the revision history of the specified files or the entire
       
  1952     project.
       
  1953 
       
  1954     File history is shown without following rename or copy history of
       
  1955     files.  Use -f/--follow to follow history across renames and
       
  1956     copies.
  1934 
  1957 
  1935     By default this command outputs: changeset id and hash, tags,
  1958     By default this command outputs: changeset id and hash, tags,
  1936     non-trivial parents, user, date and time, and a summary for each
  1959     non-trivial parents, user, date and time, and a summary for each
  1937     commit. When the -v/--verbose switch is used, the list of changed
  1960     commit. When the -v/--verbose switch is used, the list of changed
  1938     files and full commit message is shown.
  1961     files and full commit message is shown.
  3041           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
  3064           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
  3042          _('hg locate [OPTION]... [PATTERN]...')),
  3065          _('hg locate [OPTION]... [PATTERN]...')),
  3043     "^log|history":
  3066     "^log|history":
  3044         (log,
  3067         (log,
  3045          [('b', 'branches', None, _('show branches')),
  3068          [('b', 'branches', None, _('show branches')),
       
  3069           ('f', 'follow', None,
       
  3070            _('follow file history across copies and renames')),
  3046           ('k', 'keyword', [], _('search for a keyword')),
  3071           ('k', 'keyword', [], _('search for a keyword')),
  3047           ('l', 'limit', '', _('limit number of changes displayed')),
  3072           ('l', 'limit', '', _('limit number of changes displayed')),
  3048           ('r', 'rev', [], _('show the specified revision or range')),
  3073           ('r', 'rev', [], _('show the specified revision or range')),
  3049           ('M', 'no-merges', None, _('do not show merges')),
  3074           ('M', 'no-merges', None, _('do not show merges')),
  3050           ('', 'style', '', _('display using template map file')),
  3075           ('', 'style', '', _('display using template map file')),