1
+#!/bin/sh
2
+
3
+test_description='exercise basic multi-pack bitmap functionality'
4
+. ./test-lib.sh
5
+. "${TEST_DIRECTORY}/lib-bitmap.sh"
6
+
7
+# We'll be writing our own midx and bitmaps, so avoid getting confused by the
8
+# automatic ones.
9
+GIT_TEST_MULTI_PACK_INDEX=0
10
+GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
11
+
12
+objdir=.git/objects
13
+midx=$objdir/pack/multi-pack-index
14
+
15
+# midx_pack_source <obj>
16
+midx_pack_source () {
17
+ test-tool read-midx --show-objects .git/objects | grep "^$1 " | cut -f2
18
+}
19
+
20
+setup_bitmap_history
21
+
22
+test_expect_success 'enable core.multiPackIndex' '
23
+ git config core.multiPackIndex true
24
+'
25
+
26
+test_expect_success 'create single-pack midx with bitmaps' '
27
+ git repack -ad &&
28
+ git multi-pack-index write --bitmap &&
29
+ test_path_is_file $midx &&
30
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
31
+ test_path_is_file $midx-$(midx_checksum $objdir).rev
32
+'
33
+
34
+basic_bitmap_tests
35
+
36
+test_expect_success 'create new additional packs' '
37
+ for i in $(test_seq 1 16)
38
+ do
39
+ test_commit "$i" &&
40
+ git repack -d || return 1
41
+ done &&
42
+
43
+ git checkout -b other2 HEAD~8 &&
44
+ for i in $(test_seq 1 8)
45
+ do
46
+ test_commit "side-$i" &&
47
+ git repack -d || return 1
48
+ done &&
49
+ git checkout second
50
+'
51
+
52
+test_expect_success 'create multi-pack midx with bitmaps' '
53
+ git multi-pack-index write --bitmap &&
54
+
55
+ ls $objdir/pack/pack-*.pack >packs &&
56
+ test_line_count = 25 packs &&
57
+
58
+ test_path_is_file $midx &&
59
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
60
+ test_path_is_file $midx-$(midx_checksum $objdir).rev
61
+'
62
+
63
+basic_bitmap_tests
64
+
65
+test_expect_success '--no-bitmap is respected when bitmaps exist' '
66
+ git multi-pack-index write --bitmap &&
67
+
68
+ test_commit respect--no-bitmap &&
69
+ git repack -d &&
70
+
71
+ test_path_is_file $midx &&
72
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
73
+ test_path_is_file $midx-$(midx_checksum $objdir).rev &&
74
+
75
+ git multi-pack-index write --no-bitmap &&
76
+
77
+ test_path_is_file $midx &&
78
+ test_path_is_missing $midx-$(midx_checksum $objdir).bitmap &&
79
+ test_path_is_missing $midx-$(midx_checksum $objdir).rev
80
+'
81
+
82
+test_expect_success 'setup midx with base from later pack' '
83
+ # Write a and b so that "a" is a delta on top of base "b", since Git
84
+ # prefers to delete contents out of a base rather than add to a shorter
85
+ # object.
86
+ test_seq 1 128 >a &&
87
+ test_seq 1 130 >b &&
88
+
89
+ git add a b &&
90
+ git commit -m "initial commit" &&
91
+
92
+ a=$(git rev-parse HEAD:a) &&
93
+ b=$(git rev-parse HEAD:b) &&
94
+
95
+ # In the first pack, "a" is stored as a delta to "b".
96
+ p1=$(git pack-objects .git/objects/pack/pack <<-EOF
97
+ $a
98
+ $b
99
+ EOF
100
+ ) &&
101
+
102
+ # In the second pack, "a" is missing, and "b" is not a delta nor base to
103
+ # any other object.
104
+ p2=$(git pack-objects .git/objects/pack/pack <<-EOF
105
+ $b
106
+ $(git rev-parse HEAD)
107
+ $(git rev-parse HEAD^{tree})
108
+ EOF
109
+ ) &&
110
+
111
+ git prune-packed &&
112
+ # Use the second pack as the preferred source, so that "b" occurs
113
+ # earlier in the MIDX object order, rendering "a" unusable for pack
114
+ # reuse.
115
+ git multi-pack-index write --bitmap --preferred-pack=pack-$p2.idx &&
116
+
117
+ have_delta $a $b &&
118
+ test $(midx_pack_source $a) != $(midx_pack_source $b)
119
+'
120
+
121
+rev_list_tests 'full bitmap with backwards delta'
122
+
123
+test_expect_success 'clone with bitmaps enabled' '
124
+ git clone --no-local --bare . clone-reverse-delta.git &&
125
+ test_when_finished "rm -fr clone-reverse-delta.git" &&
126
+
127
+ git rev-parse HEAD >expect &&
128
+ git --git-dir=clone-reverse-delta.git rev-parse HEAD >actual &&
129
+ test_cmp expect actual
130
+'
131
+
132
+bitmap_reuse_tests() {
133
+ from=$1
134
+ to=$2
135
+
136
+ test_expect_success "setup pack reuse tests ($from -> $to)" '
137
+ rm -fr repo &&
138
+ git init repo &&
139
+ (
140
+ cd repo &&
141
+ test_commit_bulk 16 &&
142
+ git tag old-tip &&
143
+
144
+ git config core.multiPackIndex true &&
145
+ if test "MIDX" = "$from"
146
+ then
147
+ git repack -Ad &&
148
+ git multi-pack-index write --bitmap
149
+ else
150
+ git repack -Adb
151
+ fi
152
+ )
153
+ '
154
+
155
+ test_expect_success "build bitmap from existing ($from -> $to)" '
156
+ (
157
+ cd repo &&
158
+ test_commit_bulk --id=further 16 &&
159
+ git tag new-tip &&
160
+
161
+ if test "MIDX" = "$to"
162
+ then
163
+ git repack -d &&
164
+ git multi-pack-index write --bitmap
165
+ else
166
+ git repack -Adb
167
+ fi
168
+ )
169
+ '
170
+
171
+ test_expect_success "verify resulting bitmaps ($from -> $to)" '
172
+ (
173
+ cd repo &&
174
+ git for-each-ref &&
175
+ git rev-list --test-bitmap refs/tags/old-tip &&
176
+ git rev-list --test-bitmap refs/tags/new-tip
177
+ )
178
+ '
179
+}
180
+
181
+bitmap_reuse_tests 'pack' 'MIDX'
182
+bitmap_reuse_tests 'MIDX' 'pack'
183
+bitmap_reuse_tests 'MIDX' 'MIDX'
184
+
185
+test_expect_success 'missing object closure fails gracefully' '
186
+ rm -fr repo &&
187
+ git init repo &&
188
+ test_when_finished "rm -fr repo" &&
189
+ (
190
+ cd repo &&
191
+
192
+ test_commit loose &&
193
+ test_commit packed &&
194
+
195
+ # Do not pass "--revs"; we want a pack without the "loose"
196
+ # commit.
197
+ git pack-objects $objdir/pack/pack <<-EOF &&
198
+ $(git rev-parse packed)
199
+ EOF
200
+
201
+ test_must_fail git multi-pack-index write --bitmap 2>err &&
202
+ grep "doesn.t have full closure" err &&
203
+ test_path_is_missing $midx
204
+ )
205
+'
206
+
207
+test_expect_success 'setup partial bitmaps' '
208
+ test_commit packed &&
209
+ git repack &&
210
+ test_commit loose &&
211
+ git multi-pack-index write --bitmap 2>err &&
212
+ test_path_is_file $midx &&
213
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
214
+ test_path_is_file $midx-$(midx_checksum $objdir).rev
215
+'
216
+
217
+basic_bitmap_tests HEAD~
218
+
219
+test_expect_success 'removing a MIDX clears stale bitmaps' '
220
+ rm -fr repo &&
221
+ git init repo &&
222
+ test_when_finished "rm -fr repo" &&
223
+ (
224
+ cd repo &&
225
+ test_commit base &&
226
+ git repack &&
227
+ git multi-pack-index write --bitmap &&
228
+
229
+ # Write a MIDX and bitmap; remove the MIDX but leave the bitmap.
230
+ stale_bitmap=$midx-$(midx_checksum $objdir).bitmap &&
231
+ stale_rev=$midx-$(midx_checksum $objdir).rev &&
232
+ rm $midx &&
233
+
234
+ # Then write a new MIDX.
235
+ test_commit new &&
236
+ git repack &&
237
+ git multi-pack-index write --bitmap &&
238
+
239
+ test_path_is_file $midx &&
240
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
241
+ test_path_is_file $midx-$(midx_checksum $objdir).rev &&
242
+ test_path_is_missing $stale_bitmap &&
243
+ test_path_is_missing $stale_rev
244
+ )
245
+'
246
+
247
+test_expect_success 'pack.preferBitmapTips' '
248
+ git init repo &&
249
+ test_when_finished "rm -fr repo" &&
250
+ (
251
+ cd repo &&
252
+
253
+ test_commit_bulk --message="%s" 103 &&
254
+
255
+ git log --format="%H" >commits.raw &&
256
+ sort <commits.raw >commits &&
257
+
258
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
259
+ git update-ref --stdin <refs &&
260
+
261
+ git multi-pack-index write --bitmap &&
262
+ test_path_is_file $midx &&
263
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
264
+ test_path_is_file $midx-$(midx_checksum $objdir).rev &&
265
+
266
+ test-tool bitmap list-commits | sort >bitmaps &&
267
+ comm -13 bitmaps commits >before &&
268
+ test_line_count = 1 before &&
269
+
270
+ perl -ne "printf(\"create refs/tags/include/%d \", $.); print" \
271
+ <before | git update-ref --stdin &&
272
+
273
+ rm -fr $midx-$(midx_checksum $objdir).bitmap &&
274
+ rm -fr $midx-$(midx_checksum $objdir).rev &&
275
+ rm -fr $midx &&
276
+
277
+ git -c pack.preferBitmapTips=refs/tags/include \
278
+ multi-pack-index write --bitmap &&
279
+ test-tool bitmap list-commits | sort >bitmaps &&
280
+ comm -13 bitmaps commits >after &&
281
+
282
+ ! test_cmp before after
283
+ )
284
+'
285
+
286
+test_done