diff options
Diffstat (limited to 'transport.c')
-rw-r--r-- | transport.c | 98 |
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; |