summaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c98
1 files changed, 63 insertions, 35 deletions
diff --git a/transport.c b/transport.c
index eb4b2d4e47..b37664ba87 100644
--- a/transport.c
+++ b/transport.c
@@ -108,11 +108,11 @@ static void set_upstreams(struct transport *transport, struct ref *refs,
if (!remotename || !starts_with(remotename, "refs/heads/"))
continue;
- if (!pretend)
- install_branch_config(BRANCH_CONFIG_VERBOSE,
- localname + 11, transport->remote->name,
- remotename);
- else
+ if (!pretend) {
+ int flag = transport->verbose < 0 ? 0 : BRANCH_CONFIG_VERBOSE;
+ install_branch_config(flag, localname + 11,
+ transport->remote->name, remotename);
+ } else if (transport->verbose >= 0)
printf(_("Would set upstream of '%s' to '%s' of '%s'\n"),
localname + 11, remotename + 11,
transport->remote->name);
@@ -147,9 +147,11 @@ static struct ref *get_refs_from_bundle(struct transport *transport,
transport->hash_algo = data->header.hash_algo;
for (i = 0; i < data->header.references.nr; i++) {
- struct ref_list_entry *e = data->header.references.list + i;
- struct ref *ref = alloc_ref(e->name);
- oidcpy(&ref->old_oid, &e->oid);
+ struct string_list_item *e = data->header.references.items + i;
+ const char *name = e->string;
+ struct ref *ref = alloc_ref(name);
+ struct object_id *oid = e->util;
+ oidcpy(&ref->old_oid, oid);
ref->next = result;
result = ref;
}
@@ -160,12 +162,16 @@ static int fetch_refs_from_bundle(struct transport *transport,
int nr_heads, struct ref **to_fetch)
{
struct bundle_transport_data *data = transport->data;
+ struct strvec extra_index_pack_args = STRVEC_INIT;
int ret;
+ if (transport->progress)
+ strvec_push(&extra_index_pack_args, "-v");
+
if (!data->get_refs_from_bundle_called)
get_refs_from_bundle(transport, 0, NULL);
ret = unbundle(the_repository, &data->header, data->fd,
- transport->progress ? BUNDLE_VERBOSE : 0);
+ &extra_index_pack_args);
transport->hash_algo = data->header.hash_algo;
return ret;
}
@@ -175,6 +181,7 @@ static int close_bundle(struct transport *transport)
struct bundle_transport_data *data = transport->data;
if (data->fd > 0)
close(data->fd);
+ bundle_header_release(&data->header);
free(data);
return 0;
}
@@ -236,6 +243,9 @@ static int set_git_option(struct git_transport_options *opts,
list_objects_filter_die_if_populated(&opts->filter_options);
parse_list_objects_filter(&opts->filter_options, value);
return 0;
+ } else if (!strcmp(name, TRANS_OPT_REJECT_SHALLOW)) {
+ opts->reject_shallow = !!value;
+ return 0;
}
return 1;
}
@@ -370,6 +380,7 @@ static int fetch_refs_via_pack(struct transport *transport,
args.stateless_rpc = transport->stateless_rpc;
args.server_options = transport->server_options;
args.negotiation_tips = data->options.negotiation_tips;
+ args.reject_shallow_remote = transport->smart_options->reject_shallow;
if (!data->got_remote_heads) {
int i;
@@ -388,16 +399,29 @@ static int fetch_refs_via_pack(struct transport *transport,
else if (data->version <= protocol_v1)
die_if_server_options(transport);
+ if (data->options.acked_commits) {
+ if (data->version < protocol_v2) {
+ warning(_("--negotiate-only requires protocol v2"));
+ ret = -1;
+ } else if (!server_supports_feature("fetch", "wait-for-done", 0)) {
+ warning(_("server does not support wait-for-done"));
+ ret = -1;
+ } else {
+ negotiate_using_fetch(data->options.negotiation_tips,
+ transport->server_options,
+ transport->stateless_rpc,
+ data->fd,
+ data->options.acked_commits);
+ ret = 0;
+ }
+ goto cleanup;
+ }
+
refs = fetch_pack(&args, data->fd,
refs_tmp ? refs_tmp : transport->remote_refs,
to_fetch, nr_heads, &data->shallow,
&transport->pack_lockfiles, data->version);
- close(data->fd[0]);
- close(data->fd[1]);
- if (finish_connect(data->conn))
- ret = -1;
- data->conn = NULL;
data->got_remote_heads = 0;
data->options.self_contained_and_connected =
args.self_contained_and_connected;
@@ -408,6 +432,14 @@ static int fetch_refs_via_pack(struct transport *transport,
if (report_unmatched_refs(to_fetch, nr_heads))
ret = -1;
+cleanup:
+ close(data->fd[0]);
+ if (data->fd[1] >= 0)
+ close(data->fd[1]);
+ if (finish_connect(data->conn))
+ ret = -1;
+ data->conn = NULL;
+
free_refs(refs_tmp);
free_refs(refs);
return ret;
@@ -845,7 +877,8 @@ static int disconnect_git(struct transport *transport)
if (data->got_remote_heads && !transport->stateless_rpc)
packet_flush(data->fd[1]);
close(data->fd[0]);
- close(data->fd[1]);
+ if (data->fd[1] >= 0)
+ close(data->fd[1]);
finish_connect(data->conn);
}
@@ -854,12 +887,10 @@ static int disconnect_git(struct transport *transport)
}
static struct transport_vtable taken_over_vtable = {
- NULL,
- get_refs_via_connect,
- fetch_refs_via_pack,
- git_transport_push,
- NULL,
- disconnect_git
+ .get_refs_list = get_refs_via_connect,
+ .fetch_refs = fetch_refs_via_pack,
+ .push_refs = git_transport_push,
+ .disconnect = disconnect_git
};
void transport_take_over(struct transport *transport,
@@ -1003,21 +1034,17 @@ void transport_check_allowed(const char *type)
}
static struct transport_vtable bundle_vtable = {
- NULL,
- get_refs_from_bundle,
- fetch_refs_from_bundle,
- NULL,
- NULL,
- close_bundle
+ .get_refs_list = get_refs_from_bundle,
+ .fetch_refs = fetch_refs_from_bundle,
+ .disconnect = close_bundle
};
static struct transport_vtable builtin_smart_vtable = {
- NULL,
- get_refs_via_connect,
- fetch_refs_via_pack,
- git_transport_push,
- connect_git,
- disconnect_git
+ .get_refs_list = get_refs_via_connect,
+ .fetch_refs = fetch_refs_via_pack,
+ .push_refs = git_transport_push,
+ .connect = connect_git,
+ .disconnect = disconnect_git
};
struct transport *transport_get(struct remote *remote, const char *url)
@@ -1026,7 +1053,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
struct transport *ret = xcalloc(1, sizeof(*ret));
ret->progress = isatty(2);
- string_list_init(&ret->pack_lockfiles, 1);
+ string_list_init_dup(&ret->pack_lockfiles);
if (!remote)
BUG("No remote provided to transport_get()");
@@ -1055,6 +1082,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
die(_("git-over-rsync is no longer supported"));
} else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
+ bundle_header_init(&data->header);
transport_check_allowed("file");
ret->data = data;
ret->vtable = &bundle_vtable;
@@ -1423,7 +1451,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
heads[nr_heads++] = rm;
}
- rc = transport->vtable->fetch(transport, nr_heads, heads);
+ rc = transport->vtable->fetch_refs(transport, nr_heads, heads);
free(heads);
return rc;