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