]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5316-pack-delta-depth.sh
Merge branch 'ma/header-dup-cleanup'
[thirdparty/git.git] / t / t5316-pack-delta-depth.sh
CommitLineData
7dbabbbe
JK
1#!/bin/sh
2
3test_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
49test_expect_success 'create series of packs' '
c680668d 50 test-tool genrandom foo 4096 >content &&
7dbabbbe
JK
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 {
7abcbcb7
ES
60 if test -n "$prev"
61 then
62 echo "-$prev"
63 fi &&
64 echo $cur &&
7dbabbbe
JK
65 echo "$(git rev-parse :file) file"
66 } | git pack-objects --stdout >tmp &&
67 git index-pack --stdin --fix-thin <tmp || return 1
68 prev=$cur
69 done
70'
71
72max_chain() {
73 git index-pack --verify-stat-only "$1" >output &&
74 perl -lne '
49ac1d33 75 BEGIN { $len = 0 }
7dbabbbe
JK
76 /chain length = (\d+)/ and $len = $1;
77 END { print $len }
78 ' output
79}
80
81# Note that this whole setup is pretty reliant on the current
82# packing heuristics. We double-check that our test case
83# actually produces a long chain. If it doesn't, it should be
84# adjusted (or scrapped if the heuristics have become too unreliable)
85test_expect_success 'packing produces a long delta' '
86 # Use --window=0 to make sure we are seeing reused deltas,
87 # not computing a new long chain.
88 pack=$(git pack-objects --all --window=0 </dev/null pack) &&
0d75bfe6
ÆAB
89 echo 9 >expect &&
90 max_chain pack-$pack.pack >actual &&
1108cea7 91 test_cmp expect actual
7dbabbbe
JK
92'
93
94test_expect_success '--depth limits depth' '
95 pack=$(git pack-objects --all --depth=5 </dev/null pack) &&
0d75bfe6
ÆAB
96 echo 5 >expect &&
97 max_chain pack-$pack.pack >actual &&
1108cea7 98 test_cmp expect actual
7dbabbbe
JK
99'
100
49ac1d33
JK
101test_expect_success '--depth=0 disables deltas' '
102 pack=$(git pack-objects --all --depth=0 </dev/null pack) &&
103 echo 0 >expect &&
104 max_chain pack-$pack.pack >actual &&
105 test_cmp expect actual
106'
107
6d52b6a5
JK
108test_expect_success 'negative depth disables deltas' '
109 pack=$(git pack-objects --all --depth=-1 </dev/null pack) &&
110 echo 0 >expect &&
111 max_chain pack-$pack.pack >actual &&
112 test_cmp expect actual
113'
114
7dbabbbe 115test_done