diff options
Diffstat (limited to 'remote.c')
| -rw-r--r-- | remote.c | 128 |
1 files changed, 104 insertions, 24 deletions
@@ -24,6 +24,7 @@ #include "advice.h" #include "connect.h" #include "parse-options.h" +#include "transport.h" enum map_direction { FROM_SRC, FROM_DST }; @@ -143,6 +144,7 @@ static struct remote *make_remote(struct remote_state *remote_state, ret->name = xstrndup(name, len); refspec_init(&ret->push, REFSPEC_PUSH); refspec_init(&ret->fetch, REFSPEC_FETCH); + string_list_init_dup(&ret->server_options); ALLOC_GROW(remote_state->remotes, remote_state->remotes_nr + 1, remote_state->remotes_alloc); @@ -166,6 +168,7 @@ static void remote_clear(struct remote *remote) free((char *)remote->uploadpack); FREE_AND_NULL(remote->http_proxy); FREE_AND_NULL(remote->http_proxy_authmethod); + string_list_clear(&remote->server_options, 0); } static void add_merge(struct branch *branch, const char *name) @@ -243,6 +246,17 @@ static struct branch *make_branch(struct remote_state *remote_state, return ret; } +static void branch_release(struct branch *branch) +{ + free((char *)branch->name); + free((char *)branch->refname); + free(branch->remote_name); + free(branch->pushremote_name); + for (int i = 0; i < branch->merge_nr; i++) + refspec_item_clear(branch->merge[i]); + free(branch->merge); +} + static struct rewrite *make_rewrite(struct rewrites *r, const char *base, size_t len) { @@ -263,6 +277,14 @@ static struct rewrite *make_rewrite(struct rewrites *r, return ret; } +static void rewrites_release(struct rewrites *r) +{ + for (int i = 0; i < r->rewrite_nr; i++) + free((char *)r->rewrite[i]->base); + free(r->rewrite); + memset(r, 0, sizeof(*r)); +} + static void add_instead_of(struct rewrite *rewrite, const char *instead_of) { ALLOC_GROW(rewrite->instead_of, rewrite->instead_of_nr + 1, rewrite->instead_of_alloc); @@ -373,8 +395,10 @@ static int handle_config(const char *key, const char *value, return -1; branch = make_branch(remote_state, name, namelen); if (!strcmp(subkey, "remote")) { + FREE_AND_NULL(branch->remote_name); return git_config_string(&branch->remote_name, key, value); } else if (!strcmp(subkey, "pushremote")) { + FREE_AND_NULL(branch->pushremote_name); return git_config_string(&branch->pushremote_name, key, value); } else if (!strcmp(subkey, "merge")) { if (!value) @@ -406,9 +430,11 @@ static int handle_config(const char *key, const char *value, return 0; /* Handle remote.* variables */ - if (!name && !strcmp(subkey, "pushdefault")) + if (!name && !strcmp(subkey, "pushdefault")) { + FREE_AND_NULL(remote_state->pushremote_name); return git_config_string(&remote_state->pushremote_name, key, value); + } if (!name) return 0; @@ -475,13 +501,19 @@ static int handle_config(const char *key, const char *value, else if (!strcmp(value, "--tags")) remote->fetch_tags = 2; } else if (!strcmp(subkey, "proxy")) { + FREE_AND_NULL(remote->http_proxy); return git_config_string(&remote->http_proxy, key, value); } else if (!strcmp(subkey, "proxyauthmethod")) { + FREE_AND_NULL(remote->http_proxy_authmethod); return git_config_string(&remote->http_proxy_authmethod, key, value); } else if (!strcmp(subkey, "vcs")) { + FREE_AND_NULL(remote->foreign_vcs); return git_config_string(&remote->foreign_vcs, key, value); + } else if (!strcmp(subkey, "serveroption")) { + return parse_transport_option(key, value, + &remote->server_options); } return 0; } @@ -499,6 +531,7 @@ static void alias_all_urls(struct remote_state *remote_state) if (alias) strvec_replace(&remote_state->remotes[i]->pushurl, j, alias); + free(alias); } add_pushurl_aliases = remote_state->remotes[i]->pushurl.nr == 0; for (j = 0; j < remote_state->remotes[i]->url.nr; j++) { @@ -512,6 +545,7 @@ static void alias_all_urls(struct remote_state *remote_state) if (alias) strvec_replace(&remote_state->remotes[i]->url, j, alias); + free(alias); } } } @@ -604,7 +638,7 @@ const char *pushremote_for_branch(struct branch *branch, int *explicit) static struct remote *remotes_remote_get(struct remote_state *remote_state, const char *name); -const char *remote_ref_for_branch(struct branch *branch, int for_push) +char *remote_ref_for_branch(struct branch *branch, int for_push) { read_config(the_repository, 0); die_on_missing_branch(the_repository, branch); @@ -612,11 +646,11 @@ const char *remote_ref_for_branch(struct branch *branch, int for_push) if (branch) { if (!for_push) { if (branch->merge_nr) { - return branch->merge_name[0]; + return xstrdup(branch->merge_name[0]); } } else { - const char *dst, - *remote_name = remotes_pushremote_for_branch( + char *dst; + const char *remote_name = remotes_pushremote_for_branch( the_repository->remote_state, branch, NULL); struct remote *remote = remotes_remote_get( @@ -840,6 +874,20 @@ struct strvec *push_url_of_remote(struct remote *remote) return remote->pushurl.nr ? &remote->pushurl : &remote->url; } +void ref_push_report_free(struct ref_push_report *report) +{ + while (report) { + struct ref_push_report *next = report->next; + + free(report->ref_name); + free(report->old_oid); + free(report->new_oid); + free(report); + + report = next; + } +} + static int match_name_with_pattern(const char *key, const char *name, const char *value, char **result) { @@ -1094,7 +1142,9 @@ void free_one_ref(struct ref *ref) if (!ref) return; free_one_ref(ref->peer_ref); + ref_push_report_free(ref->report); free(ref->remote_status); + free(ref->tracking_ref); free(ref->symref); free(ref); } @@ -1316,18 +1366,21 @@ static int match_explicit(struct ref *src, struct ref *dst, struct ref ***dst_tail, struct refspec_item *rs) { - struct ref *matched_src, *matched_dst; - int allocated_src; + struct ref *matched_src = NULL, *matched_dst = NULL; + int allocated_src = 0, ret; const char *dst_value = rs->dst; char *dst_guess; - if (rs->pattern || rs->matching || rs->negative) - return 0; + if (rs->pattern || rs->matching || rs->negative) { + ret = 0; + goto out; + } - matched_src = matched_dst = NULL; - if (match_explicit_lhs(src, rs, &matched_src, &allocated_src) < 0) - return -1; + if (match_explicit_lhs(src, rs, &matched_src, &allocated_src) < 0) { + ret = -1; + goto out; + } if (!dst_value) { int flag; @@ -1366,18 +1419,30 @@ static int match_explicit(struct ref *src, struct ref *dst, dst_value); break; } - if (!matched_dst) - return -1; - if (matched_dst->peer_ref) - return error(_("dst ref %s receives from more than one src"), - matched_dst->name); - else { + + if (!matched_dst) { + ret = -1; + goto out; + } + + if (matched_dst->peer_ref) { + ret = error(_("dst ref %s receives from more than one src"), + matched_dst->name); + goto out; + } else { matched_dst->peer_ref = allocated_src ? matched_src : copy_ref(matched_src); matched_dst->force = rs->force; + matched_src = NULL; } - return 0; + + ret = 0; + +out: + if (allocated_src) + free_one_ref(matched_src); + return ret; } static int match_explicit_refs(struct ref *src, struct ref *dst, @@ -2038,6 +2103,8 @@ static struct ref *get_expanded_map(const struct ref *remote_refs, !ignore_symref_update(expn_name, &scratch)) { struct ref *cpy = copy_ref(ref); + if (cpy->peer_ref) + free_one_ref(cpy->peer_ref); cpy->peer_ref = alloc_ref(expn_name); if (refspec->force) cpy->peer_ref->force = 1; @@ -2354,7 +2421,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb, return 1; } -static int one_local_ref(const char *refname, const struct object_id *oid, +static int one_local_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, int flag UNUSED, void *cb_data) { @@ -2439,7 +2506,7 @@ struct stale_heads_info { struct refspec *rs; }; -static int get_stale_heads_cb(const char *refname, const struct object_id *oid, +static int get_stale_heads_cb(const char *refname, const char *referent UNUSED, const struct object_id *oid, int flags, void *cb_data) { struct stale_heads_info *info = cb_data; @@ -2498,7 +2565,7 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map) /* * Compare-and-swap */ -static void clear_cas_option(struct push_cas_option *cas) +void clear_cas_option(struct push_cas_option *cas) { int i; @@ -2575,8 +2642,10 @@ static int remote_tracking(struct remote *remote, const char *refname, dst = apply_refspecs(&remote->fetch, refname); if (!dst) return -1; /* no tracking ref for refname at remote */ - if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) + if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) { + free(dst); return -1; /* we know what the tracking ref is but we cannot read it */ + } *dst_refname = dst; return 0; @@ -2726,6 +2795,7 @@ static void check_if_includes_upstream(struct ref *remote) if (is_reachable_in_reflog(local->name, remote) <= 0) remote->unreachable = 1; + free_one_ref(local); } static void apply_cas(struct push_cas_option *cas, @@ -2795,16 +2865,26 @@ struct remote_state *remote_state_new(void) void remote_state_clear(struct remote_state *remote_state) { + struct hashmap_iter iter; + struct branch *b; int i; for (i = 0; i < remote_state->remotes_nr; i++) remote_clear(remote_state->remotes[i]); FREE_AND_NULL(remote_state->remotes); + FREE_AND_NULL(remote_state->pushremote_name); remote_state->remotes_alloc = 0; remote_state->remotes_nr = 0; + rewrites_release(&remote_state->rewrites); + rewrites_release(&remote_state->rewrites_push); + hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent); - hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent); + hashmap_for_each_entry(&remote_state->branches_hash, &iter, b, ent) { + branch_release(b); + free(b); + } + hashmap_clear(&remote_state->branches_hash); } /* |
