Comments
Patch
@@ -769,28 +769,92 @@ def filelog(repo, subset, x):
result, use ``file()``.
The pattern without explicit kind like ``glob:`` is expected to be
relative to the current directory and match against a file exactly
for efficiency.
+
+ If some linkrev point to revisions filtered by the current repoview, we'll
+ work around to return a non-filtered value.
"""
# i18n: "filelog" is a keyword
pat = getstring(x, _("filelog requires a pattern"))
s = set()
+ cl = repo.changelog
if not matchmod.patkind(pat):
f = pathutil.canonpath(repo.root, repo.getcwd(), pat)
- fl = repo.file(f)
- for fr in fl:
- s.add(fl.linkrev(fr))
+ files = [f]
else:
m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None])
- for f in repo[None]:
- if m(f):
- fl = repo.file(f)
- for fr in fl:
- s.add(fl.linkrev(fr))
+ files = (f for f in repo[None] if m(f))
+
+ for f in files:
+ backrevref = {} # final value for: changerev -> filerev
+ lowestchild = {} # lowest known filerev child of a filerev
+ delayed = [] # filerev with filtered linkrev, for post-processing
+ fl = repo.file(f)
+ for fr in list(fl):
+ lkr = rev = fl.linkrev(fr)
+ if rev not in cl:
+ # changerev pointed in linkrev is filtered
+ # record it for post processing.
+ delayed.append((fr, rev))
+ continue
+ for p in fl.parentrevs(fr):
+ if 0 <= p and p not in lowestchild:
+ lowestchild[p] = fr
+ backrevref[fr] = rev
+ s.add(rev)
+
+ # Post-post processing of all filerev we skipped because they were
+ # filtered. If such filerev have known and unfiltered children, this
+ # mean they have an unfiltered appearance out there. We'll use linkrev
+ # adjustment to find one of this appearance. The lowest known child
+ # will be used as a starting point because it is the best upper-bound we
+ # have.
+ #
+ # This approach will fails when unfiltered but linkrev-shadowned
+ # appearance exists in head changeset without unfiltered filerev
+ # children anywhere.
+ while delayed:
+ # must be a descending iteration. To slowly fill lowest child
+ # information that is of potential use by the next item.
+ fr, rev = delayed.pop()
+ lkr = rev
+
+ child = lowestchild.get(fr)
+
+ if child is None:
+ # XXX content could be linkrev-shadowed in a head, but lets
+ # ignore this case for now.
+ continue
+ else:
+ # the lowest known child is a good upper bound
+ childcrev = backrevref[child]
+ # XXX this does not grantee to return the lowest introduction
+ # of this revision, but this give result which a good start and
+ # will fit in most case. We probably need to fix the multiple
+ # introductions case properly (report each introductions, even
+ # for identical file revision) once and for all at some point
+ # anyway.
+ for p in repo[childcrev][f].parents():
+ if p.filerev() == fr:
+ rev = p.rev()
+ break
+ if rev == lkr: # no shadowed entry found
+ # XXX This should never happen unless some manifest point
+ # to biggish file revisions. (Like revision that use a
+ # parent who that never appear in the manifest ancestors.)
+ continue
+
+ # Fill the data for the next iteration.
+ for p in fl.parentrevs(fr):
+ if 0 <= p and p not in lowestchild:
+ lowestchild[p] = fr
+ backrevref[fr] = rev
+ s.add(rev)
return subset & s
def first(repo, subset, x):
"""``first(set, [n])``
@@ -1671,6 +1671,58 @@ hg log -f from the grafted changeset
o changeset: 0:ae0a3c9f9e95
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: content1
+
+Test that we use the first non-hidden changeset in that case.
+
+(hide the changeset)
+
+ $ hg log -T '{node}\n' -r 1
+ 2294ae80ad8447bc78383182eeac50cb049df623
+ $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
+ $ hg log -G
+ o changeset: 4:50b9b36e9c5d
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: content3
+ |
+ @ changeset: 3:15b2327059e5
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: content2
+ |
+ o changeset: 2:2029acd1168c
+ | parent: 0:ae0a3c9f9e95
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: unrelated
+ |
+ o changeset: 0:ae0a3c9f9e95
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: content1
+
+
+Check that log on the file does not drop the file revision.
+
+ $ hg log -G a
+ o changeset: 4:50b9b36e9c5d
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: content3
+ |
+ @ changeset: 3:15b2327059e5
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: content2
+ |
+ o changeset: 0:ae0a3c9f9e95
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: content1
+
+
$ cd ..