Mercurial > evolve
comparison hgext/obsolete.py @ 448:96c896f0180b
obsolete: some more movement
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Tue, 07 Aug 2012 21:39:55 +0200 |
parents | fa85e7205e0b |
children | 4f23f224afb4 |
comparison
equal
deleted
inserted
replaced
447:fa85e7205e0b | 448:96c896f0180b |
---|---|
340 @cachefor('extinct') | 340 @cachefor('extinct') |
341 def _computeextinctset(repo): | 341 def _computeextinctset(repo): |
342 """the set of obsolete parent without non obsolete descendant""" | 342 """the set of obsolete parent without non obsolete descendant""" |
343 return set(repo.revs('obsolete() - obsolete()::unstable()')) | 343 return set(repo.revs('obsolete() - obsolete()::unstable()')) |
344 | 344 |
345 @eh.wrapfunction(obsolete.obsstore, '__init__') | |
346 def _initobsstorecache(orig, obsstore, *args, **kwargs): | |
347 """add a caches attributes to obsstore""" | |
348 obsstore.caches = {} | |
349 return orig(obsstore, *args, **kwargs) | |
350 | |
351 def getobscache(repo, name): | |
352 if not repo.obsstore: | |
353 return () | |
354 if name not in repo.obsstore.caches: | |
355 repo.obsstore.caches[name] = computecache[name](repo) | |
356 return repo.obsstore.caches[name] | |
357 | |
358 | |
359 ### cache clean up | |
360 def clearobscaches(repo): | |
361 #if 'obsstore' in vars(repo): | |
362 # should work great but cache invalidation act strange | |
363 repo.obsstore.caches.clear() | |
364 | |
365 @eh.wrapfunction(localrepo.localrepository, 'updatebranchcache') | |
366 @eh.wrapfunction(phases, 'advanceboundary') | |
367 def wrapclearcache(orig, repo, *args, **kwargs): | |
368 try: | |
369 return orig(repo, *args, **kwargs) | |
370 finally: | |
371 clearobscaches(repo) | |
372 | |
373 @eh.wrapfunction(obsolete.obsstore, 'add') | |
374 def clearonadd(orig, obsstore, *args, **kwargs): | |
375 try: | |
376 return orig(obsstore, *args, **kwargs) | |
377 finally: | |
378 obsstore.caches.clear() | |
379 | |
380 ### cache user | |
381 | |
382 @eh.addattr(context.changectx, 'unstable') | |
383 def unstable(ctx): | |
384 """is the changeset unstable (have obsolete ancestor)""" | |
385 if ctx.node() is None: | |
386 return False | |
387 return ctx.rev() in getobscache(ctx._repo, 'unstable') | |
388 | |
389 | |
390 @eh.addattr(context.changectx, 'extinct') | |
391 def extinct(ctx): | |
392 """is the changeset extinct by other""" | |
393 if ctx.node() is None: | |
394 return False | |
395 return ctx.rev() in getobscache(ctx._repo, 'extinct') | |
396 | |
397 @eh.revset('obsolete') | |
398 def revsetobsolete(repo, subset, x): | |
399 """``obsolete()`` | |
400 Changeset is obsolete. | |
401 """ | |
402 args = revset.getargs(x, 0, 0, 'obsolete takes no argument') | |
403 obsoletes = getobscache(repo, 'obsolete') | |
404 return [r for r in subset if r in obsoletes] | |
405 | |
406 @eh.revset('unstable') | |
407 def revsetunstable(repo, subset, x): | |
408 """``unstable()`` | |
409 Unstable changesets are non-obsolete with obsolete ancestors. | |
410 """ | |
411 args = revset.getargs(x, 0, 0, 'unstable takes no arguments') | |
412 unstables = getobscache(repo, 'unstable') | |
413 return [r for r in subset if r in unstables] | |
414 | |
415 @eh.revset('extinct') | |
416 def revsetextinct(repo, subset, x): | |
417 """``extinct()`` | |
418 Obsolete changesets with obsolete descendants only. | |
419 """ | |
420 args = revset.getargs(x, 0, 0, 'extinct takes no arguments') | |
421 extincts = getobscache(repo, 'extinct') | |
422 return [r for r in subset if r in extincts] | |
423 | |
424 ##################################################################### | |
425 ### Complete troubles computation logic ### | |
426 ##################################################################### | |
427 | |
345 @cachefor('latecomer') | 428 @cachefor('latecomer') |
346 def _computelatecomerset(repo): | 429 def _computelatecomerset(repo): |
347 """the set of rev trying to obsolete public revision""" | 430 """the set of rev trying to obsolete public revision""" |
348 query = 'allsuccessors(public()) - obsolete() - public()' | 431 query = 'allsuccessors(public()) - obsolete() - public()' |
349 return set(repo.revs(query)) | 432 return set(repo.revs(query)) |
366 conflicting.add(ctx.rev()) | 449 conflicting.add(ctx.rev()) |
367 break | 450 break |
368 toprocess.update(obsstore.successors.get(prec, ())) | 451 toprocess.update(obsstore.successors.get(prec, ())) |
369 return conflicting | 452 return conflicting |
370 | 453 |
371 @eh.wrapfunction(obsolete.obsstore, '__init__') | |
372 def _initobsstorecache(orig, obsstore, *args, **kwargs): | |
373 """add a caches attributes to obsstore""" | |
374 obsstore.caches = {} | |
375 return orig(obsstore, *args, **kwargs) | |
376 | |
377 def getobscache(repo, name): | |
378 if not repo.obsstore: | |
379 return () | |
380 if name not in repo.obsstore.caches: | |
381 repo.obsstore.caches[name] = computecache[name](repo) | |
382 return repo.obsstore.caches[name] | |
383 | |
384 | |
385 ### cache clean up | |
386 def clearobscaches(repo): | |
387 #if 'obsstore' in vars(repo): | |
388 # should work great but cache invalidation act strange | |
389 repo.obsstore.caches.clear() | |
390 | |
391 @eh.wrapfunction(localrepo.localrepository, 'updatebranchcache') | |
392 @eh.wrapfunction(phases, 'advanceboundary') | |
393 def wrapclearcache(orig, repo, *args, **kwargs): | |
394 try: | |
395 return orig(repo, *args, **kwargs) | |
396 finally: | |
397 clearobscaches(repo) | |
398 | |
399 @eh.wrapfunction(obsolete.obsstore, 'add') | |
400 def clearonadd(orig, obsstore, *args, **kwargs): | |
401 try: | |
402 return orig(obsstore, *args, **kwargs) | |
403 finally: | |
404 obsstore.caches.clear() | |
405 | |
406 ### cache user | |
407 | |
408 @eh.addattr(context.changectx, 'unstable') | |
409 def unstable(ctx): | |
410 """is the changeset unstable (have obsolete ancestor)""" | |
411 if ctx.node() is None: | |
412 return False | |
413 return ctx.rev() in getobscache(ctx._repo, 'unstable') | |
414 | |
415 | |
416 @eh.addattr(context.changectx, 'extinct') | |
417 def extinct(ctx): | |
418 """is the changeset extinct by other""" | |
419 if ctx.node() is None: | |
420 return False | |
421 return ctx.rev() in getobscache(ctx._repo, 'extinct') | |
422 | |
423 @eh.revset('obsolete') | |
424 def revsetobsolete(repo, subset, x): | |
425 """``obsolete()`` | |
426 Changeset is obsolete. | |
427 """ | |
428 args = revset.getargs(x, 0, 0, 'obsolete takes no argument') | |
429 obsoletes = getobscache(repo, 'obsolete') | |
430 return [r for r in subset if r in obsoletes] | |
431 | |
432 @eh.revset('unstable') | |
433 def revsetunstable(repo, subset, x): | |
434 """``unstable()`` | |
435 Unstable changesets are non-obsolete with obsolete ancestors. | |
436 """ | |
437 args = revset.getargs(x, 0, 0, 'unstable takes no arguments') | |
438 unstables = getobscache(repo, 'unstable') | |
439 return [r for r in subset if r in unstables] | |
440 | |
441 @eh.revset('extinct') | |
442 def revsetextinct(repo, subset, x): | |
443 """``extinct()`` | |
444 Obsolete changesets with obsolete descendants only. | |
445 """ | |
446 args = revset.getargs(x, 0, 0, 'extinct takes no arguments') | |
447 extincts = getobscache(repo, 'extinct') | |
448 return [r for r in subset if r in extincts] | |
449 | |
450 ##################################################################### | |
451 ### Complete troubles computation logic ### | |
452 ##################################################################### | |
453 | |
454 @eh.addattr(context.changectx, 'latecomer') | 454 @eh.addattr(context.changectx, 'latecomer') |
455 def latecomer(ctx): | 455 def latecomer(ctx): |
456 """is the changeset latecomer (Try to succeed to public change)""" | 456 """is the changeset latecomer (Try to succeed to public change)""" |
457 if ctx.node() is None: | 457 if ctx.node() is None: |
458 return False | 458 return False |
462 def conflicting(ctx): | 462 def conflicting(ctx): |
463 """is the changeset conflicting (Try to succeed to public change)""" | 463 """is the changeset conflicting (Try to succeed to public change)""" |
464 if ctx.node() is None: | 464 if ctx.node() is None: |
465 return False | 465 return False |
466 return ctx.rev() in getobscache(ctx._repo, 'conflicting') | 466 return ctx.rev() in getobscache(ctx._repo, 'conflicting') |
467 | |
468 ### Discovery wrapping | |
469 | |
470 @eh.wrapfunction(discovery, 'checkheads') | |
471 def wrapcheckheads(orig, repo, remote, outgoing, *args, **kwargs): | |
472 """wrap mercurial.discovery.checkheads | |
473 | |
474 * prevent unstability to be pushed | |
475 * patch remote to ignore obsolete heads on remote | |
476 """ | |
477 # do not push instability | |
478 for h in outgoing.missingheads: | |
479 # Checking heads is enough, obsolete descendants are either | |
480 # obsolete or unstable. | |
481 ctx = repo[h] | |
482 if ctx.latecomer(): | |
483 raise util.Abort(_("push includes a latecomer changeset: %s!") | |
484 % ctx) | |
485 if ctx.conflicting(): | |
486 raise util.Abort(_("push includes a conflicting changeset: %s!") | |
487 % ctx) | |
488 return orig(repo, remote, outgoing, *args, **kwargs) | |
467 | 489 |
468 | 490 |
469 ##################################################################### | 491 ##################################################################### |
470 ### Additional Utilities ### | 492 ### Additional Utilities ### |
471 ##################################################################### | 493 ##################################################################### |
705 ##################################################################### | 727 ##################################################################### |
706 ### Various trouble warning ### | 728 ### Various trouble warning ### |
707 ##################################################################### | 729 ##################################################################### |
708 | 730 |
709 | 731 |
710 ### Discovery wrapping | |
711 | |
712 @eh.wrapfunction(discovery, 'checkheads') | |
713 def wrapcheckheads(orig, repo, remote, outgoing, *args, **kwargs): | |
714 """wrap mercurial.discovery.checkheads | |
715 | |
716 * prevent unstability to be pushed | |
717 * patch remote to ignore obsolete heads on remote | |
718 """ | |
719 # do not push instability | |
720 for h in outgoing.missingheads: | |
721 # Checking heads is enough, obsolete descendants are either | |
722 # obsolete or unstable. | |
723 ctx = repo[h] | |
724 if ctx.latecomer(): | |
725 raise util.Abort(_("push includes a latecomer changeset: %s!") | |
726 % ctx) | |
727 if ctx.conflicting(): | |
728 raise util.Abort(_("push includes a conflicting changeset: %s!") | |
729 % ctx) | |
730 return orig(repo, remote, outgoing, *args, **kwargs) | |
731 | 732 |
732 @eh.wrapcommand("update") | 733 @eh.wrapcommand("update") |
733 @eh.wrapcommand("pull") | 734 @eh.wrapcommand("pull") |
734 def wrapmayobsoletewc(origfn, ui, repo, *args, **opts): | 735 def wrapmayobsoletewc(origfn, ui, repo, *args, **opts): |
735 res = origfn(ui, repo, *args, **opts) | 736 res = origfn(ui, repo, *args, **opts) |