3 test_description='upload-pack ref-in-want'
8 sed -n -e '/wanted-refs/,/0001/{
12 }' <out | test-tool pkt-line unpack >actual_refs
15 get_actual_commits () {
16 sed -n -e '/packfile/,/0000/{
19 }' <out | test-tool pkt-line unpack-sideband >o.pack &&
20 git index-pack o.pack &&
21 git verify-pack -v o.idx >objs &&
22 grep commit objs | cut -d" " -f1 | sort >actual_commits
27 test_cmp expected_refs actual_refs &&
29 sort expected_commits >sorted_commits &&
30 test_cmp sorted_commits actual_commits
39 test_expect_success 'setup repository' '
42 git checkout -b o/foo &&
45 git checkout -b o/bar b &&
47 git checkout -b baz a &&
49 git checkout master &&
53 test_expect_success 'config controls ref-in-want advertisement' '
54 test-tool serve-v2 --advertise-capabilities >out &&
55 perl -ne "/ref-in-want/ and print" out >out.filter &&
56 test_must_be_empty out.filter &&
58 git config uploadpack.allowRefInWant false &&
59 test-tool serve-v2 --advertise-capabilities >out &&
60 perl -ne "/ref-in-want/ and print" out >out.filter &&
61 test_must_be_empty out.filter &&
63 git config uploadpack.allowRefInWant true &&
64 test-tool serve-v2 --advertise-capabilities >out &&
65 perl -ne "/ref-in-want/ and print" out >out.filter &&
66 test_file_not_empty out.filter
69 test_expect_success 'invalid want-ref line' '
70 test-tool pkt-line pack >in <<-EOF &&
74 want-ref refs/heads/non-existent
79 test_must_fail test-tool serve-v2 --stateless-rpc 2>out <in &&
80 grep "unknown ref" out
83 test_expect_success 'basic want-ref' '
84 oid=$(git rev-parse f) &&
85 cat >expected_refs <<-EOF &&
86 $oid refs/heads/master
88 git rev-parse f >expected_commits &&
90 oid=$(git rev-parse a) &&
91 test-tool pkt-line pack >in <<-EOF &&
95 want-ref refs/heads/master
101 test-tool serve-v2 --stateless-rpc >out <in &&
105 test_expect_success 'multiple want-ref lines' '
106 oid_c=$(git rev-parse c) &&
107 oid_d=$(git rev-parse d) &&
108 cat >expected_refs <<-EOF &&
109 $oid_c refs/heads/o/foo
110 $oid_d refs/heads/o/bar
112 git rev-parse c d >expected_commits &&
114 oid=$(git rev-parse b) &&
115 test-tool pkt-line pack >in <<-EOF &&
119 want-ref refs/heads/o/foo
120 want-ref refs/heads/o/bar
126 test-tool serve-v2 --stateless-rpc >out <in &&
130 test_expect_success 'mix want and want-ref' '
131 oid=$(git rev-parse f) &&
132 cat >expected_refs <<-EOF &&
133 $oid refs/heads/master
135 git rev-parse e f >expected_commits &&
137 test-tool pkt-line pack >in <<-EOF &&
141 want-ref refs/heads/master
142 want $(git rev-parse e)
143 have $(git rev-parse a)
148 test-tool serve-v2 --stateless-rpc >out <in &&
152 test_expect_success 'want-ref with ref we already have commit for' '
153 oid=$(git rev-parse c) &&
154 cat >expected_refs <<-EOF &&
155 $oid refs/heads/o/foo
159 oid=$(git rev-parse c) &&
160 test-tool pkt-line pack >in <<-EOF &&
164 want-ref refs/heads/o/foo
170 test-tool serve-v2 --stateless-rpc >out <in &&
175 LOCAL_PRISTINE="$(pwd)/local_pristine"
192 test_expect_success 'setup repos for fetching with ref-in-want tests' '
198 # Local repo with many commits (so that negotiation will take
199 # more than 1 request/response pair)
200 rm -rf "$LOCAL_PRISTINE" &&
201 git clone "file://$REPO" "$LOCAL_PRISTINE" &&
202 cd "$LOCAL_PRISTINE" &&
203 git checkout -b side &&
204 test_commit_bulk --id=s 33 &&
206 # Add novel commits to upstream
207 git checkout master &&
209 git checkout -b o/foo &&
212 git checkout -b o/bar b &&
214 git checkout -b baz a &&
216 git checkout master &&
219 git -C "$REPO" config uploadpack.allowRefInWant true &&
220 git -C "$LOCAL_PRISTINE" config protocol.version 2
223 test_expect_success 'fetching with exact OID' '
224 test_when_finished "rm -f log" &&
227 cp -r "$LOCAL_PRISTINE" local &&
228 oid=$(git -C "$REPO" rev-parse d) &&
229 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \
230 "$oid":refs/heads/actual &&
232 git -C "$REPO" rev-parse "d" >expected &&
233 git -C local rev-parse refs/heads/actual >actual &&
234 test_cmp expected actual &&
238 test_expect_success 'fetching multiple refs' '
239 test_when_finished "rm -f log" &&
242 cp -r "$LOCAL_PRISTINE" local &&
243 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin master baz &&
245 git -C "$REPO" rev-parse "master" "baz" >expected &&
246 git -C local rev-parse refs/remotes/origin/master refs/remotes/origin/baz >actual &&
247 test_cmp expected actual &&
248 grep "want-ref refs/heads/master" log &&
249 grep "want-ref refs/heads/baz" log
252 test_expect_success 'fetching ref and exact OID' '
253 test_when_finished "rm -f log" &&
256 cp -r "$LOCAL_PRISTINE" local &&
257 oid=$(git -C "$REPO" rev-parse b) &&
258 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \
259 master "$oid":refs/heads/actual &&
261 git -C "$REPO" rev-parse "master" "b" >expected &&
262 git -C local rev-parse refs/remotes/origin/master refs/heads/actual >actual &&
263 test_cmp expected actual &&
264 grep "want $oid" log &&
265 grep "want-ref refs/heads/master" log
268 test_expect_success 'fetching with wildcard that does not match any refs' '
269 test_when_finished "rm -f log" &&
272 cp -r "$LOCAL_PRISTINE" local &&
273 git -C local fetch origin refs/heads/none*:refs/heads/* >out &&
274 test_must_be_empty out
277 test_expect_success 'fetching with wildcard that matches multiple refs' '
278 test_when_finished "rm -f log" &&
281 cp -r "$LOCAL_PRISTINE" local &&
282 GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin refs/heads/o*:refs/heads/o* &&
284 git -C "$REPO" rev-parse "o/foo" "o/bar" >expected &&
285 git -C local rev-parse "o/foo" "o/bar" >actual &&
286 test_cmp expected actual &&
287 grep "want-ref refs/heads/o/foo" log &&
288 grep "want-ref refs/heads/o/bar" log
291 . "$TEST_DIRECTORY"/lib-httpd.sh
294 REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
295 LOCAL_PRISTINE="$(pwd)/local_pristine"
297 test_expect_success 'setup repos for change-while-negotiating test' '
301 >.git/git-daemon-export-ok &&
305 # Local repo with many commits (so that negotiation will take
306 # more than 1 request/response pair)
307 rm -rf "$LOCAL_PRISTINE" &&
308 git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
309 cd "$LOCAL_PRISTINE" &&
310 git checkout -b side &&
311 test_commit_bulk --id=s 33 &&
313 # Add novel commits to upstream
314 git checkout master &&
320 git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_perl/repo" &&
321 git -C "$LOCAL_PRISTINE" config protocol.version 2
325 # Simulate that the server initially reports $2 as the ref
326 # corresponding to $1, and after that, $1 as the ref corresponding to
327 # $1. This corresponds to the real-life situation where the server's
328 # repository appears to change during negotiation, for example, when
329 # different servers in a load-balancing arrangement serve (stateless)
330 # RPCs during a single negotiation.
331 oid1=$(git -C "$REPO" rev-parse $1) &&
332 oid2=$(git -C "$REPO" rev-parse $2) &&
333 echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-perl"
336 test_expect_success 'server is initially ahead - no ref in want' '
337 git -C "$REPO" config uploadpack.allowRefInWant false &&
339 cp -r "$LOCAL_PRISTINE" local &&
340 inconsistency master $(test_oid numeric) &&
341 test_must_fail git -C local fetch 2>err &&
342 test_i18ngrep "fatal: remote error: upload-pack: not our ref" err
345 test_expect_success 'server is initially ahead - ref in want' '
346 git -C "$REPO" config uploadpack.allowRefInWant true &&
348 cp -r "$LOCAL_PRISTINE" local &&
349 inconsistency master $(test_oid numeric) &&
350 git -C local fetch &&
352 git -C "$REPO" rev-parse --verify master >expected &&
353 git -C local rev-parse --verify refs/remotes/origin/master >actual &&
354 test_cmp expected actual
357 test_expect_success 'server is initially behind - no ref in want' '
358 git -C "$REPO" config uploadpack.allowRefInWant false &&
360 cp -r "$LOCAL_PRISTINE" local &&
361 inconsistency master "master^" &&
362 git -C local fetch &&
364 git -C "$REPO" rev-parse --verify "master^" >expected &&
365 git -C local rev-parse --verify refs/remotes/origin/master >actual &&
366 test_cmp expected actual
369 test_expect_success 'server is initially behind - ref in want' '
370 git -C "$REPO" config uploadpack.allowRefInWant true &&
372 cp -r "$LOCAL_PRISTINE" local &&
373 inconsistency master "master^" &&
374 git -C local fetch &&
376 git -C "$REPO" rev-parse --verify "master" >expected &&
377 git -C local rev-parse --verify refs/remotes/origin/master >actual &&
378 test_cmp expected actual
381 test_expect_success 'server loses a ref - ref in want' '
382 git -C "$REPO" config uploadpack.allowRefInWant true &&
384 cp -r "$LOCAL_PRISTINE" local &&
385 echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-perl" &&
386 test_must_fail git -C local fetch 2>err &&
388 test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
391 # DO NOT add non-httpd-specific tests here, because the last part of this
392 # test script is only executed when httpd is available and enabled.