| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='test index-pack handling of delta cycles in packfiles' |
| 4 | |
| 5 | . ./test-lib.sh |
| 6 | . "$TEST_DIRECTORY"/lib-pack.sh |
| 7 | |
| 8 | # Two similar-ish objects that we have computed deltas between. |
| 9 | A=$(test_oid packlib_7_0) |
| 10 | B=$(test_oid packlib_7_76) |
| 11 | |
| 12 | # double-check our hand-constucted packs |
| 13 | test_expect_success 'index-pack works with a single delta (A->B)' ' |
| 14 | clear_packs && |
| 15 | { |
| 16 | pack_header 2 && |
| 17 | pack_obj $A $B && |
| 18 | pack_obj $B |
| 19 | } >ab.pack && |
| 20 | pack_trailer ab.pack && |
| 21 | git index-pack --stdin <ab.pack && |
| 22 | git cat-file -t $A && |
| 23 | git cat-file -t $B |
| 24 | ' |
| 25 | |
| 26 | test_expect_success 'index-pack works with a single delta (B->A)' ' |
| 27 | clear_packs && |
| 28 | { |
| 29 | pack_header 2 && |
| 30 | pack_obj $A && |
| 31 | pack_obj $B $A |
| 32 | } >ba.pack && |
| 33 | pack_trailer ba.pack && |
| 34 | git index-pack --stdin <ba.pack && |
| 35 | git cat-file -t $A && |
| 36 | git cat-file -t $B |
| 37 | ' |
| 38 | |
| 39 | test_expect_success 'index-pack detects missing base objects' ' |
| 40 | clear_packs && |
| 41 | { |
| 42 | pack_header 1 && |
| 43 | pack_obj $A $B |
| 44 | } >missing.pack && |
| 45 | pack_trailer missing.pack && |
| 46 | test_must_fail git index-pack --fix-thin --stdin <missing.pack |
| 47 | ' |
| 48 | |
| 49 | test_expect_success 'index-pack detects REF_DELTA cycles' ' |
| 50 | clear_packs && |
| 51 | { |
| 52 | pack_header 2 && |
| 53 | pack_obj $A $B && |
| 54 | pack_obj $B $A |
| 55 | } >cycle.pack && |
| 56 | pack_trailer cycle.pack && |
| 57 | test_must_fail git index-pack --fix-thin --stdin <cycle.pack |
| 58 | ' |
| 59 | |
| 60 | test_expect_success 'failover to an object in another pack' ' |
| 61 | clear_packs && |
| 62 | git index-pack --stdin <ab.pack && |
| 63 | |
| 64 | # This cycle does not fail since the existence of A & B in |
| 65 | # the repo allows us to resolve the cycle. |
| 66 | git index-pack --stdin --fix-thin <cycle.pack |
| 67 | ' |
| 68 | |
| 69 | test_expect_success 'failover to a duplicate object in the same pack' ' |
| 70 | clear_packs && |
| 71 | { |
| 72 | pack_header 3 && |
| 73 | pack_obj $A $B && |
| 74 | pack_obj $B $A && |
| 75 | pack_obj $A |
| 76 | } >recoverable.pack && |
| 77 | pack_trailer recoverable.pack && |
| 78 | |
| 79 | # This cycle does not fail since the existence of a full copy |
| 80 | # of A in the pack allows us to resolve the cycle. |
| 81 | git index-pack --fix-thin --stdin <recoverable.pack |
| 82 | ' |
| 83 | |
| 84 | test_expect_success 'index-pack works with thin pack A->B->C with B on disk' ' |
| 85 | git init server && |
| 86 | ( |
| 87 | cd server && |
| 88 | test_commit_bulk 4 |
| 89 | ) && |
| 90 | |
| 91 | A=$(git -C server rev-parse HEAD^{tree}) && |
| 92 | B=$(git -C server rev-parse HEAD~1^{tree}) && |
| 93 | C=$(git -C server rev-parse HEAD~2^{tree}) && |
| 94 | git -C server reset --hard HEAD~1 && |
| 95 | |
| 96 | test-tool -C server pack-deltas --num-objects=2 >thin.pack <<-EOF && |
| 97 | REF_DELTA $A $B |
| 98 | REF_DELTA $B $C |
| 99 | EOF |
| 100 | |
| 101 | git clone "file://$(pwd)/server" client && |
| 102 | ( |
| 103 | cd client && |
| 104 | git index-pack --fix-thin --stdin <../thin.pack |
| 105 | ) |
| 106 | ' |
| 107 | |
| 108 | test_done |