Mercurial > hg
changeset 23720:8ec03e0ef51a
linkrev-filelog: handle filtered linkrev with no visible children (issue4307)
If the file revision with a filtered linkrev does not have any
(unfiltered) children, we cannot use it to bound the search for
another introduction. Instead, we have to look at the file revision
used by each head changeset. If one of them uses this file revision, we
know there is another occurrence and we have a starting point. See
inline comments for details.
Adding some kind of permanent reference of all the introductions of a
file revision instead of just the first one would be much better. But
this is more difficult. I hope to take that into account in the next
repository format.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Mon, 29 Dec 2014 18:35:23 -0800 |
parents | 34364a4b25eb |
children | 5803bfeebbfe |
files | mercurial/revset.py tests/test-log.t |
diffstat | 2 files changed, 37 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/revset.py Mon Dec 29 17:23:16 2014 -0800 +++ b/mercurial/revset.py Mon Dec 29 18:35:23 2014 -0800 @@ -792,6 +792,7 @@ backrevref = {} # final value for: changerev -> filerev lowestchild = {} # lowest known filerev child of a filerev delayed = [] # filerev with filtered linkrev, for post-processing + lowesthead = None # cache for manifest content of all head revisions fl = repo.file(f) for fr in list(fl): lkr = rev = fl.linkrev(fr) @@ -825,9 +826,24 @@ 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 + # search for existence of this file revision in a head revision. + # There are three possibilities: + # - the revision exists in a head and we can find an + # introduction from there, + # - the revision does not exist in a head because it has been + # changed since its introduction: we would have found a child + # and be in the other 'else' clause, + # - all versions of the revision are hidden. + if lowesthead is None: + lowesthead = {} + for h in repo.heads(): + fnode = repo[h].manifest()[f] + lowesthead[fl.rev(fnode)] = h + headrev = lowesthead.get(fr) + if headrev is None: + # content is nowhere unfiltered + continue + rev = repo[headrev][f].introrev() else: # the lowest known child is a good upper bound childcrev = backrevref[child]
--- a/tests/test-log.t Mon Dec 29 17:23:16 2014 -0800 +++ b/tests/test-log.t Mon Dec 29 18:35:23 2014 -0800 @@ -1725,4 +1725,22 @@ summary: content1 +Even when a head revision is linkrev-shadowed. + + $ hg log -T '{node}\n' -r 4 + 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2 + $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2 + $ hg log -G a + @ changeset: 3:15b2327059e5 + | tag: tip + | 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 ..