diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1059,8 +1059,14 @@ def walkchangerevs(repo, match, opts, pr # We only have to read through the filelog to find wanted revisions minrev, maxrev = min(revs), max(revs) - # Only files, no patterns. Check the history of each file. def filerevgen(filelog, last): + """ + Only files, no patterns. Check the history of each file. + + Examines filelog entries within minrev, maxrev linkrev range + Returns an iterator yielding (linkrev, parentlinkrevs, copied) + tuples in backwards order + """ cl_count = len(repo) revs = [] for j in xrange(0, last + 1): @@ -1071,8 +1077,13 @@ def walkchangerevs(repo, match, opts, pr # happen while doing "hg log" during a pull or commit if linkrev > maxrev or linkrev >= cl_count: break + + parentlinkrevs = [] + for p in filelog.parentrevs(j): + if p != nullrev: + parentlinkrevs.append(filelog.linkrev(p)) n = filelog.node(j) - revs.append((filelog.linkrev(j), + revs.append((linkrev, parentlinkrevs, follow and filelog.renamed(n))) for rev in reversed(revs): @@ -1101,7 +1112,18 @@ def walkchangerevs(repo, match, opts, pr else: last = filelog.rev(node) - for rev, copied in filerevgen(filelog, last): + + # keep track of all ancestors of the file + ancestors = set([filelog.linkrev(last)]) + + # iterate from latest to oldest revision + for rev, flparentlinkrevs, copied in filerevgen(filelog, last): + if rev not in ancestors: + continue + # XXX insert 1327 fix here + if flparentlinkrevs: + ancestors.update(flparentlinkrevs) + fncache.setdefault(rev, []) fncache[rev].append(file_) wanted.add(rev) diff --git a/tests/test-log b/tests/test-log --- a/tests/test-log +++ b/tests/test-log @@ -200,4 +200,53 @@ cd dir hg log -p -R .. ../a +cd .. +hg init follow2 +cd follow2 + +# Build the following history: +# tip - o - x - o - x - x +# \ / +# o - o - o - x +# \ / +# o +# +# Where "o" is a revision containing "foo" and +# "x" is a revision without "foo" +touch init +hg ci -A -m "init, unrelated" +echo 'foo' > init +hg ci -m "change, unrelated" +echo 'foo' > foo +hg ci -A -m "add unrelated old foo" +hg rm foo +hg ci -m "delete foo, unrelated" +echo 'related' > foo +hg ci -A -m "add foo, related" + +hg up 0 +touch branch +hg ci -A -m "first branch, unrelated" +touch foo +hg ci -A -m "create foo, related" +echo 'change' > foo +hg ci -m "change foo, related" + +hg up 6 +echo 'change foo in branch' > foo +hg ci -m "change foo in branch, related" +hg merge 7 +echo 'merge 1' > foo +hg resolve -m foo +hg ci -m "First merge, related" + +hg merge 4 +echo 'merge 2' > foo +hg resolve -m foo +hg ci -m "Last merge, related" + +hg --config "extensions.graphlog=" glog + +hg --traceback log -f foo + exit 0 diff --git a/tests/test-log.out b/tests/test-log.out --- a/tests/test-log.out +++ b/tests/test-log.out @@ -611,3 +611,120 @@ diff -r 000000000000 -r 24427303d56f a @@ -0,0 +1,1 @@ +a +adding init +adding foo +adding foo +1 files updated, 0 files merged, 1 files removed, 0 files unresolved +adding branch +created new head +adding foo +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +created new head +merging foo +warning: conflicts during merge. +merging foo failed! +0 files updated, 0 files merged, 0 files removed, 1 files unresolved +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon +merging foo +warning: conflicts during merge. +merging foo failed! +1 files updated, 0 files merged, 0 files removed, 1 files unresolved +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon +@ changeset: 10:4dae8563d2c5 +|\ tag: tip +| | parent: 9:7b35701b003e +| | parent: 4:88176d361b69 +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: Last merge, related +| | +| o changeset: 9:7b35701b003e +| |\ parent: 8:e5416ad8a855 +| | | parent: 7:87fe3144dcfa +| | | user: test +| | | date: Thu Jan 01 00:00:00 1970 +0000 +| | | summary: First merge, related +| | | +| | o changeset: 8:e5416ad8a855 +| | | parent: 6:dc6c325fe5ee +| | | user: test +| | | date: Thu Jan 01 00:00:00 1970 +0000 +| | | summary: change foo in branch, related +| | | +| o | changeset: 7:87fe3144dcfa +| |/ user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: change foo, related +| | +| o changeset: 6:dc6c325fe5ee +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: create foo, related +| | +| o changeset: 5:73db34516eb9 +| | parent: 0:e87515fd044a +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: first branch, unrelated +| | +o | changeset: 4:88176d361b69 +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: add foo, related +| | +o | changeset: 3:dd78ae4afb56 +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: delete foo, unrelated +| | +o | changeset: 2:c4c64aedf0f7 +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: add unrelated old foo +| | +o | changeset: 1:e5faa7440653 +|/ user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: change, unrelated +| +o changeset: 0:e87515fd044a + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: init, unrelated + +changeset: 10:4dae8563d2c5 +tag: tip +parent: 9:7b35701b003e +parent: 4:88176d361b69 +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: Last merge, related + +changeset: 9:7b35701b003e +parent: 8:e5416ad8a855 +parent: 7:87fe3144dcfa +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: First merge, related + +changeset: 8:e5416ad8a855 +parent: 6:dc6c325fe5ee +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: change foo in branch, related + +changeset: 7:87fe3144dcfa +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: change foo, related + +changeset: 6:dc6c325fe5ee +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: create foo, related + +changeset: 4:88176d361b69 +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: add foo, related +