mercurial/revset.py
changeset 23720 8ec03e0ef51a
parent 23719 34364a4b25eb
child 23725 6a81f88758aa
--- 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]