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 |