http-backend: respect GIT_NAMESPACE with dumb clients
Filter the list of refs returned via the dumb HTTP protocol according to the active namespace, consistent with other clients of the upload-pack service. Signed-off-by: John Koleszar <jkoleszar@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
John Koleszar committed
Apr 9, 2013 at 17:55 UTC
6130f86deabe15c78d966b3588f47dbd653ec4fa
3 files changed
+63
-4
http-backend.c
+34
-4
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
361
static int show_text_ref(const char *name, const unsigned char *sha1,
362
int flag, void *cb_data)
363
{
364
+ const char *name_nons = strip_namespace(name);
365
struct strbuf *buf = cb_data;
366
struct object *o = parse_object(sha1);
367
if (!o)
368
return 0;
369
369
- strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name);
370
+ strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name_nons);
371
if (o->type == OBJ_TAG) {
372
o = deref_tag(o, name, 0);
373
if (!o)
374
return 0;
374
- strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), name);
375
+ strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1),
376
+ name_nons);
377
}
378
return 0;
379
}
@@ -402,12 +404,40 @@ static void get_info_refs(char *arg)
404
405
} else {
406
select_getanyfile();
405
- for_each_ref(show_text_ref, &buf);
407
+ for_each_namespaced_ref(show_text_ref, &buf);
408
send_strbuf("text/plain", &buf);
409
}
410
strbuf_release(&buf);
411
}
412
413
+static int show_head_ref(const char *name, const unsigned char *sha1,
414
+ int flag, void *cb_data)
415
+{
416
+ struct strbuf *buf = cb_data;
417
+
418
+ if (flag & REF_ISSYMREF) {
419
+ unsigned char sha1[20];
420
+ const char *target = resolve_ref_unsafe(name, sha1, 1, NULL);
421
+ const char *target_nons = strip_namespace(target);
422
+
423
+ strbuf_addf(buf, "ref: %s\n", target_nons);
424
+ } else {
425
+ strbuf_addf(buf, "%s\n", sha1_to_hex(sha1));
426
+ }
427
+
428
+ return 0;
429
+}
430
+
431
+static void get_head(char *arg)
432
+{
433
+ struct strbuf buf = STRBUF_INIT;
434
+
435
+ select_getanyfile();
436
+ head_ref_namespaced(show_head_ref, &buf);
437
+ send_strbuf("text/plain", &buf);
438
+ strbuf_release(&buf);
439
+}
440
+
441
static void get_info_packs(char *arg)
442
{
443
size_t objdirlen = strlen(get_object_directory());
@@ -520,7 +550,7 @@ static struct service_cmd {
550
const char *pattern;
551
void (*imp)(char *);
552
} services[] = {
523
- {"GET", "/HEAD$", get_text_file},
553
+ {"GET", "/HEAD$", get_head},
554
{"GET", "/info/refs$", get_info_refs},
555
{"GET", "/objects/info/alternates$", get_text_file},
556
{"GET", "/objects/info/http-alternates$", get_text_file},
t/lib-httpd/apache.conf
+5
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
61
SetEnv GIT_COMMITTER_NAME "Custom User"
62
SetEnv GIT_COMMITTER_EMAIL custom@example.com
63
</LocationMatch>
64
+<LocationMatch /smart_namespace/>
65
+ SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
66
+ SetEnv GIT_HTTP_EXPORT_ALL
67
+ SetEnv GIT_NAMESPACE ns
68
+</LocationMatch>
69
ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
70
ScriptAlias /broken_smart/ broken-smart-http.sh/
71
<Directory ${GIT_EXEC_PATH}>
t/t5551-http-fetch.sh
+24
@@ -162,6 +162,30 @@ test_expect_success 'invalid Content-Type rejected' '
162
grep "not valid:" actual
163
'
164
165
+test_expect_success 'create namespaced refs' '
166
+ test_commit namespaced &&
167
+ git push public HEAD:refs/namespaces/ns/refs/heads/master &&
168
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
169
+ symbolic-ref refs/namespaces/ns/HEAD refs/namespaces/ns/refs/heads/master
170
+'
171
+
172
+test_expect_success 'smart clone respects namespace' '
173
+ git clone "$HTTPD_URL/smart_namespace/repo.git" ns-smart &&
174
+ echo namespaced >expect &&
175
+ git --git-dir=ns-smart/.git log -1 --format=%s >actual &&
176
+ test_cmp expect actual
177
+'
178
+
179
+test_expect_success 'dumb clone via http-backend respects namespace' '
180
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
181
+ config http.getanyfile true &&
182
+ GIT_SMART_HTTP=0 git clone \
183
+ "$HTTPD_URL/smart_namespace/repo.git" ns-dumb &&
184
+ echo namespaced >expect &&
185
+ git --git-dir=ns-dumb/.git log -1 --format=%s >actual &&
186
+ test_cmp expect actual
187
+'
188
+
189
test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
190
191
test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '