Git 2.33-rc1
[git/debian.git] / t / t5703-upload-pack-ref-in-want.sh
blobe9e471621d59a6a321699c1c59138b95c05b2525
1 #!/bin/sh
3 test_description='upload-pack ref-in-want'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 . ./test-lib.sh
10 get_actual_refs () {
11 sed -n -e '/wanted-refs/,/0001/{
12 /wanted-refs/d
13 /0001/d
15 }' <out | test-tool pkt-line unpack >actual_refs
18 get_actual_commits () {
19 test-tool pkt-line unpack-sideband <out >o.pack &&
20 git index-pack o.pack &&
21 git verify-pack -v o.idx >objs &&
22 sed -n -e 's/\([0-9a-f][0-9a-f]*\) commit .*/\1/p' objs >objs.sed &&
23 sort >actual_commits <objs.sed
26 check_output () {
27 get_actual_refs &&
28 test_cmp expected_refs actual_refs &&
29 get_actual_commits &&
30 sort expected_commits >sorted_commits &&
31 test_cmp sorted_commits actual_commits
34 write_command () {
35 echo "command=$1"
37 if test "$(test_oid algo)" != sha1
38 then
39 echo "object-format=$(test_oid algo)"
43 # c(o/foo) d(o/bar)
44 # \ /
45 # b e(baz) f(main)
46 # \__ | __/
47 # \ | /
48 # a
49 test_expect_success 'setup repository' '
50 test_commit a &&
51 git branch -M main &&
52 git checkout -b o/foo &&
53 test_commit b &&
54 test_commit c &&
55 git checkout -b o/bar b &&
56 test_commit d &&
57 git checkout -b baz a &&
58 test_commit e &&
59 git checkout main &&
60 test_commit f
63 test_expect_success 'config controls ref-in-want advertisement' '
64 test-tool serve-v2 --advertise-capabilities >out &&
65 perl -ne "/ref-in-want/ and print" out >out.filter &&
66 test_must_be_empty out.filter &&
68 git config uploadpack.allowRefInWant false &&
69 test-tool serve-v2 --advertise-capabilities >out &&
70 perl -ne "/ref-in-want/ and print" out >out.filter &&
71 test_must_be_empty out.filter &&
73 git config uploadpack.allowRefInWant true &&
74 test-tool serve-v2 --advertise-capabilities >out &&
75 perl -ne "/ref-in-want/ and print" out >out.filter &&
76 test_file_not_empty out.filter
79 test_expect_success 'invalid want-ref line' '
80 test-tool pkt-line pack >in <<-EOF &&
81 $(write_command fetch)
82 0001
83 no-progress
84 want-ref refs/heads/non-existent
85 done
86 0000
87 EOF
89 test_must_fail test-tool serve-v2 --stateless-rpc 2>out <in &&
90 grep "unknown ref" out
93 test_expect_success 'basic want-ref' '
94 oid=$(git rev-parse f) &&
95 cat >expected_refs <<-EOF &&
96 $oid refs/heads/main
97 EOF
98 git rev-parse f >expected_commits &&
100 oid=$(git rev-parse a) &&
101 test-tool pkt-line pack >in <<-EOF &&
102 $(write_command fetch)
103 0001
104 no-progress
105 want-ref refs/heads/main
106 have $oid
107 done
108 0000
111 test-tool serve-v2 --stateless-rpc >out <in &&
112 check_output
115 test_expect_success 'multiple want-ref lines' '
116 oid_c=$(git rev-parse c) &&
117 oid_d=$(git rev-parse d) &&
118 cat >expected_refs <<-EOF &&
119 $oid_c refs/heads/o/foo
120 $oid_d refs/heads/o/bar
122 git rev-parse c d >expected_commits &&
124 oid=$(git rev-parse b) &&
125 test-tool pkt-line pack >in <<-EOF &&
126 $(write_command fetch)
127 0001
128 no-progress
129 want-ref refs/heads/o/foo
130 want-ref refs/heads/o/bar
131 have $oid
132 done
133 0000
136 test-tool serve-v2 --stateless-rpc >out <in &&
137 check_output
140 test_expect_success 'mix want and want-ref' '
141 oid=$(git rev-parse f) &&
142 cat >expected_refs <<-EOF &&
143 $oid refs/heads/main
145 git rev-parse e f >expected_commits &&
147 test-tool pkt-line pack >in <<-EOF &&
148 $(write_command fetch)
149 0001
150 no-progress
151 want-ref refs/heads/main
152 want $(git rev-parse e)
153 have $(git rev-parse a)
154 done
155 0000
158 test-tool serve-v2 --stateless-rpc >out <in &&
159 check_output
162 test_expect_success 'want-ref with ref we already have commit for' '
163 oid=$(git rev-parse c) &&
164 cat >expected_refs <<-EOF &&
165 $oid refs/heads/o/foo
167 >expected_commits &&
169 oid=$(git rev-parse c) &&
170 test-tool pkt-line pack >in <<-EOF &&
171 $(write_command fetch)
172 0001
173 no-progress
174 want-ref refs/heads/o/foo
175 have $oid
176 done
177 0000
180 test-tool serve-v2 --stateless-rpc >out <in &&
181 check_output
184 REPO="$(pwd)/repo"
185 LOCAL_PRISTINE="$(pwd)/local_pristine"
187 # $REPO
188 # c(o/foo) d(o/bar)
189 # \ /
190 # b e(baz) f(main)
191 # \__ | __/
192 # \ | /
195 # $LOCAL_PRISTINE
196 # s32(side)
201 # a(main)
202 test_expect_success 'setup repos for fetching with ref-in-want tests' '
204 git init -b main "$REPO" &&
205 cd "$REPO" &&
206 test_commit a &&
208 # Local repo with many commits (so that negotiation will take
209 # more than 1 request/response pair)
210 rm -rf "$LOCAL_PRISTINE" &&
211 git clone "file://$REPO" "$LOCAL_PRISTINE" &&
212 cd "$LOCAL_PRISTINE" &&
213 git checkout -b side &&
214 test_commit_bulk --id=s 33 &&
216 # Add novel commits to upstream
217 git checkout main &&
218 cd "$REPO" &&
219 git checkout -b o/foo &&
220 test_commit b &&
221 test_commit c &&
222 git checkout -b o/bar b &&
223 test_commit d &&
224 git checkout -b baz a &&
225 test_commit e &&
226 git checkout main &&
227 test_commit f
228 ) &&
229 git -C "$REPO" config uploadpack.allowRefInWant true &&
230 git -C "$LOCAL_PRISTINE" config protocol.version 2
233 test_expect_success 'fetching with exact OID' '
234 test_when_finished "rm -f log" &&
236 rm -rf local &&
237 cp -r "$LOCAL_PRISTINE" local &&
238 oid=$(git -C "$REPO" rev-parse d) &&
239 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \
240 "$oid":refs/heads/actual &&
242 git -C "$REPO" rev-parse "d" >expected &&
243 git -C local rev-parse refs/heads/actual >actual &&
244 test_cmp expected actual &&
245 grep "want $oid" log
248 test_expect_success 'fetching multiple refs' '
249 test_when_finished "rm -f log" &&
251 rm -rf local &&
252 cp -r "$LOCAL_PRISTINE" local &&
253 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin main baz &&
255 git -C "$REPO" rev-parse "main" "baz" >expected &&
256 git -C local rev-parse refs/remotes/origin/main refs/remotes/origin/baz >actual &&
257 test_cmp expected actual &&
258 grep "want-ref refs/heads/main" log &&
259 grep "want-ref refs/heads/baz" log
262 test_expect_success 'fetching ref and exact OID' '
263 test_when_finished "rm -f log" &&
265 rm -rf local &&
266 cp -r "$LOCAL_PRISTINE" local &&
267 oid=$(git -C "$REPO" rev-parse b) &&
268 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \
269 main "$oid":refs/heads/actual &&
271 git -C "$REPO" rev-parse "main" "b" >expected &&
272 git -C local rev-parse refs/remotes/origin/main refs/heads/actual >actual &&
273 test_cmp expected actual &&
274 grep "want $oid" log &&
275 grep "want-ref refs/heads/main" log
278 test_expect_success 'fetching with wildcard that does not match any refs' '
279 test_when_finished "rm -f log" &&
281 rm -rf local &&
282 cp -r "$LOCAL_PRISTINE" local &&
283 git -C local fetch origin refs/heads/none*:refs/heads/* >out &&
284 test_must_be_empty out
287 test_expect_success 'fetching with wildcard that matches multiple refs' '
288 test_when_finished "rm -f log" &&
290 rm -rf local &&
291 cp -r "$LOCAL_PRISTINE" local &&
292 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin refs/heads/o*:refs/heads/o* &&
294 git -C "$REPO" rev-parse "o/foo" "o/bar" >expected &&
295 git -C local rev-parse "o/foo" "o/bar" >actual &&
296 test_cmp expected actual &&
297 grep "want-ref refs/heads/o/foo" log &&
298 grep "want-ref refs/heads/o/bar" log
301 . "$TEST_DIRECTORY"/lib-httpd.sh
302 start_httpd
304 REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
305 LOCAL_PRISTINE="$(pwd)/local_pristine"
307 test_expect_success 'setup repos for change-while-negotiating test' '
309 git init -b main "$REPO" &&
310 cd "$REPO" &&
311 >.git/git-daemon-export-ok &&
312 test_commit m1 &&
313 git tag -d m1 &&
315 # Local repo with many commits (so that negotiation will take
316 # more than 1 request/response pair)
317 rm -rf "$LOCAL_PRISTINE" &&
318 git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
319 cd "$LOCAL_PRISTINE" &&
320 git checkout -b side &&
321 test_commit_bulk --id=s 33 &&
323 # Add novel commits to upstream
324 git checkout main &&
325 cd "$REPO" &&
326 test_commit m2 &&
327 test_commit m3 &&
328 git tag -d m2 m3
329 ) &&
330 git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_perl/repo" &&
331 git -C "$LOCAL_PRISTINE" config protocol.version 2
334 inconsistency () {
335 # Simulate that the server initially reports $2 as the ref
336 # corresponding to $1, and after that, $1 as the ref corresponding to
337 # $1. This corresponds to the real-life situation where the server's
338 # repository appears to change during negotiation, for example, when
339 # different servers in a load-balancing arrangement serve (stateless)
340 # RPCs during a single negotiation.
341 oid1=$(git -C "$REPO" rev-parse $1) &&
342 oid2=$(git -C "$REPO" rev-parse $2) &&
343 echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-perl"
346 test_expect_success 'server is initially ahead - no ref in want' '
347 git -C "$REPO" config uploadpack.allowRefInWant false &&
348 rm -rf local &&
349 cp -r "$LOCAL_PRISTINE" local &&
350 inconsistency main $(test_oid numeric) &&
351 test_must_fail git -C local fetch 2>err &&
352 test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
355 test_expect_success 'server is initially ahead - ref in want' '
356 git -C "$REPO" config uploadpack.allowRefInWant true &&
357 rm -rf local &&
358 cp -r "$LOCAL_PRISTINE" local &&
359 inconsistency main $(test_oid numeric) &&
360 git -C local fetch &&
362 git -C "$REPO" rev-parse --verify main >expected &&
363 git -C local rev-parse --verify refs/remotes/origin/main >actual &&
364 test_cmp expected actual
367 test_expect_success 'server is initially behind - no ref in want' '
368 git -C "$REPO" config uploadpack.allowRefInWant false &&
369 rm -rf local &&
370 cp -r "$LOCAL_PRISTINE" local &&
371 inconsistency main "main^" &&
372 git -C local fetch &&
374 git -C "$REPO" rev-parse --verify "main^" >expected &&
375 git -C local rev-parse --verify refs/remotes/origin/main >actual &&
376 test_cmp expected actual
379 test_expect_success 'server is initially behind - ref in want' '
380 git -C "$REPO" config uploadpack.allowRefInWant true &&
381 rm -rf local &&
382 cp -r "$LOCAL_PRISTINE" local &&
383 inconsistency main "main^" &&
384 git -C local fetch &&
386 git -C "$REPO" rev-parse --verify "main" >expected &&
387 git -C local rev-parse --verify refs/remotes/origin/main >actual &&
388 test_cmp expected actual
391 test_expect_success 'server loses a ref - ref in want' '
392 git -C "$REPO" config uploadpack.allowRefInWant true &&
393 rm -rf local &&
394 cp -r "$LOCAL_PRISTINE" local &&
395 echo "s/main/rain/" >"$HTTPD_ROOT_PATH/one-time-perl" &&
396 test_must_fail git -C local fetch 2>err &&
398 test_i18ngrep "fatal: remote error: unknown ref refs/heads/rain" err
401 # DO NOT add non-httpd-specific tests here, because the last part of this
402 # test script is only executed when httpd is available and enabled.
404 test_done