@@ -342,4 +342,97 @@ test_expect_success 'truncated bitmap fails gracefully' '
342
342
test_i18ngrep corrupt stderr
343
343
'
344
344
345
+ # have_delta <obj> <expected_base>
346
+ #
347
+ # Note that because this relies on cat-file, it might find _any_ copy of an
348
+ # object in the repository. The caller is responsible for making sure
349
+ # there's only one (e.g., via "repack -ad", or having just fetched a copy).
350
+ have_delta () {
351
+ echo $2 > expect &&
352
+ echo $1 | git cat-file --batch-check=" %(deltabase)" > actual &&
353
+ test_cmp expect actual
354
+ }
355
+
356
+ # Create a state of history with these properties:
357
+ #
358
+ # - refs that allow a client to fetch some new history, while sharing some old
359
+ # history with the server; we use branches delta-reuse-old and
360
+ # delta-reuse-new here
361
+ #
362
+ # - the new history contains an object that is stored on the server as a delta
363
+ # against a base that is in the old history
364
+ #
365
+ # - the base object is not immediately reachable from the tip of the old
366
+ # history; finding it would involve digging down through history we know the
367
+ # other side has
368
+ #
369
+ # This should result in a state where fetching from old->new would not
370
+ # traditionally reuse the on-disk delta (because we'd have to dig to realize
371
+ # that the client has it), but we will do so if bitmaps can tell us cheaply
372
+ # that the other side has it.
373
+ test_expect_success ' set up thin delta-reuse parent' '
374
+ # This first commit contains the buried base object.
375
+ test-tool genrandom delta 16384 >file &&
376
+ git add file &&
377
+ git commit -m "delta base" &&
378
+ base=$(git rev-parse --verify HEAD:file) &&
379
+
380
+ # These intermediate commits bury the base back in history.
381
+ # This becomes the "old" state.
382
+ for i in 1 2 3 4 5
383
+ do
384
+ echo $i >file &&
385
+ git commit -am "intermediate $i" || return 1
386
+ done &&
387
+ git branch delta-reuse-old &&
388
+
389
+ # And now our new history has a delta against the buried base. Note
390
+ # that this must be smaller than the original file, since pack-objects
391
+ # prefers to create deltas from smaller objects to larger.
392
+ test-tool genrandom delta 16300 >file &&
393
+ git commit -am "delta result" &&
394
+ delta=$(git rev-parse --verify HEAD:file) &&
395
+ git branch delta-reuse-new &&
396
+
397
+ # Repack with bitmaps and double check that we have the expected delta
398
+ # relationship.
399
+ git repack -adb &&
400
+ have_delta $delta $base
401
+ '
402
+
403
+ # Now we can sanity-check the non-bitmap behavior (that the server is not able
404
+ # to reuse the delta). This isn't strictly something we care about, so this
405
+ # test could be scrapped in the future. But it makes sure that the next test is
406
+ # actually triggering the feature we want.
407
+ #
408
+ # Note that our tools for working with on-the-wire "thin" packs are limited. So
409
+ # we actually perform the fetch, retain the resulting pack, and inspect the
410
+ # result.
411
+ test_expect_success ' fetch without bitmaps ignores delta against old base' '
412
+ test_config pack.usebitmaps false &&
413
+ test_when_finished "rm -rf client.git" &&
414
+ git init --bare client.git &&
415
+ (
416
+ cd client.git &&
417
+ git config transfer.unpackLimit 1 &&
418
+ git fetch .. delta-reuse-old:delta-reuse-old &&
419
+ git fetch .. delta-reuse-new:delta-reuse-new &&
420
+ have_delta $delta $ZERO_OID
421
+ )
422
+ '
423
+
424
+ # And do the same for the bitmap case, where we do expect to find the delta.
425
+ test_expect_success ' fetch with bitmaps can reuse old base' '
426
+ test_config pack.usebitmaps true &&
427
+ test_when_finished "rm -rf client.git" &&
428
+ git init --bare client.git &&
429
+ (
430
+ cd client.git &&
431
+ git config transfer.unpackLimit 1 &&
432
+ git fetch .. delta-reuse-old:delta-reuse-old &&
433
+ git fetch .. delta-reuse-new:delta-reuse-new &&
434
+ have_delta $delta $base
435
+ )
436
+ '
437
+
345
438
test_done
0 commit comments