Jeff King | 7dbabbb | 2017-01-27 19:09:59 -0500 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='pack-objects breaks long cross-pack delta chains' |
| 4 | . ./test-lib.sh |
| 5 | |
| 6 | # This mirrors a repeated push setup: |
| 7 | # |
| 8 | # 1. A client repeatedly modifies some files, makes a |
| 9 | # commit, and pushes the result. It does this N times |
| 10 | # before we get around to repacking. |
| 11 | # |
| 12 | # 2. Each push generates a thin pack with the new version of |
| 13 | # various objects. Let's consider some file in the root tree |
| 14 | # which is updated in each commit. |
| 15 | # |
| 16 | # When generating push number X, we feed commit X-1 (and |
| 17 | # thus blob X-1) as a preferred base. The resulting pack has |
| 18 | # blob X as a thin delta against blob X-1. |
| 19 | # |
| 20 | # On the receiving end, "index-pack --fix-thin" will |
| 21 | # complete the pack with a base copy of blob X-1. |
| 22 | # |
| 23 | # 3. In older versions of git, if we used the delta from |
| 24 | # pack X, then we'd always find blob X-1 as a base in the |
| 25 | # same pack (and generate a fresh delta). |
| 26 | # |
| 27 | # But with the pack mru, we jump from delta to delta |
| 28 | # following the traversal order: |
| 29 | # |
| 30 | # a. We grab blob X from pack X as a delta, putting it at |
| 31 | # the tip of our mru list. |
| 32 | # |
| 33 | # b. Eventually we move onto commit X-1. We need other |
| 34 | # objects which are only in pack X-1 (in the test code |
| 35 | # below, it's the containing tree). That puts pack X-1 |
| 36 | # at the tip of our mru list. |
| 37 | # |
| 38 | # c. Eventually we look for blob X-1, and we find the |
| 39 | # version in pack X-1 (because it's the mru tip). |
| 40 | # |
| 41 | # Now we have blob X as a delta against X-1, which is a delta |
| 42 | # against X-2, and so forth. |
| 43 | # |
| 44 | # In the real world, these small pushes would get exploded by |
| 45 | # unpack-objects rather than "index-pack --fix-thin", but the |
| 46 | # same principle applies to larger pushes (they only need one |
| 47 | # repeatedly-modified file to generate the delta chain). |
| 48 | |
| 49 | test_expect_success 'create series of packs' ' |
| 50 | test-genrandom foo 4096 >content && |
| 51 | prev= && |
| 52 | for i in $(test_seq 1 10) |
| 53 | do |
| 54 | cat content >file && |
| 55 | echo $i >>file && |
| 56 | git add file && |
| 57 | git commit -m $i && |
| 58 | cur=$(git rev-parse HEAD^{tree}) && |
| 59 | { |
| 60 | test -n "$prev" && echo "-$prev" |
| 61 | echo $cur |
| 62 | echo "$(git rev-parse :file) file" |
| 63 | } | git pack-objects --stdout >tmp && |
| 64 | git index-pack --stdin --fix-thin <tmp || return 1 |
| 65 | prev=$cur |
| 66 | done |
| 67 | ' |
| 68 | |
| 69 | max_chain() { |
| 70 | git index-pack --verify-stat-only "$1" >output && |
| 71 | perl -lne ' |
| 72 | /chain length = (\d+)/ and $len = $1; |
| 73 | END { print $len } |
| 74 | ' output |
| 75 | } |
| 76 | |
| 77 | # Note that this whole setup is pretty reliant on the current |
| 78 | # packing heuristics. We double-check that our test case |
| 79 | # actually produces a long chain. If it doesn't, it should be |
| 80 | # adjusted (or scrapped if the heuristics have become too unreliable) |
| 81 | test_expect_success 'packing produces a long delta' ' |
| 82 | # Use --window=0 to make sure we are seeing reused deltas, |
| 83 | # not computing a new long chain. |
| 84 | pack=$(git pack-objects --all --window=0 </dev/null pack) && |
Ævar Arnfjörð Bjarmason | 0d75bfe | 2017-05-05 18:19:32 +0000 | [diff] [blame] | 85 | echo 9 >expect && |
| 86 | max_chain pack-$pack.pack >actual && |
| 87 | test_i18ncmp expect actual |
Jeff King | 7dbabbb | 2017-01-27 19:09:59 -0500 | [diff] [blame] | 88 | ' |
| 89 | |
| 90 | test_expect_success '--depth limits depth' ' |
| 91 | pack=$(git pack-objects --all --depth=5 </dev/null pack) && |
Ævar Arnfjörð Bjarmason | 0d75bfe | 2017-05-05 18:19:32 +0000 | [diff] [blame] | 92 | echo 5 >expect && |
| 93 | max_chain pack-$pack.pack >actual && |
| 94 | test_i18ncmp expect actual |
Jeff King | 7dbabbb | 2017-01-27 19:09:59 -0500 | [diff] [blame] | 95 | ' |
| 96 | |
| 97 | test_done |