]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5316-pack-delta-depth.sh
Start the 2.46 cycle
[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'
e75d2f7f
ÆAB
4
5TEST_PASSES_SANITIZE_LEAK=true
7dbabbbe
JK
6. ./test-lib.sh
7
8# This mirrors a repeated push setup:
9#
10# 1. A client repeatedly modifies some files, makes a
11# commit, and pushes the result. It does this N times
12# before we get around to repacking.
13#
14# 2. Each push generates a thin pack with the new version of
15# various objects. Let's consider some file in the root tree
16# which is updated in each commit.
17#
18# When generating push number X, we feed commit X-1 (and
19# thus blob X-1) as a preferred base. The resulting pack has
20# blob X as a thin delta against blob X-1.
21#
22# On the receiving end, "index-pack --fix-thin" will
23# complete the pack with a base copy of blob X-1.
24#
25# 3. In older versions of git, if we used the delta from
26# pack X, then we'd always find blob X-1 as a base in the
27# same pack (and generate a fresh delta).
28#
29# But with the pack mru, we jump from delta to delta
30# following the traversal order:
31#
32# a. We grab blob X from pack X as a delta, putting it at
33# the tip of our mru list.
34#
35# b. Eventually we move onto commit X-1. We need other
36# objects which are only in pack X-1 (in the test code
37# below, it's the containing tree). That puts pack X-1
38# at the tip of our mru list.
39#
40# c. Eventually we look for blob X-1, and we find the
41# version in pack X-1 (because it's the mru tip).
42#
43# Now we have blob X as a delta against X-1, which is a delta
44# against X-2, and so forth.
45#
46# In the real world, these small pushes would get exploded by
47# unpack-objects rather than "index-pack --fix-thin", but the
48# same principle applies to larger pushes (they only need one
49# repeatedly-modified file to generate the delta chain).
50
51test_expect_success 'create series of packs' '
c680668d 52 test-tool genrandom foo 4096 >content &&
7dbabbbe
JK
53 prev= &&
54 for i in $(test_seq 1 10)
55 do
56 cat content >file &&
57 echo $i >>file &&
58 git add file &&
59 git commit -m $i &&
60 cur=$(git rev-parse HEAD^{tree}) &&
61 {
7abcbcb7
ES
62 if test -n "$prev"
63 then
64 echo "-$prev"
65 fi &&
66 echo $cur &&
7dbabbbe
JK
67 echo "$(git rev-parse :file) file"
68 } | git pack-objects --stdout >tmp &&
74900a6b
ÆAB
69 GIT_TRACE2_EVENT=$PWD/trace \
70 git index-pack -v --stdin --fix-thin <tmp || return 1 &&
71 grep -c region_enter.*progress trace >enter &&
72 grep -c region_leave.*progress trace >leave &&
73 test_cmp enter leave &&
7dbabbbe
JK
74 prev=$cur
75 done
76'
77
78max_chain() {
79 git index-pack --verify-stat-only "$1" >output &&
80 perl -lne '
49ac1d33 81 BEGIN { $len = 0 }
7dbabbbe
JK
82 /chain length = (\d+)/ and $len = $1;
83 END { print $len }
84 ' output
85}
86
87# Note that this whole setup is pretty reliant on the current
88# packing heuristics. We double-check that our test case
89# actually produces a long chain. If it doesn't, it should be
90# adjusted (or scrapped if the heuristics have become too unreliable)
91test_expect_success 'packing produces a long delta' '
92 # Use --window=0 to make sure we are seeing reused deltas,
93 # not computing a new long chain.
94 pack=$(git pack-objects --all --window=0 </dev/null pack) &&
0d75bfe6
ÆAB
95 echo 9 >expect &&
96 max_chain pack-$pack.pack >actual &&
1108cea7 97 test_cmp expect actual
7dbabbbe
JK
98'
99
100test_expect_success '--depth limits depth' '
101 pack=$(git pack-objects --all --depth=5 </dev/null pack) &&
0d75bfe6
ÆAB
102 echo 5 >expect &&
103 max_chain pack-$pack.pack >actual &&
1108cea7 104 test_cmp expect actual
7dbabbbe
JK
105'
106
49ac1d33
JK
107test_expect_success '--depth=0 disables deltas' '
108 pack=$(git pack-objects --all --depth=0 </dev/null pack) &&
109 echo 0 >expect &&
110 max_chain pack-$pack.pack >actual &&
111 test_cmp expect actual
112'
113
6d52b6a5
JK
114test_expect_success 'negative depth disables deltas' '
115 pack=$(git pack-objects --all --depth=-1 </dev/null pack) &&
116 echo 0 >expect &&
117 max_chain pack-$pack.pack >actual &&
118 test_cmp expect actual
119'
120
7dbabbbe 121test_done