393 |
398 |
394 for rev in revs: |
399 for rev in revs: |
395 if rev == nullrev: |
400 if rev == nullrev: |
396 continue |
401 continue |
397 |
402 |
|
403 debug_delta_source = None |
|
404 if debug_info is not None: |
|
405 debug_info['revision-total'] += 1 |
|
406 |
398 node = fnode(rev) |
407 node = fnode(rev) |
399 p1rev, p2rev = store.parentrevs(rev) |
408 p1rev, p2rev = store.parentrevs(rev) |
400 |
409 |
|
410 if debug_info is not None: |
|
411 if p1rev != p2rev and p1rev != nullrev and p2rev != nullrev: |
|
412 debug_info['merge-total'] += 1 |
|
413 |
401 if deltaparentfn: |
414 if deltaparentfn: |
402 deltaparentrev = deltaparentfn(rev) |
415 deltaparentrev = deltaparentfn(rev) |
|
416 if debug_info is not None: |
|
417 if deltaparentrev == nullrev: |
|
418 debug_info['available-full'] += 1 |
|
419 else: |
|
420 debug_info['available-delta'] += 1 |
|
421 |
403 else: |
422 else: |
404 deltaparentrev = nullrev |
423 deltaparentrev = nullrev |
405 |
424 |
406 # Forced delta against previous mode. |
425 # Forced delta against previous mode. |
407 if deltamode == repository.CG_DELTAMODE_PREV: |
426 if deltamode == repository.CG_DELTAMODE_PREV: |
|
427 if debug_info is not None: |
|
428 debug_delta_source = "prev" |
408 baserev = prevrev |
429 baserev = prevrev |
409 |
430 |
410 # We're instructed to send fulltext. Honor that. |
431 # We're instructed to send fulltext. Honor that. |
411 elif deltamode == repository.CG_DELTAMODE_FULL: |
432 elif deltamode == repository.CG_DELTAMODE_FULL: |
|
433 if debug_info is not None: |
|
434 debug_delta_source = "full" |
412 baserev = nullrev |
435 baserev = nullrev |
413 # We're instructed to use p1. Honor that |
436 # We're instructed to use p1. Honor that |
414 elif deltamode == repository.CG_DELTAMODE_P1: |
437 elif deltamode == repository.CG_DELTAMODE_P1: |
|
438 if debug_info is not None: |
|
439 debug_delta_source = "p1" |
415 baserev = p1rev |
440 baserev = p1rev |
416 |
441 |
417 # There is a delta in storage. We try to use that because it |
442 # There is a delta in storage. We try to use that because it |
418 # amounts to effectively copying data from storage and is |
443 # amounts to effectively copying data from storage and is |
419 # therefore the fastest. |
444 # therefore the fastest. |
420 elif deltaparentrev != nullrev: |
445 elif deltaparentrev != nullrev: |
421 # Base revision was already emitted in this group. We can |
446 # Base revision was already emitted in this group. We can |
422 # always safely use the delta. |
447 # always safely use the delta. |
423 if deltaparentrev in available: |
448 if deltaparentrev in available: |
|
449 if debug_info is not None: |
|
450 debug_delta_source = "storage" |
424 baserev = deltaparentrev |
451 baserev = deltaparentrev |
425 |
452 |
426 # Base revision is a parent that hasn't been emitted already. |
453 # Base revision is a parent that hasn't been emitted already. |
427 # Use it if we can assume the receiver has the parent revision. |
454 # Use it if we can assume the receiver has the parent revision. |
428 elif assumehaveparentrevisions and deltaparentrev in (p1rev, p2rev): |
455 elif assumehaveparentrevisions and deltaparentrev in (p1rev, p2rev): |
|
456 if debug_info is not None: |
|
457 debug_delta_source = "storage" |
429 baserev = deltaparentrev |
458 baserev = deltaparentrev |
430 |
|
431 # No guarantee the receiver has the delta parent. Send delta |
459 # No guarantee the receiver has the delta parent. Send delta |
432 # against last revision (if possible), which in the common case |
460 # against last revision (if possible), which in the common case |
433 # should be similar enough to this revision that the delta is |
461 # should be similar enough to this revision that the delta is |
434 # reasonable. |
462 # reasonable. |
435 elif prevrev is not None: |
463 elif prevrev is not None: |
|
464 if debug_info is not None: |
|
465 debug_info['denied-base-not-available'] += 1 |
|
466 debug_delta_source = "prev" |
436 baserev = prevrev |
467 baserev = prevrev |
437 else: |
468 else: |
|
469 if debug_info is not None: |
|
470 debug_info['denied-base-not-available'] += 1 |
|
471 debug_delta_source = "full" |
438 baserev = nullrev |
472 baserev = nullrev |
439 |
473 |
440 # Storage has a fulltext revision. |
474 # Storage has a fulltext revision. |
441 |
475 |
442 # Let's use the previous revision, which is as good a guess as any. |
476 # Let's use the previous revision, which is as good a guess as any. |
443 # There is definitely room to improve this logic. |
477 # There is definitely room to improve this logic. |
444 elif prevrev is not None: |
478 elif prevrev is not None: |
|
479 if debug_info is not None: |
|
480 debug_delta_source = "prev" |
445 baserev = prevrev |
481 baserev = prevrev |
446 else: |
482 else: |
|
483 if debug_info is not None: |
|
484 debug_delta_source = "full" |
447 baserev = nullrev |
485 baserev = nullrev |
448 |
486 |
449 # But we can't actually use our chosen delta base for whatever |
487 # But we can't actually use our chosen delta base for whatever |
450 # reason. Reset to fulltext. |
488 # reason. Reset to fulltext. |
451 if baserev != nullrev and (candeltafn and not candeltafn(baserev, rev)): |
489 if ( |
|
490 baserev != nullrev |
|
491 and candeltafn is not None |
|
492 and not candeltafn(baserev, rev) |
|
493 ): |
|
494 if debug_info is not None: |
|
495 debug_delta_source = "full" |
|
496 debug_info['denied-delta-candeltafn'] += 1 |
452 baserev = nullrev |
497 baserev = nullrev |
453 |
498 |
454 revision = None |
499 revision = None |
455 delta = None |
500 delta = None |
456 baserevisionsize = None |
501 baserevisionsize = None |
469 baserevisionsize = len(store.rawdata(baserev)) |
517 baserevisionsize = len(store.rawdata(baserev)) |
470 |
518 |
471 elif ( |
519 elif ( |
472 baserev == nullrev and deltamode != repository.CG_DELTAMODE_PREV |
520 baserev == nullrev and deltamode != repository.CG_DELTAMODE_PREV |
473 ): |
521 ): |
|
522 if debug_info is not None: |
|
523 debug_info['computed-delta'] += 1 # close enough |
|
524 debug_info['delta-full'] += 1 |
474 revision = store.rawdata(node) |
525 revision = store.rawdata(node) |
475 available.add(rev) |
526 available.add(rev) |
476 else: |
527 else: |
477 if revdifffn: |
528 if revdifffn: |
|
529 if debug_info is not None: |
|
530 if debug_delta_source == "full": |
|
531 debug_info['computed-delta'] += 1 |
|
532 debug_info['delta-full'] += 1 |
|
533 elif debug_delta_source == "prev": |
|
534 debug_info['computed-delta'] += 1 |
|
535 debug_info['delta-against-prev'] += 1 |
|
536 elif debug_delta_source == "p1": |
|
537 debug_info['computed-delta'] += 1 |
|
538 debug_info['delta-against-p1'] += 1 |
|
539 elif debug_delta_source == "storage": |
|
540 debug_info['reused-storage-delta'] += 1 |
|
541 else: |
|
542 assert False, 'unreachable' |
|
543 |
478 delta = revdifffn(baserev, rev) |
544 delta = revdifffn(baserev, rev) |
479 else: |
545 else: |
|
546 if debug_info is not None: |
|
547 if debug_delta_source == "full": |
|
548 debug_info['computed-delta'] += 1 |
|
549 debug_info['delta-full'] += 1 |
|
550 elif debug_delta_source == "prev": |
|
551 debug_info['computed-delta'] += 1 |
|
552 debug_info['delta-against-prev'] += 1 |
|
553 elif debug_delta_source == "p1": |
|
554 debug_info['computed-delta'] += 1 |
|
555 debug_info['delta-against-p1'] += 1 |
|
556 elif debug_delta_source == "storage": |
|
557 # seem quite unlikelry to happens |
|
558 debug_info['computed-delta'] += 1 |
|
559 debug_info['reused-storage-delta'] += 1 |
|
560 else: |
|
561 assert False, 'unreachable' |
480 delta = mdiff.textdiff( |
562 delta = mdiff.textdiff( |
481 store.rawdata(baserev), store.rawdata(rev) |
563 store.rawdata(baserev), store.rawdata(rev) |
482 ) |
564 ) |
483 |
565 |
484 available.add(rev) |
566 available.add(rev) |