ref namespaces: Support remote repositories via upload-pack and receive-pack

Change upload-pack and receive-pack to use the namespace-prefixed refs
when working with the repository, and use the unprefixed refs when
talking to the client, maintaining the masquerade.  This allows
clone, pull, fetch, and push to work with a suitably configured
GIT_NAMESPACE.

receive-pack advertises refs outside the current namespace as .have refs
(as it currently does for refs in alternates), so that the client can
use them to minimize data transfer but will otherwise ignore them.

With appropriate configuration, this also allows http-backend to expose
namespaces as multiple repositories with different paths.  This only
requires setting GIT_NAMESPACE, which http-backend passes through to
upload-pack and receive-pack.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Josh Triplett
2011-07-08 16:13:32 -07:00
committed by Junio C Hamano
parent a1bea2c1fc
commit 6b01ecfe22
2 changed files with 47 additions and 13 deletions

View File

@ -641,16 +641,17 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
" side-band-64k ofs-delta shallow no-progress"
" include-tag multi_ack_detailed";
struct object *o = parse_object(sha1);
const char *refname_nons = strip_namespace(refname);
if (!o)
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
if (capabilities)
packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname,
packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname_nons,
0, capabilities,
stateless_rpc ? " no-done" : "");
else
packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
capabilities = NULL;
if (!(o->flags & OUR_REF)) {
o->flags |= OUR_REF;
@ -659,7 +660,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
if (o->type == OBJ_TAG) {
o = deref_tag(o, refname, 0);
if (o)
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname_nons);
}
return 0;
}
@ -680,12 +681,12 @@ static void upload_pack(void)
{
if (advertise_refs || !stateless_rpc) {
reset_timeout();
head_ref(send_ref, NULL);
for_each_ref(send_ref, NULL);
head_ref_namespaced(send_ref, NULL);
for_each_namespaced_ref(send_ref, NULL);
packet_flush(1);
} else {
head_ref(mark_our_ref, NULL);
for_each_ref(mark_our_ref, NULL);
head_ref_namespaced(mark_our_ref, NULL);
for_each_namespaced_ref(mark_our_ref, NULL);
}
if (advertise_refs)
return;