@@ -40,6 +40,54 @@ write_command () {
40
40
fi
41
41
}
42
42
43
+ # Write a complete fetch command to stdout, suitable for use with `test-tool
44
+ # pkt-line`. "want-ref", "want", and "have" values can be given in this order,
45
+ # with sections separated by "--".
46
+ #
47
+ # Examples:
48
+ #
49
+ # write_fetch_command refs/heads/main
50
+ #
51
+ # write_fetch_command \
52
+ # refs/heads/main \
53
+ # -- \
54
+ # -- \
55
+ # $(git rev-parse x)
56
+ #
57
+ # write_fetch_command \
58
+ # --
59
+ # $(git rev-parse a) \
60
+ # --
61
+ # $(git rev-parse b)
62
+ write_fetch_command () {
63
+ write_command fetch &&
64
+ echo " 0001" &&
65
+ echo " no-progress" || return
66
+ while :
67
+ do
68
+ case $# in 0) break ;; esac &&
69
+ case " $1 " in --) shift ; break ;; esac &&
70
+ echo " want-ref $1 " &&
71
+ shift || return
72
+ done &&
73
+ while :
74
+ do
75
+ case $# in 0) break ;; esac &&
76
+ case " $1 " in --) shift ; break ;; esac &&
77
+ echo " want $1 " &&
78
+ shift || return
79
+ done &&
80
+ while :
81
+ do
82
+ case $# in 0) break ;; esac &&
83
+ case " $1 " in --) shift ; break ;; esac &&
84
+ echo " have $1 " &&
85
+ shift || return
86
+ done &&
87
+ echo " done" &&
88
+ echo " 0000"
89
+ }
90
+
43
91
# c(o/foo) d(o/bar)
44
92
# \ /
45
93
# b e(baz) f(main)
@@ -97,15 +145,13 @@ test_expect_success 'basic want-ref' '
97
145
EOF
98
146
git rev-parse f >expected_commits &&
99
147
100
- oid=$(git rev-parse a) &&
101
148
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
149
+ $(write_fetch_command \
150
+ refs/heads/main \
151
+ -- \
152
+ -- \
153
+ $(git rev-parse a) \
154
+ )
109
155
EOF
110
156
111
157
test-tool serve-v2 --stateless-rpc >out <in &&
@@ -121,16 +167,14 @@ test_expect_success 'multiple want-ref lines' '
121
167
EOF
122
168
git rev-parse c d >expected_commits &&
123
169
124
- oid=$(git rev-parse b) &&
125
170
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
171
+ $(write_fetch_command \
172
+ refs/heads/o/foo \
173
+ refs/heads/o/bar \
174
+ -- \
175
+ -- \
176
+ $(git rev-parse b) \
177
+ )
134
178
EOF
135
179
136
180
test-tool serve-v2 --stateless-rpc >out <in &&
@@ -145,14 +189,13 @@ test_expect_success 'mix want and want-ref' '
145
189
git rev-parse e f >expected_commits &&
146
190
147
191
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
192
+ $(write_fetch_command \
193
+ refs/heads/main \
194
+ -- \
195
+ $(git rev-parse e) \
196
+ -- \
197
+ $(git rev-parse a) \
198
+ )
156
199
EOF
157
200
158
201
test-tool serve-v2 --stateless-rpc >out <in &&
@@ -166,15 +209,13 @@ test_expect_success 'want-ref with ref we already have commit for' '
166
209
EOF
167
210
>expected_commits &&
168
211
169
- oid=$(git rev-parse c) &&
170
212
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
213
+ $(write_fetch_command \
214
+ refs/heads/o/foo \
215
+ -- \
216
+ -- \
217
+ $(git rev-parse c) \
218
+ )
178
219
EOF
179
220
180
221
test-tool serve-v2 --stateless-rpc >out <in &&
@@ -298,6 +339,135 @@ test_expect_success 'fetching with wildcard that matches multiple refs' '
298
339
grep "want-ref refs/heads/o/bar" log
299
340
'
300
341
342
+ REPO=" $( pwd) /repo-ns"
343
+
344
+ test_expect_success ' setup namespaced repo' '
345
+ (
346
+ git init -b main "$REPO" &&
347
+ cd "$REPO" &&
348
+ test_commit a &&
349
+ test_commit b &&
350
+ git checkout a &&
351
+ test_commit c &&
352
+ git checkout a &&
353
+ test_commit d &&
354
+ git update-ref refs/heads/ns-no b &&
355
+ git update-ref refs/namespaces/ns/refs/heads/ns-yes c &&
356
+ git update-ref refs/namespaces/ns/refs/heads/hidden d
357
+ ) &&
358
+ git -C "$REPO" config uploadpack.allowRefInWant true
359
+ '
360
+
361
+ test_expect_success ' with namespace: want-ref is considered relative to namespace' '
362
+ wanted_ref=refs/heads/ns-yes &&
363
+
364
+ oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") &&
365
+ cat >expected_refs <<-EOF &&
366
+ $oid $wanted_ref
367
+ EOF
368
+ cat >expected_commits <<-EOF &&
369
+ $oid
370
+ $(git -C "$REPO" rev-parse a)
371
+ EOF
372
+
373
+ test-tool pkt-line pack >in <<-EOF &&
374
+ $(write_fetch_command $wanted_ref)
375
+ EOF
376
+
377
+ GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
378
+ check_output
379
+ '
380
+
381
+ test_expect_success ' with namespace: want-ref outside namespace is unknown' '
382
+ wanted_ref=refs/heads/ns-no &&
383
+
384
+ test-tool pkt-line pack >in <<-EOF &&
385
+ $(write_fetch_command $wanted_ref)
386
+ EOF
387
+
388
+ test_must_fail env GIT_NAMESPACE=ns \
389
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
390
+ grep "unknown ref" out
391
+ '
392
+
393
+ # Cross-check refs/heads/ns-no indeed exists
394
+ test_expect_success ' without namespace: want-ref outside namespace succeeds' '
395
+ wanted_ref=refs/heads/ns-no &&
396
+
397
+ oid=$(git -C "$REPO" rev-parse $wanted_ref) &&
398
+ cat >expected_refs <<-EOF &&
399
+ $oid $wanted_ref
400
+ EOF
401
+ cat >expected_commits <<-EOF &&
402
+ $oid
403
+ $(git -C "$REPO" rev-parse a)
404
+ EOF
405
+
406
+ test-tool pkt-line pack >in <<-EOF &&
407
+ $(write_fetch_command $wanted_ref)
408
+ EOF
409
+
410
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
411
+ check_output
412
+ '
413
+
414
+ test_expect_success ' with namespace: hideRefs is matched, relative to namespace' '
415
+ wanted_ref=refs/heads/hidden &&
416
+ git -C "$REPO" config transfer.hideRefs $wanted_ref &&
417
+
418
+ test-tool pkt-line pack >in <<-EOF &&
419
+ $(write_fetch_command $wanted_ref)
420
+ EOF
421
+
422
+ test_must_fail env GIT_NAMESPACE=ns \
423
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
424
+ grep "unknown ref" out
425
+ '
426
+
427
+ # Cross-check refs/heads/hidden indeed exists
428
+ test_expect_success ' with namespace: want-ref succeeds if hideRefs is removed' '
429
+ wanted_ref=refs/heads/hidden &&
430
+ git -C "$REPO" config --unset transfer.hideRefs $wanted_ref &&
431
+
432
+ oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") &&
433
+ cat >expected_refs <<-EOF &&
434
+ $oid $wanted_ref
435
+ EOF
436
+ cat >expected_commits <<-EOF &&
437
+ $oid
438
+ $(git -C "$REPO" rev-parse a)
439
+ EOF
440
+
441
+ test-tool pkt-line pack >in <<-EOF &&
442
+ $(write_fetch_command $wanted_ref)
443
+ EOF
444
+
445
+ GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
446
+ check_output
447
+ '
448
+
449
+ test_expect_success ' without namespace: relative hideRefs does not match' '
450
+ wanted_ref=refs/namespaces/ns/refs/heads/hidden &&
451
+ git -C "$REPO" config transfer.hideRefs refs/heads/hidden &&
452
+
453
+ oid=$(git -C "$REPO" rev-parse $wanted_ref) &&
454
+ cat >expected_refs <<-EOF &&
455
+ $oid $wanted_ref
456
+ EOF
457
+ cat >expected_commits <<-EOF &&
458
+ $oid
459
+ $(git -C "$REPO" rev-parse a)
460
+ EOF
461
+
462
+ test-tool pkt-line pack >in <<-EOF &&
463
+ $(write_fetch_command $wanted_ref)
464
+ EOF
465
+
466
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
467
+ check_output
468
+ '
469
+
470
+
301
471
. " $TEST_DIRECTORY " /lib-httpd.sh
302
472
start_httpd
303
473
0 commit comments