mercurial/repoview.py
changeset 43540 bad4a26b4607
parent 43506 c8e5b3094a1d
child 43554 9f70512ae2cf
equal deleted inserted replaced
43539:9391784299e9 43540:bad4a26b4607
   225 
   225 
   226 def wrapchangelog(unfichangelog, filteredrevs):
   226 def wrapchangelog(unfichangelog, filteredrevs):
   227     cl = copy.copy(unfichangelog)
   227     cl = copy.copy(unfichangelog)
   228     cl.filteredrevs = filteredrevs
   228     cl.filteredrevs = filteredrevs
   229 
   229 
   230     class filteredchangelog(cl.__class__):
   230     cl.__class__ = type(
   231         def tiprev(self):
   231         'filteredchangelog', (filteredchangelogmixin, cl.__class__), {}
   232             """filtered version of revlog.tiprev"""
   232     )
   233             for i in pycompat.xrange(len(self) - 1, -2, -1):
   233 
   234                 if i not in self.filteredrevs:
   234     return cl
   235                     return i
   235 
   236 
   236 
   237         def __contains__(self, rev):
   237 class filteredchangelogmixin(object):
   238             """filtered version of revlog.__contains__"""
   238     def tiprev(self):
   239             return 0 <= rev < len(self) and rev not in self.filteredrevs
   239         """filtered version of revlog.tiprev"""
   240 
   240         for i in pycompat.xrange(len(self) - 1, -2, -1):
   241         def __iter__(self):
   241             if i not in self.filteredrevs:
   242             """filtered version of revlog.__iter__"""
   242                 return i
   243 
   243 
   244             def filterediter():
   244     def __contains__(self, rev):
   245                 for i in pycompat.xrange(len(self)):
   245         """filtered version of revlog.__contains__"""
   246                     if i not in self.filteredrevs:
   246         return 0 <= rev < len(self) and rev not in self.filteredrevs
   247                         yield i
   247 
   248 
   248     def __iter__(self):
   249             return filterediter()
   249         """filtered version of revlog.__iter__"""
   250 
   250 
   251         def revs(self, start=0, stop=None):
   251         def filterediter():
   252             """filtered version of revlog.revs"""
   252             for i in pycompat.xrange(len(self)):
   253             for i in super(filteredchangelog, self).revs(start, stop):
       
   254                 if i not in self.filteredrevs:
   253                 if i not in self.filteredrevs:
   255                     yield i
   254                     yield i
   256 
   255 
   257         def _checknofilteredinrevs(self, revs):
   256         return filterediter()
   258             """raise the appropriate error if 'revs' contains a filtered revision
   257 
   259 
   258     def revs(self, start=0, stop=None):
   260             This returns a version of 'revs' to be used thereafter by the caller.
   259         """filtered version of revlog.revs"""
   261             In particular, if revs is an iterator, it is converted into a set.
   260         for i in super(filteredchangelogmixin, self).revs(start, stop):
   262             """
   261             if i not in self.filteredrevs:
   263             safehasattr = util.safehasattr
   262                 yield i
   264             if safehasattr(revs, '__next__'):
   263 
   265                 # Note that inspect.isgenerator() is not true for iterators,
   264     def _checknofilteredinrevs(self, revs):
   266                 revs = set(revs)
   265         """raise the appropriate error if 'revs' contains a filtered revision
   267 
   266 
   268             filteredrevs = self.filteredrevs
   267         This returns a version of 'revs' to be used thereafter by the caller.
   269             if safehasattr(revs, 'first'):  # smartset
   268         In particular, if revs is an iterator, it is converted into a set.
   270                 offenders = revs & filteredrevs
   269         """
   271             else:
   270         safehasattr = util.safehasattr
   272                 offenders = filteredrevs.intersection(revs)
   271         if safehasattr(revs, '__next__'):
   273 
   272             # Note that inspect.isgenerator() is not true for iterators,
   274             for rev in offenders:
   273             revs = set(revs)
   275                 raise error.FilteredIndexError(rev)
   274 
   276             return revs
   275         filteredrevs = self.filteredrevs
   277 
   276         if safehasattr(revs, 'first'):  # smartset
   278         def headrevs(self, revs=None):
   277             offenders = revs & filteredrevs
   279             if revs is None:
   278         else:
   280                 try:
   279             offenders = filteredrevs.intersection(revs)
   281                     return self.index.headrevsfiltered(self.filteredrevs)
   280 
   282                 # AttributeError covers non-c-extension environments and
   281         for rev in offenders:
   283                 # old c extensions without filter handling.
   282             raise error.FilteredIndexError(rev)
   284                 except AttributeError:
   283         return revs
   285                     return self._headrevs()
   284 
   286 
   285     def headrevs(self, revs=None):
   287             revs = self._checknofilteredinrevs(revs)
   286         if revs is None:
   288             return super(filteredchangelog, self).headrevs(revs)
   287             try:
   289 
   288                 return self.index.headrevsfiltered(self.filteredrevs)
   290         def strip(self, *args, **kwargs):
   289             # AttributeError covers non-c-extension environments and
   291             # XXX make something better than assert
   290             # old c extensions without filter handling.
   292             # We can't expect proper strip behavior if we are filtered.
   291             except AttributeError:
   293             assert not self.filteredrevs
   292                 return self._headrevs()
   294             super(filteredchangelog, self).strip(*args, **kwargs)
   293 
   295 
   294         revs = self._checknofilteredinrevs(revs)
   296         def rev(self, node):
   295         return super(filteredchangelogmixin, self).headrevs(revs)
   297             """filtered version of revlog.rev"""
   296 
   298             r = super(filteredchangelog, self).rev(node)
   297     def strip(self, *args, **kwargs):
   299             if r in self.filteredrevs:
   298         # XXX make something better than assert
   300                 raise error.FilteredLookupError(
   299         # We can't expect proper strip behavior if we are filtered.
   301                     hex(node), self.indexfile, _(b'filtered node')
   300         assert not self.filteredrevs
   302                 )
   301         super(filteredchangelogmixin, self).strip(*args, **kwargs)
   303             return r
   302 
   304 
   303     def rev(self, node):
   305         def node(self, rev):
   304         """filtered version of revlog.rev"""
   306             """filtered version of revlog.node"""
   305         r = super(filteredchangelogmixin, self).rev(node)
   307             if rev in self.filteredrevs:
   306         if r in self.filteredrevs:
   308                 raise error.FilteredIndexError(rev)
   307             raise error.FilteredLookupError(
   309             return super(filteredchangelog, self).node(rev)
   308                 hex(node), self.indexfile, _(b'filtered node')
   310 
   309             )
   311         def linkrev(self, rev):
   310         return r
   312             """filtered version of revlog.linkrev"""
   311 
   313             if rev in self.filteredrevs:
   312     def node(self, rev):
   314                 raise error.FilteredIndexError(rev)
   313         """filtered version of revlog.node"""
   315             return super(filteredchangelog, self).linkrev(rev)
   314         if rev in self.filteredrevs:
   316 
   315             raise error.FilteredIndexError(rev)
   317         def parentrevs(self, rev):
   316         return super(filteredchangelogmixin, self).node(rev)
   318             """filtered version of revlog.parentrevs"""
   317 
   319             if rev in self.filteredrevs:
   318     def linkrev(self, rev):
   320                 raise error.FilteredIndexError(rev)
   319         """filtered version of revlog.linkrev"""
   321             return super(filteredchangelog, self).parentrevs(rev)
   320         if rev in self.filteredrevs:
   322 
   321             raise error.FilteredIndexError(rev)
   323         def flags(self, rev):
   322         return super(filteredchangelogmixin, self).linkrev(rev)
   324             """filtered version of revlog.flags"""
   323 
   325             if rev in self.filteredrevs:
   324     def parentrevs(self, rev):
   326                 raise error.FilteredIndexError(rev)
   325         """filtered version of revlog.parentrevs"""
   327             return super(filteredchangelog, self).flags(rev)
   326         if rev in self.filteredrevs:
   328 
   327             raise error.FilteredIndexError(rev)
   329     cl.__class__ = filteredchangelog
   328         return super(filteredchangelogmixin, self).parentrevs(rev)
   330 
   329 
   331     return cl
   330     def flags(self, rev):
       
   331         """filtered version of revlog.flags"""
       
   332         if rev in self.filteredrevs:
       
   333             raise error.FilteredIndexError(rev)
       
   334         return super(filteredchangelogmixin, self).flags(rev)
   332 
   335 
   333 
   336 
   334 class repoview(object):
   337 class repoview(object):
   335     """Provide a read/write view of a repo through a filtered changelog
   338     """Provide a read/write view of a repo through a filtered changelog
   336 
   339