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