##// END OF EJS Templates
linkrev: work around linkrev to filtered entry in 'filelog' revset...
Pierre-Yves David -
r23719:34364a4b default
parent child Browse files
Show More
@@ -771,24 +771,89 b' def filelog(repo, subset, x):'
771 The pattern without explicit kind like ``glob:`` is expected to be
771 The pattern without explicit kind like ``glob:`` is expected to be
772 relative to the current directory and match against a file exactly
772 relative to the current directory and match against a file exactly
773 for efficiency.
773 for efficiency.
774
775 If some linkrev points to revisions filtered by the current repoview, we'll
776 work around it to return a non-filtered value.
774 """
777 """
775
778
776 # i18n: "filelog" is a keyword
779 # i18n: "filelog" is a keyword
777 pat = getstring(x, _("filelog requires a pattern"))
780 pat = getstring(x, _("filelog requires a pattern"))
778 s = set()
781 s = set()
782 cl = repo.changelog
779
783
780 if not matchmod.patkind(pat):
784 if not matchmod.patkind(pat):
781 f = pathutil.canonpath(repo.root, repo.getcwd(), pat)
785 f = pathutil.canonpath(repo.root, repo.getcwd(), pat)
782 fl = repo.file(f)
786 files = [f]
783 for fr in fl:
784 s.add(fl.linkrev(fr))
785 else:
787 else:
786 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None])
788 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None])
787 for f in repo[None]:
789 files = (f for f in repo[None] if m(f))
788 if m(f):
790
789 fl = repo.file(f)
791 for f in files:
790 for fr in fl:
792 backrevref = {} # final value for: changerev -> filerev
791 s.add(fl.linkrev(fr))
793 lowestchild = {} # lowest known filerev child of a filerev
794 delayed = [] # filerev with filtered linkrev, for post-processing
795 fl = repo.file(f)
796 for fr in list(fl):
797 lkr = rev = fl.linkrev(fr)
798 if rev not in cl:
799 # changerev pointed in linkrev is filtered
800 # record it for post processing.
801 delayed.append((fr, rev))
802 continue
803 for p in fl.parentrevs(fr):
804 if 0 <= p and p not in lowestchild:
805 lowestchild[p] = fr
806 backrevref[fr] = rev
807 s.add(rev)
808
809 # Post-processing of all filerevs we skipped because they were
810 # filtered. If such filerevs have known and unfiltered children, this
811 # means they have an unfiltered appearance out there. We'll use linkrev
812 # adjustment to find one of these appearances. The lowest known child
813 # will be used as a starting point because it is the best upper-bound we
814 # have.
815 #
816 # This approach will fail when an unfiltered but linkrev-shadowed
817 # appearance exists in a head changeset without unfiltered filerev
818 # children anywhere.
819 while delayed:
820 # must be a descending iteration. To slowly fill lowest child
821 # information that is of potential use by the next item.
822 fr, rev = delayed.pop()
823 lkr = rev
824
825 child = lowestchild.get(fr)
826
827 if child is None:
828 # XXX content could be linkrev-shadowed in a head, but lets
829 # ignore this case for now.
830 continue
831 else:
832 # the lowest known child is a good upper bound
833 childcrev = backrevref[child]
834 # XXX this does not guarantee returning the lowest
835 # introduction of this revision, but this gives a
836 # result which is a good start and will fit in most
837 # cases. We probably need to fix the multiple
838 # introductions case properly (report each
839 # introduction, even for identical file revisions)
840 # once and for all at some point anyway.
841 for p in repo[childcrev][f].parents():
842 if p.filerev() == fr:
843 rev = p.rev()
844 break
845 if rev == lkr: # no shadowed entry found
846 # XXX This should never happen unless some manifest points
847 # to biggish file revisions (like a revision that uses a
848 # parent that never appears in the manifest ancestors)
849 continue
850
851 # Fill the data for the next iteration.
852 for p in fl.parentrevs(fr):
853 if 0 <= p and p not in lowestchild:
854 lowestchild[p] = fr
855 backrevref[fr] = rev
856 s.add(rev)
792
857
793 return subset & s
858 return subset & s
794
859
@@ -1673,4 +1673,56 b' hg log -f from the grafted changeset'
1673 date: Thu Jan 01 00:00:00 1970 +0000
1673 date: Thu Jan 01 00:00:00 1970 +0000
1674 summary: content1
1674 summary: content1
1675
1675
1676
1677 Test that we use the first non-hidden changeset in that case.
1678
1679 (hide the changeset)
1680
1681 $ hg log -T '{node}\n' -r 1
1682 2294ae80ad8447bc78383182eeac50cb049df623
1683 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
1684 $ hg log -G
1685 o changeset: 4:50b9b36e9c5d
1686 | tag: tip
1687 | user: test
1688 | date: Thu Jan 01 00:00:00 1970 +0000
1689 | summary: content3
1690 |
1691 @ changeset: 3:15b2327059e5
1692 | user: test
1693 | date: Thu Jan 01 00:00:00 1970 +0000
1694 | summary: content2
1695 |
1696 o changeset: 2:2029acd1168c
1697 | parent: 0:ae0a3c9f9e95
1698 | user: test
1699 | date: Thu Jan 01 00:00:00 1970 +0000
1700 | summary: unrelated
1701 |
1702 o changeset: 0:ae0a3c9f9e95
1703 user: test
1704 date: Thu Jan 01 00:00:00 1970 +0000
1705 summary: content1
1706
1707
1708 Check that log on the file does not drop the file revision.
1709
1710 $ hg log -G a
1711 o changeset: 4:50b9b36e9c5d
1712 | tag: tip
1713 | user: test
1714 | date: Thu Jan 01 00:00:00 1970 +0000
1715 | summary: content3
1716 |
1717 @ changeset: 3:15b2327059e5
1718 | user: test
1719 | date: Thu Jan 01 00:00:00 1970 +0000
1720 | summary: content2
1721 |
1722 o changeset: 0:ae0a3c9f9e95
1723 user: test
1724 date: Thu Jan 01 00:00:00 1970 +0000
1725 summary: content1
1726
1727
1676 $ cd ..
1728 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now