comparison mercurial/revset.py @ 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 6a81f88758aa
comparison
equal deleted inserted replaced
23719:34364a4b25eb 23720:8ec03e0ef51a
790 790
791 for f in files: 791 for f in files:
792 backrevref = {} # final value for: changerev -> filerev 792 backrevref = {} # final value for: changerev -> filerev
793 lowestchild = {} # lowest known filerev child of a filerev 793 lowestchild = {} # lowest known filerev child of a filerev
794 delayed = [] # filerev with filtered linkrev, for post-processing 794 delayed = [] # filerev with filtered linkrev, for post-processing
795 lowesthead = None # cache for manifest content of all head revisions
795 fl = repo.file(f) 796 fl = repo.file(f)
796 for fr in list(fl): 797 for fr in list(fl):
797 lkr = rev = fl.linkrev(fr) 798 lkr = rev = fl.linkrev(fr)
798 if rev not in cl: 799 if rev not in cl:
799 # changerev pointed in linkrev is filtered 800 # changerev pointed in linkrev is filtered
823 lkr = rev 824 lkr = rev
824 825
825 child = lowestchild.get(fr) 826 child = lowestchild.get(fr)
826 827
827 if child is None: 828 if child is None:
828 # XXX content could be linkrev-shadowed in a head, but lets 829 # search for existence of this file revision in a head revision.
829 # ignore this case for now. 830 # There are three possibilities:
830 continue 831 # - the revision exists in a head and we can find an
832 # introduction from there,
833 # - the revision does not exist in a head because it has been
834 # changed since its introduction: we would have found a child
835 # and be in the other 'else' clause,
836 # - all versions of the revision are hidden.
837 if lowesthead is None:
838 lowesthead = {}
839 for h in repo.heads():
840 fnode = repo[h].manifest()[f]
841 lowesthead[fl.rev(fnode)] = h
842 headrev = lowesthead.get(fr)
843 if headrev is None:
844 # content is nowhere unfiltered
845 continue
846 rev = repo[headrev][f].introrev()
831 else: 847 else:
832 # the lowest known child is a good upper bound 848 # the lowest known child is a good upper bound
833 childcrev = backrevref[child] 849 childcrev = backrevref[child]
834 # XXX this does not guarantee returning the lowest 850 # XXX this does not guarantee returning the lowest
835 # introduction of this revision, but this gives a 851 # introduction of this revision, but this gives a