diff options
Diffstat (limited to 'transport.c')
| -rw-r--r-- | transport.c | 83 |
1 files changed, 60 insertions, 23 deletions
diff --git a/transport.c b/transport.c index 219af8fd50..47fda6a773 100644 --- a/transport.c +++ b/transport.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "advice.h" #include "config.h" @@ -10,9 +12,7 @@ #include "remote.h" #include "connect.h" #include "send-pack.h" -#include "walker.h" #include "bundle.h" -#include "dir.h" #include "gettext.h" #include "refs.h" #include "refspec.h" @@ -26,7 +26,6 @@ #include "transport-internal.h" #include "protocol.h" #include "object-name.h" -#include "object-store-ll.h" #include "color.h" #include "bundle-uri.h" @@ -103,8 +102,9 @@ static void set_upstreams(struct transport *transport, struct ref *refs, /* Follow symbolic refs (mainly for HEAD). */ localname = ref->peer_ref->name; remotename = ref->name; - tmp = resolve_ref_unsafe(localname, RESOLVE_REF_READING, - NULL, &flag); + tmp = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + localname, RESOLVE_REF_READING, + NULL, &flag); if (tmp && flag & REF_ISSYMREF && starts_with(tmp, "refs/heads/")) localname = tmp; @@ -186,8 +186,11 @@ static int fetch_refs_from_bundle(struct transport *transport, if (!data->get_refs_from_bundle_called) get_refs_from_bundle_inner(transport); ret = unbundle(the_repository, &data->header, data->fd, - &extra_index_pack_args, 0); + &extra_index_pack_args, + fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0); transport->hash_algo = data->header.hash_algo; + + strvec_clear(&extra_index_pack_args); return ret; } @@ -331,6 +334,9 @@ static struct ref *handshake(struct transport *transport, int for_push, data->version = discover_version(&reader); switch (data->version) { case protocol_v2: + if ((!transport->server_options || !transport->server_options->nr) && + transport->remote->server_options.nr) + transport->server_options = &transport->remote->server_options; if (server_feature_v2("session-id", &server_sid)) trace2_data_string("transfer", NULL, "server-sid", server_sid); if (must_list_refs) @@ -411,7 +417,7 @@ static int fetch_refs_via_pack(struct transport *transport, struct git_transport_data *data = transport->data; struct ref *refs = NULL; struct fetch_pack_args args; - struct ref *refs_tmp = NULL; + struct ref *refs_tmp = NULL, **to_fetch_dup = NULL; memset(&args, 0, sizeof(args)); args.uploadpack = data->options.uploadpack; @@ -474,6 +480,14 @@ static int fetch_refs_via_pack(struct transport *transport, goto cleanup; } + /* + * Create a shallow copy of `sought` so that we can free all of its entries. + * This is because `fetch_pack()` will modify the array to evict some + * entries, but won't free those. + */ + DUP_ARRAY(to_fetch_dup, to_fetch, nr_heads); + to_fetch = to_fetch_dup; + refs = fetch_pack(&args, data->fd, refs_tmp ? refs_tmp : transport->remote_refs, to_fetch, nr_heads, &data->shallow, @@ -497,6 +511,7 @@ cleanup: ret = -1; data->conn = NULL; + free(to_fetch_dup); free_refs(refs_tmp); free_refs(refs); list_objects_filter_release(&args.filter_options); @@ -546,10 +561,12 @@ static void update_one_tracking_ref(struct remote *remote, char *refname, if (verbose) fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst); if (deletion) - delete_ref(NULL, rs.dst, NULL, 0); + refs_delete_ref(get_main_ref_store(the_repository), + NULL, rs.dst, NULL, 0); else - update_ref("update by push", rs.dst, new_oid, - NULL, 0, 0); + refs_update_ref(get_main_ref_store(the_repository), + "update by push", rs.dst, new_oid, + NULL, 0, 0); free(rs.dst); } } @@ -817,7 +834,8 @@ void transport_print_push_status(const char *dest, struct ref *refs, if (transport_color_config() < 0) warning(_("could not parse transport.color.* config")); - head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL); + head = refs_resolve_refdup(get_main_ref_store(the_repository), "HEAD", + RESOLVE_REF_READING, NULL, NULL); if (verbose) { for (ref = refs; ref; ref = ref->next) @@ -941,7 +959,13 @@ static int disconnect_git(struct transport *transport) finish_connect(data->conn); } + if (data->options.negotiation_tips) { + oid_array_clear(data->options.negotiation_tips); + free(data->options.negotiation_tips); + } list_objects_filter_release(&data->options.filter_options); + oid_array_clear(&data->extra_have); + oid_array_clear(&data->shallow); free(data); return 0; } @@ -1087,6 +1111,18 @@ int is_transport_allowed(const char *type, int from_user) BUG("invalid protocol_allow_config type"); } +int parse_transport_option(const char *var, const char *value, + struct string_list *transport_options) +{ + if (!value) + return config_error_nonbool(var); + if (!*value) + string_list_clear(transport_options, 0); + else + string_list_append(transport_options, value); + return 0; +} + void transport_check_allowed(const char *type) { if (!is_transport_allowed(type, -1)) @@ -1111,6 +1147,8 @@ static struct transport_vtable builtin_smart_vtable = { struct transport *transport_get(struct remote *remote, const char *url) { const char *helper; + char *helper_to_free = NULL; + const char *p; struct transport *ret = xcalloc(1, sizeof(*ret)); ret->progress = isatty(2); @@ -1126,22 +1164,19 @@ struct transport *transport_get(struct remote *remote, const char *url) ret->remote = remote; helper = remote->foreign_vcs; - if (!url && remote->url) - url = remote->url[0]; + if (!url) + url = remote->url.v[0]; ret->url = url; - /* maybe it is a foreign URL? */ - if (url) { - const char *p = url; - - while (is_urlschemechar(p == url, *p)) - p++; - if (starts_with(p, "::")) - helper = xstrndup(url, p - url); - } + p = url; + while (is_urlschemechar(p == url, *p)) + p++; + if (starts_with(p, "::")) + helper = helper_to_free = xstrndup(url, p - url); if (helper) { transport_helper_init(ret, helper); + free(helper_to_free); } else if (starts_with(url, "rsync:")) { die(_("git-over-rsync is no longer supported")); } else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) { @@ -1175,6 +1210,7 @@ struct transport *transport_get(struct remote *remote, const char *url) int len = external_specification_len(url); char *handler = xmemdupz(url, len); transport_helper_init(ret, handler); + free(handler); } if (ret->smart_options) { @@ -1269,7 +1305,7 @@ static int run_pre_push_hook(struct transport *transport, struct ref *r; struct child_process proc = CHILD_PROCESS_INIT; struct strbuf buf; - const char *hook_path = find_hook("pre-push"); + const char *hook_path = find_hook(the_repository, "pre-push"); if (!hook_path) return 0; @@ -1470,6 +1506,7 @@ int transport_push(struct repository *r, if (porcelain && !push_ret) puts("Done"); else if (!quiet && !ret && !transport_refs_pushed(remote_refs)) + /* stable plumbing output; do not modify or localize */ fprintf(stderr, "Everything up-to-date\n"); done: |
