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