Raw
1 #!/bin/sh
2
3 test_description='handling of promisor remote advertisement'
4
5 . ./test-lib.sh
6
7 if ! test_have_prereq PERL_TEST_HELPERS
8 then
9 skip_all='skipping promisor remote capabilities tests; Perl not available'
10 test_done
11 fi
12
13 GIT_TEST_MULTI_PACK_INDEX=0
14 GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL=0
15
16 # Setup the repository with three commits, this way HEAD is always
17 # available and we can hide commit 1 or 2.
18 test_expect_success 'setup: create "template" repository' '
19 git init template &&
20 test_commit -C template 1 &&
21 test_commit -C template 2 &&
22 test_commit -C template 3 &&
23 test-tool genrandom foo 10k >template/foo &&
24 git -C template add foo &&
25 git -C template commit -m foo
26 '
27
28 # A bare repo will act as a server repo with unpacked objects.
29 test_expect_success 'setup: create bare "server" repository' '
30 git clone --bare --no-local template server &&
31 mv server/objects/pack/pack-* . &&
32 packfile=$(ls pack-*.pack) &&
33 git -C server unpack-objects --strict <"$packfile"
34 '
35
36 check_missing_objects () {
37 git -C "$1" rev-list --objects --all --missing=print > all.txt &&
38 perl -ne 'print if s/^[?]//' all.txt >missing.txt &&
39 test_line_count = "$2" missing.txt &&
40 if test "$2" -lt 2
41 then
42 test "$3" = "$(cat missing.txt)"
43 else
44 test -f "$3" &&
45 sort <"$3" >expected_sorted &&
46 sort <missing.txt >actual_sorted &&
47 test_cmp expected_sorted actual_sorted
48 fi
49 }
50
51 initialize_server () {
52 count="$1"
53 missing_oids="$2"
54
55 # Repack everything first
56 git -C server -c repack.writebitmaps=false repack -a -d &&
57
58 # Remove promisor file in case they exist, useful when reinitializing
59 rm -rf server/objects/pack/*.promisor &&
60
61 # Repack without the largest object and create a promisor pack on server
62 git -C server -c repack.writebitmaps=false repack -a -d \
63 --filter=blob:limit=5k --filter-to="$(pwd)/pack" &&
64 promisor_file=$(ls server/objects/pack/*.pack | sed "s/\.pack/.promisor/") &&
65 >"$promisor_file" &&
66
67 # Check objects missing on the server
68 check_missing_objects server "$count" "$missing_oids"
69 }
70
71 copy_to_lop () {
72 oid_path="$(test_oid_to_path $1)" &&
73 path="server/objects/$oid_path" &&
74 path2="lop/objects/$oid_path" &&
75 mkdir -p $(dirname "$path2") &&
76 cp "$path" "$path2"
77 }
78
79 # On Windows, `pwd` returns a path like 'D:/foo/bar'. Prepend '/' to turn
80 # it into '/D:/foo/bar', which is what git expects in file:// URLs on Windows.
81 # On Unix, the path already starts with '/', so this is a no-op.
82 pwd_path=$(pwd)
83 case "$pwd_path" in
84 [a-zA-Z]:*) pwd_path="/$pwd_path" ;;
85 esac
86
87 # Allowed characters: alphanumeric, standard path/URI (_ . ~ / : -),
88 # and those percent-encoded below (% space = , ;)
89 rest=$(printf "%s" "$pwd_path" | tr -d 'a-zA-Z0-9_.~/:% =,;-')
90 if test -n "$rest"
91 then
92 skip_all="PWD contains unsupported special characters"
93 test_done
94 fi
95
96 TRASH_DIRECTORY_URL="file://$pwd_path"
97
98 encoded_path=$(printf "%s" "$pwd_path" |
99 sed -e 's/%/%25/g' -e 's/ /%20/g' -e 's/=/%3D/g' \
100 -e 's/;/%3B/g' -e 's/,/%2C/g')
101
102 ENCODED_TRASH_DIRECTORY_URL="file://$encoded_path"
103
104 test_expect_success "setup for testing promisor remote advertisement" '
105 # Create another bare repo called "lop" (for Large Object Promisor)
106 git init --bare lop &&
107
108 # Copy the largest object from server to lop
109 obj="HEAD:foo" &&
110 oid="$(git -C server rev-parse $obj)" &&
111 copy_to_lop "$oid" &&
112
113 initialize_server 1 "$oid" &&
114
115 # Configure lop as promisor remote for server
116 git -C server remote add lop "$TRASH_DIRECTORY_URL/lop" &&
117 git -C server config remote.lop.promisor true &&
118
119 git -C lop config uploadpack.allowFilter true &&
120 git -C lop config uploadpack.allowAnySHA1InWant true &&
121 git -C server config uploadpack.allowFilter true &&
122 git -C server config uploadpack.allowAnySHA1InWant true
123 '
124
125 test_expect_success "clone with promisor.advertise set to 'true'" '
126 git -C server config promisor.advertise true &&
127 test_when_finished "rm -rf client" &&
128
129 # Clone from server to create a client
130 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
131 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
132 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
133 -c promisor.acceptfromserver=All \
134 --no-local --filter="blob:limit=5k" server client &&
135
136 # Check that the largest object is still missing on the server
137 check_missing_objects server 1 "$oid"
138 '
139
140 test_expect_success "clone with promisor.advertise set to 'false'" '
141 git -C server config promisor.advertise false &&
142 test_when_finished "rm -rf client" &&
143
144 # Clone from server to create a client
145 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
146 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
147 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
148 -c promisor.acceptfromserver=All \
149 --no-local --filter="blob:limit=5k" server client &&
150
151 # Check that the largest object is not missing on the server
152 check_missing_objects server 0 "" &&
153
154 # Reinitialize server so that the largest object is missing again
155 initialize_server 1 "$oid"
156 '
157
158 test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
159 git -C server config promisor.advertise true &&
160 test_when_finished "rm -rf client" &&
161
162 # Clone from server to create a client
163 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
164 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
165 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
166 -c promisor.acceptfromserver=None \
167 --no-local --filter="blob:limit=5k" server client &&
168
169 # Check that the largest object is not missing on the server
170 check_missing_objects server 0 "" &&
171
172 # Reinitialize server so that the largest object is missing again
173 initialize_server 1 "$oid"
174 '
175
176 test_expect_success "init + fetch with promisor.advertise set to 'true'" '
177 git -C server config promisor.advertise true &&
178 test_when_finished "rm -rf client" &&
179
180 mkdir client &&
181 git -C client init &&
182 git -C client config remote.lop.promisor true &&
183 git -C client config remote.lop.fetch "+refs/heads/*:refs/remotes/lop/*" &&
184 git -C client config remote.lop.url "$TRASH_DIRECTORY_URL/lop" &&
185 git -C client config remote.server.url "$TRASH_DIRECTORY_URL/server" &&
186 git -C client config remote.server.fetch "+refs/heads/*:refs/remotes/server/*" &&
187 git -C client config promisor.acceptfromserver All &&
188 GIT_NO_LAZY_FETCH=0 git -C client fetch --filter="blob:limit=5k" server &&
189
190 # Check that the largest object is still missing on the server
191 check_missing_objects server 1 "$oid"
192 '
193
194 test_expect_success "clone with two promisors but only one advertised" '
195 git -C server config promisor.advertise true &&
196 test_when_finished "rm -rf client unused_lop" &&
197
198 # Create a promisor that will be configured but not be used
199 git init --bare unused_lop &&
200
201 # Clone from server to create a client
202 GIT_TRACE="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git clone \
203 -c remote.unused_lop.promisor=true \
204 -c remote.unused_lop.fetch="+refs/heads/*:refs/remotes/unused_lop/*" \
205 -c remote.unused_lop.url="$TRASH_DIRECTORY_URL/unused_lop" \
206 -c remote.lop.promisor=true \
207 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
208 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
209 -c promisor.acceptfromserver=All \
210 --no-local --filter="blob:limit=5k" server client &&
211
212 # Check that "unused_lop" appears before "lop" in the config
213 printf "remote.%s.promisor true\n" "unused_lop" "lop" "origin" >expect &&
214 git -C client config get --all --show-names --regexp "^remote\..*\.promisor$" >actual &&
215 test_cmp expect actual &&
216
217 # Check that "lop" was tried
218 test_grep " fetch lop " trace &&
219 # Check that "unused_lop" was not contacted
220 # This means "lop", the accepted promisor, was tried first
221 test_grep ! " fetch unused_lop " trace &&
222
223 # Check that the largest object is still missing on the server
224 check_missing_objects server 1 "$oid"
225 '
226
227 test_expect_success "init + fetch two promisors but only one advertised" '
228 git -C server config promisor.advertise true &&
229 test_when_finished "rm -rf client unused_lop" &&
230
231 # Create a promisor that will be configured but not be used
232 git init --bare unused_lop &&
233
234 mkdir client &&
235 git -C client init &&
236 git -C client config remote.unused_lop.promisor true &&
237 git -C client config remote.unused_lop.fetch "+refs/heads/*:refs/remotes/unused_lop/*" &&
238 git -C client config remote.unused_lop.url "$TRASH_DIRECTORY_URL/unused_lop" &&
239 git -C client config remote.lop.promisor true &&
240 git -C client config remote.lop.fetch "+refs/heads/*:refs/remotes/lop/*" &&
241 git -C client config remote.lop.url "$TRASH_DIRECTORY_URL/lop" &&
242 git -C client config remote.server.url "$TRASH_DIRECTORY_URL/server" &&
243 git -C client config remote.server.fetch "+refs/heads/*:refs/remotes/server/*" &&
244 git -C client config promisor.acceptfromserver All &&
245
246 # Check that "unused_lop" appears before "lop" in the config
247 printf "remote.%s.promisor true\n" "unused_lop" "lop" >expect &&
248 git -C client config get --all --show-names --regexp "^remote\..*\.promisor$" >actual &&
249 test_cmp expect actual &&
250
251 GIT_TRACE="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git -C client fetch --filter="blob:limit=5k" server &&
252
253 # Check that "lop" was tried
254 test_grep " fetch lop " trace &&
255 # Check that "unused_lop" was not contacted
256 # This means "lop", the accepted promisor, was tried first
257 test_grep ! " fetch unused_lop " trace &&
258
259 # Check that the largest object is still missing on the server
260 check_missing_objects server 1 "$oid"
261 '
262
263 test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" '
264 git -C server config promisor.advertise true &&
265 test_when_finished "rm -rf client" &&
266
267 # Clone from server to create a client
268 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
269 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
270 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
271 -c promisor.acceptfromserver=KnownName \
272 --no-local --filter="blob:limit=5k" server client &&
273
274 # Check that the largest object is still missing on the server
275 check_missing_objects server 1 "$oid"
276 '
277
278 test_expect_success "clone with 'KnownName' and different remote names" '
279 git -C server config promisor.advertise true &&
280 test_when_finished "rm -rf client" &&
281
282 # Clone from server to create a client
283 GIT_NO_LAZY_FETCH=0 git clone -c remote.serverTwo.promisor=true \
284 -c remote.serverTwo.fetch="+refs/heads/*:refs/remotes/lop/*" \
285 -c remote.serverTwo.url="$TRASH_DIRECTORY_URL/lop" \
286 -c promisor.acceptfromserver=KnownName \
287 --no-local --filter="blob:limit=5k" server client &&
288
289 # Check that the largest object is not missing on the server
290 check_missing_objects server 0 "" &&
291
292 # Reinitialize server so that the largest object is missing again
293 initialize_server 1 "$oid"
294 '
295
296 test_expect_success "clone with 'KnownName' and missing URL in the config" '
297 git -C server config promisor.advertise true &&
298 test_when_finished "rm -rf client" &&
299
300 # Clone from server to create a client
301 # Lazy fetching by the client from the LOP will fail because of the
302 # missing URL in the client config, so the server will have to lazy
303 # fetch from the LOP.
304 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
305 -c promisor.acceptfromserver=KnownName \
306 --no-local --filter="blob:limit=5k" server client &&
307
308 # Check that the largest object is not missing on the server
309 check_missing_objects server 0 "" &&
310
311 # Reinitialize server so that the largest object is missing again
312 initialize_server 1 "$oid"
313 '
314
315 test_expect_success "clone with promisor.acceptfromserver set to 'KnownUrl'" '
316 git -C server config promisor.advertise true &&
317 test_when_finished "rm -rf client" &&
318
319 # Clone from server to create a client
320 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
321 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
322 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
323 -c promisor.acceptfromserver=KnownUrl \
324 --no-local --filter="blob:limit=5k" server client &&
325
326 # Check that the largest object is still missing on the server
327 check_missing_objects server 1 "$oid"
328 '
329
330 test_expect_success "clone with 'KnownUrl' and different remote urls" '
331 ln -s lop serverTwo &&
332
333 git -C server config promisor.advertise true &&
334 test_when_finished "rm -rf client" &&
335
336 # Clone from server to create a client
337 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
338 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
339 -c remote.lop.url="$TRASH_DIRECTORY_URL/serverTwo" \
340 -c promisor.acceptfromserver=KnownUrl \
341 --no-local --filter="blob:limit=5k" server client &&
342
343 # Check that the largest object is not missing on the server
344 check_missing_objects server 0 "" &&
345
346 # Reinitialize server so that the largest object is missing again
347 initialize_server 1 "$oid"
348 '
349
350 test_expect_success "clone with 'KnownUrl' and url not configured on the server" '
351 git -C server config promisor.advertise true &&
352 test_when_finished "rm -rf client" &&
353
354 test_when_finished "git -C server config set remote.lop.url \"$TRASH_DIRECTORY_URL/lop\"" &&
355 git -C server config unset remote.lop.url &&
356
357 # Clone from server to create a client
358 # It should fail because the client will reject the LOP as URLs are
359 # different, and the server cannot lazy fetch as the LOP URL is
360 # missing, so the remote name will be used instead which will fail.
361 test_must_fail env GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
362 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
363 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
364 -c promisor.acceptfromserver=KnownUrl \
365 --no-local --filter="blob:limit=5k" server client &&
366
367 # Check that the largest object is still missing on the server
368 check_missing_objects server 1 "$oid"
369 '
370
371 test_expect_success "clone with 'KnownUrl' and empty url, so not advertised" '
372 git -C server config promisor.advertise true &&
373 test_when_finished "rm -rf client" &&
374
375 test_when_finished "git -C server config set remote.lop.url \"$TRASH_DIRECTORY_URL/lop\"" &&
376 git -C server config set remote.lop.url "" &&
377
378 # Clone from server to create a client
379 # It should fail because the client will reject the LOP as an empty URL is
380 # not advertised, and the server cannot lazy fetch as the LOP URL is empty,
381 # so the remote name will be used instead which will fail.
382 test_must_fail env GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
383 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
384 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
385 -c promisor.acceptfromserver=KnownUrl \
386 --no-local --filter="blob:limit=5k" server client &&
387
388 # Check that the largest object is still missing on the server
389 check_missing_objects server 1 "$oid"
390 '
391
392 test_expect_success "clone with promisor.sendFields" '
393 git -C server config promisor.advertise true &&
394 test_when_finished "rm -rf client" &&
395
396 git -C server remote add otherLop "https://invalid.invalid" &&
397 git -C server config remote.otherLop.token "fooBar" &&
398 git -C server config remote.otherLop.stuff "baz" &&
399 git -C server config remote.otherLop.partialCloneFilter "blob:limit=10k" &&
400 test_when_finished "git -C server remote remove otherLop" &&
401 test_config -C server promisor.sendFields "partialCloneFilter, token" &&
402 test_when_finished "rm trace" &&
403
404 # Clone from server to create a client
405 GIT_TRACE_PACKET="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git clone \
406 -c remote.lop.promisor=true \
407 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
408 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
409 -c promisor.acceptfromserver=All \
410 --no-local --filter="blob:limit=5k" server client &&
411
412 # Check that fields are properly transmitted
413 PR1="name=lop,url=$ENCODED_TRASH_DIRECTORY_URL/lop,partialCloneFilter=blob:none" &&
414 PR2="name=otherLop,url=https://invalid.invalid,partialCloneFilter=blob:limit=10k,token=fooBar" &&
415 test_grep "clone< promisor-remote=$PR1;$PR2" trace &&
416 test_grep "clone> promisor-remote=lop;otherLop" trace &&
417
418 # Check that the largest object is still missing on the server
419 check_missing_objects server 1 "$oid"
420 '
421
422 test_expect_success "clone with promisor.checkFields" '
423 git -C server config promisor.advertise true &&
424 test_when_finished "rm -rf client" &&
425
426 git -C server remote add otherLop "https://invalid.invalid" &&
427 git -C server config remote.otherLop.token "fooBar" &&
428 git -C server config remote.otherLop.stuff "baz" &&
429 git -C server config remote.otherLop.partialCloneFilter "blob:limit=10k" &&
430 test_when_finished "git -C server remote remove otherLop" &&
431 test_config -C server promisor.sendFields "partialCloneFilter, token" &&
432 test_when_finished "rm trace" &&
433
434 # Clone from server to create a client
435 GIT_TRACE_PACKET="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git clone \
436 -c remote.lop.promisor=true \
437 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
438 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
439 -c remote.lop.partialCloneFilter="blob:none" \
440 -c promisor.acceptfromserver=All \
441 -c promisor.checkFields=partialcloneFilter \
442 --no-local --filter="blob:limit=5k" server client &&
443
444 # Check that fields are properly transmitted
445 PR1="name=lop,url=$ENCODED_TRASH_DIRECTORY_URL/lop,partialCloneFilter=blob:none" &&
446 PR2="name=otherLop,url=https://invalid.invalid,partialCloneFilter=blob:limit=10k,token=fooBar" &&
447 test_grep "clone< promisor-remote=$PR1;$PR2" trace &&
448 test_grep "clone> promisor-remote=lop" trace &&
449 test_grep ! "clone> promisor-remote=lop;otherLop" trace &&
450
451 # Check that the largest object is still missing on the server
452 check_missing_objects server 1 "$oid"
453 '
454
455 test_expect_success "clone with promisor.storeFields=partialCloneFilter" '
456 git -C server config promisor.advertise true &&
457 test_when_finished "rm -rf client" &&
458
459 git -C server remote add otherLop "https://invalid.invalid" &&
460 git -C server config remote.otherLop.token "fooBar" &&
461 git -C server config remote.otherLop.stuff "baz" &&
462 git -C server config remote.otherLop.partialCloneFilter "blob:limit=10k" &&
463 test_when_finished "git -C server remote remove otherLop" &&
464
465 git -C server config remote.lop.token "fooXXX" &&
466 git -C server config remote.lop.partialCloneFilter "blob:limit=8k" &&
467
468 test_config -C server promisor.sendFields "partialCloneFilter, token" &&
469 test_when_finished "rm trace" &&
470
471 # Clone from server to create a client
472 GIT_TRACE_PACKET="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git clone \
473 -c remote.lop.promisor=true \
474 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
475 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
476 -c remote.lop.token="fooYYY" \
477 -c remote.lop.partialCloneFilter="blob:none" \
478 -c promisor.acceptfromserver=All \
479 -c promisor.storeFields=partialcloneFilter \
480 --no-local --filter="blob:limit=5k" server client 2>err &&
481
482 # Check that the filter from the server is stored
483 echo "blob:limit=8k" >expected &&
484 git -C client config remote.lop.partialCloneFilter >actual &&
485 test_cmp expected actual &&
486
487 # Check that user is notified when the filter is stored
488 test_grep "Storing new filter from server for remote '\''lop'\''" err &&
489 test_grep "'\''blob:none'\'' -> '\''blob:limit=8k'\''" err &&
490
491 # Check that the token from the server is NOT stored
492 echo "fooYYY" >expected &&
493 git -C client config remote.lop.token >actual &&
494 test_cmp expected actual &&
495 test_grep ! "Storing new token from server" err &&
496
497 # Check that the filter for an unknown remote is NOT stored
498 test_must_fail git -C client config remote.otherLop.partialCloneFilter >actual &&
499
500 # Check that the largest object is still missing on the server
501 check_missing_objects server 1 "$oid" &&
502
503 # Change the configuration on the server and fetch from the client
504 git -C server config remote.lop.partialCloneFilter "blob:limit=7k" &&
505 GIT_NO_LAZY_FETCH=0 git -C client fetch \
506 --filter="blob:limit=5k" ../server 2>err &&
507
508 # Check that the fetch updated the configuration on the client
509 echo "blob:limit=7k" >expected &&
510 git -C client config remote.lop.partialCloneFilter >actual &&
511 test_cmp expected actual &&
512
513 # Check that user is notified when the new filter is stored
514 test_grep "Storing new filter from server for remote '\''lop'\''" err &&
515 test_grep "'\''blob:limit=8k'\'' -> '\''blob:limit=7k'\''" err
516 '
517
518 test_expect_success "clone and fetch with --filter=auto" '
519 git -C server config promisor.advertise true &&
520 test_when_finished "rm -rf client trace" &&
521
522 git -C server config remote.lop.partialCloneFilter "blob:limit=9500" &&
523 test_config -C server promisor.sendFields "partialCloneFilter" &&
524
525 GIT_TRACE_PACKET="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git clone \
526 -c remote.lop.promisor=true \
527 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
528 -c promisor.acceptfromserver=All \
529 --no-local --filter=auto server client 2>err &&
530
531 test_grep "filter blob:limit=9500" trace &&
532 test_grep ! "filter auto" trace &&
533
534 # Verify "auto" is persisted in config
535 echo auto >expected &&
536 git -C client config remote.origin.partialCloneFilter >actual &&
537 test_cmp expected actual &&
538
539 # Check that the largest object is still missing on the server
540 check_missing_objects server 1 "$oid" &&
541
542 # Now change the filter on the server
543 git -C server config remote.lop.partialCloneFilter "blob:limit=5678" &&
544
545 # Get a new commit on the server to ensure "git fetch" actually runs fetch-pack
546 test_commit -C template new-commit &&
547 git -C template push --all "$(pwd)/server" &&
548
549 # Perform a fetch WITH --filter=auto
550 rm -rf trace &&
551 GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch --filter=auto &&
552
553 # Verify that the new filter was used
554 test_grep "filter blob:limit=5678" trace &&
555
556 # Check that the largest object is still missing on the server
557 check_missing_objects server 1 "$oid" &&
558
559 # Change the filter on the server again
560 git -C server config remote.lop.partialCloneFilter "blob:limit=5432" &&
561
562 # Get yet a new commit on the server to ensure fetch-pack runs
563 test_commit -C template yet-a-new-commit &&
564 git -C template push --all "$(pwd)/server" &&
565
566 # Perform a fetch WITHOUT --filter=auto
567 # Relies on "auto" being persisted in the client config
568 rm -rf trace &&
569 GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch &&
570
571 # Verify that the new filter was used
572 test_grep "filter blob:limit=5432" trace &&
573
574 # Check that the largest object is still missing on the server
575 check_missing_objects server 1 "$oid"
576 '
577
578 test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" '
579 git -C server config promisor.advertise true &&
580
581 # Clone from server to create a client
582 GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
583 -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
584 -c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
585 -c promisor.acceptfromserver=All \
586 --no-local --filter="blob:limit=5k" server client &&
587
588 # Check that the largest object is still missing on the server
589 check_missing_objects server 1 "$oid"
590 '
591
592 test_expect_success "setup for subsequent fetches" '
593 # Generate new commit with large blob
594 test-tool genrandom bar 10k >template/bar &&
595 git -C template add bar &&
596 git -C template commit -m bar &&
597
598 # Fetch new commit with large blob
599 git -C server fetch origin &&
600 git -C server update-ref HEAD FETCH_HEAD &&
601 git -C server rev-parse HEAD >expected_head &&
602
603 # Repack everything twice and remove .promisor files before
604 # each repack. This makes sure everything gets repacked
605 # into a single packfile. The second repack is necessary
606 # because the first one fetches from lop and creates a new
607 # packfile and its associated .promisor file.
608
609 rm -f server/objects/pack/*.promisor &&
610 git -C server -c repack.writebitmaps=false repack -a -d &&
611 rm -f server/objects/pack/*.promisor &&
612 git -C server -c repack.writebitmaps=false repack -a -d &&
613
614 # Unpack everything
615 rm pack-* &&
616 mv server/objects/pack/pack-* . &&
617 packfile=$(ls pack-*.pack) &&
618 git -C server unpack-objects --strict <"$packfile" &&
619
620 # Copy new large object to lop
621 obj_bar="HEAD:bar" &&
622 oid_bar="$(git -C server rev-parse $obj_bar)" &&
623 copy_to_lop "$oid_bar" &&
624
625 # Reinitialize server so that the 2 largest objects are missing
626 printf "%s\n" "$oid" "$oid_bar" >expected_missing.txt &&
627 initialize_server 2 expected_missing.txt &&
628
629 # Create one more client
630 cp -r client client2
631 '
632
633 test_expect_success "subsequent fetch from a client when promisor.advertise is true" '
634 git -C server config promisor.advertise true &&
635
636 GIT_NO_LAZY_FETCH=0 git -C client pull origin &&
637
638 git -C client rev-parse HEAD >actual &&
639 test_cmp expected_head actual &&
640
641 cat client/bar >/dev/null &&
642
643 check_missing_objects server 2 expected_missing.txt
644 '
645
646 test_expect_success "subsequent fetch from a client when promisor.advertise is false" '
647 git -C server config promisor.advertise false &&
648
649 GIT_NO_LAZY_FETCH=0 git -C client2 pull origin &&
650
651 git -C client2 rev-parse HEAD >actual &&
652 test_cmp expected_head actual &&
653
654 cat client2/bar >/dev/null &&
655
656 check_missing_objects server 1 "$oid"
657 '
658
659 test_done