mirror of
https://github.com/git/git.git
synced 2024-05-26 22:16:15 +02:00
Merge branch 'bc/clone-empty-repo-via-protocol-v0' into next
* bc/clone-empty-repo-via-protocol-v0: upload-pack: advertise capabilities when cloning empty repos
This commit is contained in:
commit
d320de7ee9
|
@ -611,6 +611,33 @@ test_expect_success 'client falls back from v2 to v0 to match server' '
|
|||
grep symref=HEAD:refs/heads/ trace
|
||||
'
|
||||
|
||||
test_expect_success 'create empty http-accessible SHA-256 repository' '
|
||||
mkdir "$HTTPD_DOCUMENT_ROOT_PATH/sha256.git" &&
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH/sha256.git" &&
|
||||
git --bare init --object-format=sha256
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'clone empty SHA-256 repository with protocol v2' '
|
||||
rm -fr sha256 &&
|
||||
echo sha256 >expected &&
|
||||
git -c protocol.version=2 clone "$HTTPD_URL/smart/sha256.git" &&
|
||||
git -C sha256 rev-parse --show-object-format >actual &&
|
||||
test_cmp actual expected &&
|
||||
git ls-remote "$HTTPD_URL/smart/sha256.git" >actual &&
|
||||
test_must_be_empty actual
|
||||
'
|
||||
|
||||
test_expect_success 'clone empty SHA-256 repository with protocol v0' '
|
||||
rm -fr sha256 &&
|
||||
echo sha256 >expected &&
|
||||
GIT_TRACE=1 GIT_TRACE_PACKET=1 git -c protocol.version=0 clone "$HTTPD_URL/smart/sha256.git" &&
|
||||
git -C sha256 rev-parse --show-object-format >actual &&
|
||||
test_cmp actual expected &&
|
||||
git ls-remote "$HTTPD_URL/smart/sha256.git" >actual &&
|
||||
test_must_be_empty actual
|
||||
'
|
||||
|
||||
test_expect_success 'passing hostname resolution information works' '
|
||||
BOGUS_HOST=gitbogusexamplehost.invalid &&
|
||||
BOGUS_HTTPD_URL=$HTTPD_PROTO://$BOGUS_HOST:$LIB_HTTPD_PORT &&
|
||||
|
|
|
@ -244,15 +244,28 @@ test_expect_success 'push with ssh:// using protocol v1' '
|
|||
grep "push< version 1" log
|
||||
'
|
||||
|
||||
test_expect_success 'clone propagates object-format from empty repo' '
|
||||
test_when_finished "rm -fr src256 dst256" &&
|
||||
|
||||
echo sha256 >expect &&
|
||||
git init --object-format=sha256 src256 &&
|
||||
git clone --no-local src256 dst256 &&
|
||||
git -C dst256 rev-parse --show-object-format >actual &&
|
||||
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Test protocol v1 with 'http://' transport
|
||||
#
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
start_httpd
|
||||
|
||||
test_expect_success 'create repo to be served by http:// transport' '
|
||||
test_expect_success 'create repos to be served by http:// transport' '
|
||||
git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
|
||||
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" config http.receivepack true &&
|
||||
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one
|
||||
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one &&
|
||||
git init --object-format=sha256 "$HTTPD_DOCUMENT_ROOT_PATH/sha256" &&
|
||||
git -C "$HTTPD_DOCUMENT_ROOT_PATH/sha256" config http.receivepack true
|
||||
'
|
||||
|
||||
test_expect_success 'clone with http:// using protocol v1' '
|
||||
|
@ -269,6 +282,20 @@ test_expect_success 'clone with http:// using protocol v1' '
|
|||
grep "git< version 1" log
|
||||
'
|
||||
|
||||
test_expect_success 'clone with http:// using protocol v1 with empty SHA-256 repo' '
|
||||
GIT_TRACE_PACKET=1 GIT_TRACE_CURL=1 git -c protocol.version=1 \
|
||||
clone "$HTTPD_URL/smart/sha256" sha256 2>log &&
|
||||
|
||||
echo sha256 >expect &&
|
||||
git -C sha256 rev-parse --show-object-format >actual &&
|
||||
test_cmp expect actual &&
|
||||
|
||||
# Client requested to use protocol v1
|
||||
grep "Git-Protocol: version=1" log &&
|
||||
# Server responded using protocol v1
|
||||
grep "git< version 1" log
|
||||
'
|
||||
|
||||
test_expect_success 'fetch with http:// using protocol v1' '
|
||||
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ struct upload_pack_data {
|
|||
unsigned allow_ref_in_want : 1; /* v2 only */
|
||||
unsigned allow_sideband_all : 1; /* v2 only */
|
||||
unsigned advertise_sid : 1;
|
||||
unsigned sent_capabilities : 1;
|
||||
};
|
||||
|
||||
static void upload_pack_data_init(struct upload_pack_data *data)
|
||||
|
@ -1206,18 +1207,17 @@ static void format_session_id(struct strbuf *buf, struct upload_pack_data *d) {
|
|||
strbuf_addf(buf, " session-id=%s", trace2_session_id());
|
||||
}
|
||||
|
||||
static int send_ref(const char *refname, const struct object_id *oid,
|
||||
int flag UNUSED, void *cb_data)
|
||||
static void write_v0_ref(struct upload_pack_data *data,
|
||||
const char *refname, const char *refname_nons,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
static const char *capabilities = "multi_ack thin-pack side-band"
|
||||
" side-band-64k ofs-delta shallow deepen-since deepen-not"
|
||||
" deepen-relative no-progress include-tag multi_ack_detailed";
|
||||
const char *refname_nons = strip_namespace(refname);
|
||||
struct object_id peeled;
|
||||
struct upload_pack_data *data = cb_data;
|
||||
|
||||
if (mark_our_ref(refname_nons, refname, oid, &data->hidden_refs))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (capabilities) {
|
||||
struct strbuf symref_info = STRBUF_INIT;
|
||||
|
@ -1240,12 +1240,20 @@ static int send_ref(const char *refname, const struct object_id *oid,
|
|||
git_user_agent_sanitized());
|
||||
strbuf_release(&symref_info);
|
||||
strbuf_release(&session_id);
|
||||
data->sent_capabilities = 1;
|
||||
} else {
|
||||
packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(oid), refname_nons);
|
||||
}
|
||||
capabilities = NULL;
|
||||
if (!peel_iterated_oid(oid, &peeled))
|
||||
packet_fwrite_fmt(stdout, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons);
|
||||
return;
|
||||
}
|
||||
|
||||
static int send_ref(const char *refname, const struct object_id *oid,
|
||||
int flag UNUSED, void *cb_data)
|
||||
{
|
||||
write_v0_ref(cb_data, refname, strip_namespace(refname), oid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1379,6 +1387,10 @@ void upload_pack(const int advertise_refs, const int stateless_rpc,
|
|||
data.no_done = 1;
|
||||
head_ref_namespaced(send_ref, &data);
|
||||
for_each_namespaced_ref(send_ref, &data);
|
||||
if (!data.sent_capabilities) {
|
||||
const char *refname = "capabilities^{}";
|
||||
write_v0_ref(&data, refname, refname, null_oid());
|
||||
}
|
||||
/*
|
||||
* fflush stdout before calling advertise_shallow_grafts because send_ref
|
||||
* uses stdio.
|
||||
|
|
Loading…
Reference in New Issue