Mercurial > public > mercurial-scm > hg
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 |