# HG changeset patch # User Vadim Gelfer # Date 2006-07-31 14:31:31 # Node ID ae5ce3454ef50d3d512e7cc208a6cc0d148a226c # Parent 386f04d6ecb3b852ad77182b9f152ab7c990ae36 log: add -f/--follow option, to follow rename/copy diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -125,6 +125,7 @@ def walkchangerevs(ui, repo, pats, opts) files, matchfn, anypats = matchpats(repo, pats, opts) + follow = opts.get('follow') if repo.changelog.count() == 0: return [], False, matchfn @@ -144,37 +145,54 @@ def walkchangerevs(ui, repo, pats, opts) if not slowpath and not files: # No files, no patterns. Display all revs. wanted = dict(zip(revs, revs)) + copies = [] if not slowpath: # Only files, no patterns. Check the history of each file. - def filerevgen(filelog): + def filerevgen(filelog, node): cl_count = repo.changelog.count() - for i, window in increasing_windows(filelog.count()-1, -1): + if node is None: + last = filelog.count() - 1 + else: + last = filelog.rev(node) + for i, window in increasing_windows(last, -1): revs = [] for j in xrange(i - window, i + 1): - revs.append(filelog.linkrev(filelog.node(j))) + n = filelog.node(j) + revs.append((filelog.linkrev(n), + follow and filelog.renamed(n))) revs.reverse() for rev in revs: # only yield rev for which we have the changelog, it can # happen while doing "hg log" during a pull or commit - if rev < cl_count: + if rev[0] < cl_count: yield rev - + def iterfiles(): + for filename in files: + yield filename, None + for filename_node in copies: + yield filename_node minrev, maxrev = min(revs), max(revs) - for file_ in files: + for file_, node in iterfiles(): filelog = repo.file(file_) # A zero count may be a directory or deleted file, so # try to find matching entries on the slow path. if filelog.count() == 0: slowpath = True break - for rev in filerevgen(filelog): + for rev, copied in filerevgen(filelog, node): if rev <= maxrev: if rev < minrev: break fncache.setdefault(rev, []) fncache[rev].append(file_) wanted[rev] = 1 + if follow and copied: + copies.append(copied) if slowpath: + if follow: + raise util.Abort(_('can only follow copies/renames for explicit ' + 'file names')) + # The slow path checks files modified in every changeset. def changerevgen(): for i, window in increasing_windows(repo.changelog.count()-1, -1): @@ -1930,7 +1948,12 @@ def locate(ui, repo, *pats, **opts): def log(ui, repo, *pats, **opts): """show revision history of entire repository or files - Print the revision history of the specified files or the entire project. + Print the revision history of the specified files or the entire + project. + + File history is shown without following rename or copy history of + files. Use -f/--follow to follow history across renames and + copies. By default this command outputs: changeset id and hash, tags, non-trivial parents, user, date and time, and a summary for each @@ -3043,6 +3066,8 @@ table = { "^log|history": (log, [('b', 'branches', None, _('show branches')), + ('f', 'follow', None, + _('follow file history across copies and renames')), ('k', 'keyword', [], _('search for a keyword')), ('l', 'limit', '', _('limit number of changes displayed')), ('r', 'rev', [], _('show the specified revision or range')), diff --git a/tests/test-log b/tests/test-log new file mode 100755 --- /dev/null +++ b/tests/test-log @@ -0,0 +1,30 @@ +#!/bin/sh + +hg init a + +cd a +echo a > a +hg ci -Ama -d '1 0' + +hg cp a b +hg ci -mb -d '2 0' + +mkdir dir +hg mv b dir +hg ci -mc -d '3 0' + +hg mv a b +hg ci -md -d '4 0' + +hg mv dir/b e +hg ci -me -d '5 0' + +hg log a +echo % -f, directory +hg log -f dir +echo % -f, but no args +hg log -f +echo % one rename +hg log -vf a +echo % many renames +hg log -vf e diff --git a/tests/test-log.out b/tests/test-log.out new file mode 100644 --- /dev/null +++ b/tests/test-log.out @@ -0,0 +1,78 @@ +adding a +changeset: 0:8580ff50825a +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +summary: a + +% -f, directory +abort: can only follow copies/renames for explicit file names +% -f, but no args +changeset: 4:8c1c8408f737 +tag: tip +user: test +date: Thu Jan 01 00:00:05 1970 +0000 +summary: e + +changeset: 3:c4ba038c90ce +user: test +date: Thu Jan 01 00:00:04 1970 +0000 +summary: d + +changeset: 2:21fba396af4c +user: test +date: Thu Jan 01 00:00:03 1970 +0000 +summary: c + +changeset: 1:c0296dabce9b +user: test +date: Thu Jan 01 00:00:02 1970 +0000 +summary: b + +changeset: 0:8580ff50825a +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +summary: a + +% one rename +changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +files: a +description: +a + + +% many renames +changeset: 4:8c1c8408f7371319750ea2d4fa7969828effbcf4 +tag: tip +user: test +date: Thu Jan 01 00:00:05 1970 +0000 +files: dir/b e +description: +e + + +changeset: 2:21fba396af4c801f9717de6c415b6cc9620437e8 +user: test +date: Thu Jan 01 00:00:03 1970 +0000 +files: b dir/b +description: +c + + +changeset: 1:c0296dabce9bf0cd3fdd608de26693c91cd6bbf4 +user: test +date: Thu Jan 01 00:00:02 1970 +0000 +files: b +description: +b + + +changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +files: a +description: +a + +