diff options
Diffstat (limited to 'remote.c')
| -rw-r--r-- | remote.c | 436 |
1 files changed, 160 insertions, 276 deletions
@@ -12,7 +12,7 @@ #include "refs.h" #include "refspec.h" #include "object-name.h" -#include "object-store-ll.h" +#include "odb.h" #include "path.h" #include "commit.h" #include "diff.h" @@ -143,8 +143,8 @@ static struct remote *make_remote(struct remote_state *remote_state, ret->prune = -1; /* unspecified */ ret->prune_tags = -1; /* unspecified */ ret->name = xstrndup(name, len); - refspec_init(&ret->push, REFSPEC_PUSH); - refspec_init(&ret->fetch, REFSPEC_FETCH); + refspec_init_push(&ret->push); + refspec_init_fetch(&ret->fetch); string_list_init_dup(&ret->server_options); ALLOC_GROW(remote_state->remotes, remote_state->remotes_nr + 1, @@ -165,6 +165,9 @@ static void remote_clear(struct remote *remote) strvec_clear(&remote->url); strvec_clear(&remote->pushurl); + refspec_clear(&remote->push); + refspec_clear(&remote->fetch); + free((char *)remote->receivepack); free((char *)remote->uploadpack); FREE_AND_NULL(remote->http_proxy); @@ -174,9 +177,15 @@ static void remote_clear(struct remote *remote) static void add_merge(struct branch *branch, const char *name) { - ALLOC_GROW(branch->merge_name, branch->merge_nr + 1, + struct refspec_item *merge; + + ALLOC_GROW(branch->merge, branch->merge_nr + 1, branch->merge_alloc); - branch->merge_name[branch->merge_nr++] = name; + + merge = xcalloc(1, sizeof(*merge)); + merge->src = xstrdup(name); + + branch->merge[branch->merge_nr++] = merge; } struct branches_hash_key { @@ -247,15 +256,23 @@ static struct branch *make_branch(struct remote_state *remote_state, return ret; } +static void merge_clear(struct branch *branch) +{ + for (int i = 0; i < branch->merge_nr; i++) { + refspec_item_clear(branch->merge[i]); + free(branch->merge[i]); + } + FREE_AND_NULL(branch->merge); + branch->merge_nr = 0; +} + 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); + merge_clear(branch); } static struct rewrite *make_rewrite(struct rewrites *r, @@ -294,6 +311,7 @@ static void add_instead_of(struct rewrite *rewrite, const char *instead_of) rewrite->instead_of_nr++; } +#ifndef WITH_BREAKING_CHANGES static const char *skip_spaces(const char *s) { while (isspace(*s)) @@ -301,14 +319,32 @@ static const char *skip_spaces(const char *s) return s; } -static void read_remotes_file(struct remote_state *remote_state, - struct remote *remote) +static void warn_about_deprecated_remote_type(const char *type, + const struct remote *remote) +{ + warning(_("reading remote from \"%s/%s\", which is nominated for removal.\n" + "\n" + "If you still use the \"remotes/\" directory it is recommended to\n" + "migrate to config-based remotes:\n" + "\n" + "\tgit remote rename %s %s\n" + "\n" + "If you cannot, please let us know why you still need to use it by\n" + "sending an e-mail to <git@vger.kernel.org>."), + type, remote->name, remote->name, remote->name); +} + +static void read_remotes_file(struct repository *repo, struct remote *remote) { struct strbuf buf = STRBUF_INIT; - FILE *f = fopen_or_warn(git_path("remotes/%s", remote->name), "r"); + FILE *f = fopen_or_warn(repo_git_path_append(repo, &buf, + "remotes/%s", remote->name), "r"); if (!f) - return; + goto out; + + warn_about_deprecated_remote_type("remotes", remote); + remote->configured_in_repo = 1; remote->origin = REMOTE_REMOTES; while (strbuf_getline(&buf, f) != EOF) { @@ -317,34 +353,36 @@ static void read_remotes_file(struct remote_state *remote_state, strbuf_rtrim(&buf); if (skip_prefix(buf.buf, "URL:", &v)) - add_url_alias(remote_state, remote, + add_url_alias(repo->remote_state, remote, skip_spaces(v)); else if (skip_prefix(buf.buf, "Push:", &v)) refspec_append(&remote->push, skip_spaces(v)); else if (skip_prefix(buf.buf, "Pull:", &v)) refspec_append(&remote->fetch, skip_spaces(v)); } - strbuf_release(&buf); fclose(f); + +out: + strbuf_release(&buf); } -static void read_branches_file(struct remote_state *remote_state, - struct remote *remote) +static void read_branches_file(struct repository *repo, struct remote *remote) { char *frag, *to_free = NULL; struct strbuf buf = STRBUF_INIT; - FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r"); + FILE *f = fopen_or_warn(repo_git_path_append(repo, &buf, + "branches/%s", remote->name), "r"); if (!f) - return; + goto out; + + warn_about_deprecated_remote_type("branches", remote); strbuf_getline_lf(&buf, f); fclose(f); strbuf_trim(&buf); - if (!buf.len) { - strbuf_release(&buf); - return; - } + if (!buf.len) + goto out; remote->configured_in_repo = 1; remote->origin = REMOTE_BRANCHES; @@ -359,9 +397,9 @@ static void read_branches_file(struct remote_state *remote_state, if (frag) *(frag++) = '\0'; else - frag = to_free = repo_default_branch_name(the_repository, 0); + frag = to_free = repo_default_branch_name(repo, 0); - add_url_alias(remote_state, remote, buf.buf); + add_url_alias(repo->remote_state, remote, buf.buf); refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s", frag, remote->name); @@ -372,9 +410,11 @@ static void read_branches_file(struct remote_state *remote_state, refspec_appendf(&remote->push, "HEAD:refs/heads/%s", frag); remote->fetch_tags = 1; /* always auto-follow */ +out: strbuf_release(&buf); free(to_free); } +#endif /* WITH_BREAKING_CHANGES */ static int handle_config(const char *key, const char *value, const struct config_context *ctx, void *cb) @@ -404,7 +444,7 @@ static int handle_config(const char *key, const char *value, } else if (!strcmp(subkey, "merge")) { if (!value) return config_error_nonbool(key); - add_merge(branch, xstrdup(value)); + add_merge(branch, value); } return 0; } @@ -591,6 +631,7 @@ static void read_config(struct repository *repo, int early) alias_all_urls(repo->remote_state); } +#ifndef WITH_BREAKING_CHANGES static int valid_remote_nick(const char *name) { if (!name[0] || is_dot_or_dotdot(name)) @@ -602,6 +643,7 @@ static int valid_remote_nick(const char *name) return 0; return 1; } +#endif /* WITH_BREAKING_CHANGES */ static const char *remotes_remote_for_branch(struct remote_state *remote_state, struct branch *branch, @@ -654,7 +696,7 @@ const char *pushremote_for_branch(struct branch *branch, int *explicit) branch, explicit); } -static struct remote *remotes_remote_get(struct remote_state *remote_state, +static struct remote *remotes_remote_get(struct repository *repo, const char *name); char *remote_ref_for_branch(struct branch *branch, int for_push) @@ -665,7 +707,7 @@ char *remote_ref_for_branch(struct branch *branch, int for_push) if (branch) { if (!for_push) { if (branch->merge_nr) { - return xstrdup(branch->merge_name[0]); + return xstrdup(branch->merge[0]->src); } } else { char *dst; @@ -673,7 +715,7 @@ char *remote_ref_for_branch(struct branch *branch, int for_push) the_repository->remote_state, branch, NULL); struct remote *remote = remotes_remote_get( - the_repository->remote_state, remote_name); + the_repository, remote_name); if (remote && remote->push.nr && (dst = apply_refspecs(&remote->push, @@ -692,7 +734,7 @@ static void validate_remote_url(struct remote *remote) struct strbuf redacted = STRBUF_INIT; int warn_not_die; - if (git_config_get_string_tmp("transfer.credentialsinurl", &value)) + if (repo_config_get_string_tmp(the_repository, "transfer.credentialsinurl", &value)) return; if (!strcmp("warn", value)) @@ -730,10 +772,11 @@ loop_cleanup: } static struct remote * -remotes_remote_get_1(struct remote_state *remote_state, const char *name, +remotes_remote_get_1(struct repository *repo, const char *name, const char *(*get_default)(struct remote_state *, struct branch *, int *)) { + struct remote_state *remote_state = repo->remote_state; struct remote *ret; int name_given = 0; @@ -744,12 +787,14 @@ remotes_remote_get_1(struct remote_state *remote_state, const char *name, &name_given); ret = make_remote(remote_state, name, 0); +#ifndef WITH_BREAKING_CHANGES if (valid_remote_nick(name) && have_git_dir()) { if (!valid_remote(ret)) - read_remotes_file(remote_state, ret); + read_remotes_file(repo, ret); if (!valid_remote(ret)) - read_branches_file(remote_state, ret); + read_branches_file(repo, ret); } +#endif /* WITH_BREAKING_CHANGES */ if (name_given && !valid_remote(ret)) add_url_alias(remote_state, ret, name); if (!valid_remote(ret)) @@ -761,35 +806,33 @@ remotes_remote_get_1(struct remote_state *remote_state, const char *name, } static inline struct remote * -remotes_remote_get(struct remote_state *remote_state, const char *name) +remotes_remote_get(struct repository *repo, const char *name) { - return remotes_remote_get_1(remote_state, name, - remotes_remote_for_branch); + return remotes_remote_get_1(repo, name, remotes_remote_for_branch); } struct remote *remote_get(const char *name) { read_config(the_repository, 0); - return remotes_remote_get(the_repository->remote_state, name); + return remotes_remote_get(the_repository, name); } struct remote *remote_get_early(const char *name) { read_config(the_repository, 1); - return remotes_remote_get(the_repository->remote_state, name); + return remotes_remote_get(the_repository, name); } static inline struct remote * -remotes_pushremote_get(struct remote_state *remote_state, const char *name) +remotes_pushremote_get(struct repository *repo, const char *name) { - return remotes_remote_get_1(remote_state, name, - remotes_pushremote_for_branch); + return remotes_remote_get_1(repo, name, remotes_pushremote_for_branch); } struct remote *pushremote_get(const char *name) { read_config(the_repository, 0); - return remotes_pushremote_get(the_repository->remote_state, name); + return remotes_pushremote_get(the_repository, name); } int remote_is_configured(struct remote *remote, int in_repo) @@ -907,210 +950,9 @@ void ref_push_report_free(struct ref_push_report *report) } } -static int match_name_with_pattern(const char *key, const char *name, - const char *value, char **result) -{ - const char *kstar = strchr(key, '*'); - size_t klen; - size_t ksuffixlen; - size_t namelen; - int ret; - if (!kstar) - die(_("key '%s' of pattern had no '*'"), key); - klen = kstar - key; - ksuffixlen = strlen(kstar + 1); - namelen = strlen(name); - ret = !strncmp(name, key, klen) && namelen >= klen + ksuffixlen && - !memcmp(name + namelen - ksuffixlen, kstar + 1, ksuffixlen); - if (ret && value) { - struct strbuf sb = STRBUF_INIT; - const char *vstar = strchr(value, '*'); - if (!vstar) - die(_("value '%s' of pattern has no '*'"), value); - strbuf_add(&sb, value, vstar - value); - strbuf_add(&sb, name + klen, namelen - klen - ksuffixlen); - strbuf_addstr(&sb, vstar + 1); - *result = strbuf_detach(&sb, NULL); - } - return ret; -} - -static int refspec_match(const struct refspec_item *refspec, - const char *name) -{ - if (refspec->pattern) - return match_name_with_pattern(refspec->src, name, NULL, NULL); - - return !strcmp(refspec->src, name); -} - -int omit_name_by_refspec(const char *name, struct refspec *rs) -{ - int i; - - for (i = 0; i < rs->nr; i++) { - if (rs->items[i].negative && refspec_match(&rs->items[i], name)) - return 1; - } - return 0; -} - -struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs) -{ - struct ref **tail; - - for (tail = &ref_map; *tail; ) { - struct ref *ref = *tail; - - if (omit_name_by_refspec(ref->name, rs)) { - *tail = ref->next; - free(ref->peer_ref); - free(ref); - } else - tail = &ref->next; - } - - return ref_map; -} - -static int query_matches_negative_refspec(struct refspec *rs, struct refspec_item *query) -{ - int i, matched_negative = 0; - int find_src = !query->src; - struct string_list reversed = STRING_LIST_INIT_DUP; - const char *needle = find_src ? query->dst : query->src; - - /* - * Check whether the queried ref matches any negative refpsec. If so, - * then we should ultimately treat this as not matching the query at - * all. - * - * Note that negative refspecs always match the source, but the query - * item uses the destination. To handle this, we apply pattern - * refspecs in reverse to figure out if the query source matches any - * of the negative refspecs. - * - * The first loop finds and expands all positive refspecs - * matched by the queried ref. - * - * The second loop checks if any of the results of the first loop - * match any negative refspec. - */ - for (i = 0; i < rs->nr; i++) { - struct refspec_item *refspec = &rs->items[i]; - char *expn_name; - - if (refspec->negative) - continue; - - /* Note the reversal of src and dst */ - if (refspec->pattern) { - const char *key = refspec->dst ? refspec->dst : refspec->src; - const char *value = refspec->src; - - if (match_name_with_pattern(key, needle, value, &expn_name)) - string_list_append_nodup(&reversed, expn_name); - } else if (refspec->matching) { - /* For the special matching refspec, any query should match */ - string_list_append(&reversed, needle); - } else if (!refspec->src) { - BUG("refspec->src should not be null here"); - } else if (!strcmp(needle, refspec->src)) { - string_list_append(&reversed, refspec->src); - } - } - - for (i = 0; !matched_negative && i < reversed.nr; i++) { - if (omit_name_by_refspec(reversed.items[i].string, rs)) - matched_negative = 1; - } - - string_list_clear(&reversed, 0); - - return matched_negative; -} - -static void query_refspecs_multiple(struct refspec *rs, - struct refspec_item *query, - struct string_list *results) -{ - int i; - int find_src = !query->src; - - if (find_src && !query->dst) - BUG("query_refspecs_multiple: need either src or dst"); - - if (query_matches_negative_refspec(rs, query)) - return; - - for (i = 0; i < rs->nr; i++) { - struct refspec_item *refspec = &rs->items[i]; - const char *key = find_src ? refspec->dst : refspec->src; - const char *value = find_src ? refspec->src : refspec->dst; - const char *needle = find_src ? query->dst : query->src; - char **result = find_src ? &query->src : &query->dst; - - if (!refspec->dst || refspec->negative) - continue; - if (refspec->pattern) { - if (match_name_with_pattern(key, needle, value, result)) - string_list_append_nodup(results, *result); - } else if (!strcmp(needle, key)) { - string_list_append(results, value); - } - } -} - -int query_refspecs(struct refspec *rs, struct refspec_item *query) -{ - int i; - int find_src = !query->src; - const char *needle = find_src ? query->dst : query->src; - char **result = find_src ? &query->src : &query->dst; - - if (find_src && !query->dst) - BUG("query_refspecs: need either src or dst"); - - if (query_matches_negative_refspec(rs, query)) - return -1; - - for (i = 0; i < rs->nr; i++) { - struct refspec_item *refspec = &rs->items[i]; - const char *key = find_src ? refspec->dst : refspec->src; - const char *value = find_src ? refspec->src : refspec->dst; - - if (!refspec->dst || refspec->negative) - continue; - if (refspec->pattern) { - if (match_name_with_pattern(key, needle, value, result)) { - query->force = refspec->force; - return 0; - } - } else if (!strcmp(needle, key)) { - *result = xstrdup(value); - query->force = refspec->force; - return 0; - } - } - return -1; -} - -char *apply_refspecs(struct refspec *rs, const char *name) -{ - struct refspec_item query; - - memset(&query, 0, sizeof(struct refspec_item)); - query.src = (char *)name; - - if (query_refspecs(rs, &query)) - return NULL; - - return query.dst; -} - int remote_find_tracking(struct remote *remote, struct refspec_item *refspec) { - return query_refspecs(&remote->fetch, refspec); + return refspec_find_match(&remote->fetch, refspec); } static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen, @@ -1234,7 +1076,7 @@ int count_refspec_match(const char *pattern, } } -static void tail_link_ref(struct ref *ref, struct ref ***tail) +void tail_link_ref(struct ref *ref, struct ref ***tail) { **tail = ref; while (ref->next) @@ -1354,7 +1196,7 @@ static void show_push_unqualified_ref_name_error(const char *dst_value, BUG("'%s' is not a valid object, " "match_explicit_lhs() should catch this!", matched_src_name); - type = oid_object_info(the_repository, &oid, NULL); + type = odb_read_object_info(the_repository->objects, &oid, NULL); if (type == OBJ_COMMIT) { advise(_("The <src> part of the refspec is a commit object.\n" "Did you mean to create a new branch by pushing to\n" @@ -1497,9 +1339,9 @@ static char *get_ref_match(const struct refspec *rs, const struct ref *ref, const char *dst_side = item->dst ? item->dst : item->src; int match; if (direction == FROM_SRC) - match = match_name_with_pattern(item->src, ref->name, dst_side, &name); + match = match_refname_with_pattern(item->src, ref->name, dst_side, &name); else - match = match_name_with_pattern(dst_side, ref->name, item->src, &name); + match = match_refname_with_pattern(dst_side, ref->name, item->src, &name); if (match) { matching_refs = i; break; @@ -1535,7 +1377,7 @@ static struct ref **tail_ref(struct ref **head) struct tips { struct commit **tip; - int nr, alloc; + size_t nr, alloc; }; static void add_to_tips(struct tips *tips, const struct object_id *oid) @@ -1584,7 +1426,8 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds continue; /* not a tag */ if (string_list_has_string(&dst_tag, ref->name)) continue; /* they already have it */ - if (oid_object_info(the_repository, &ref->new_oid, NULL) != OBJ_TAG) + if (odb_read_object_info(the_repository->objects, + &ref->new_oid, NULL) != OBJ_TAG) continue; /* be conservative */ item = string_list_append(&src_tag, ref->name); item->util = ref; @@ -1602,7 +1445,7 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds const int reachable_flag = 1; struct commit_list *found_commits; struct commit **src_commits; - int nr_src_commits = 0, alloc_src_commits = 16; + size_t nr_src_commits = 0, alloc_src_commits = 16; ALLOC_ARRAY(src_commits, alloc_src_commits); for_each_string_list_item(item, &src_tag) { @@ -1874,7 +1717,7 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, if (!reject_reason && !ref->deletion && !is_null_oid(&ref->old_oid)) { if (starts_with(ref->name, "refs/tags/")) reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS; - else if (!repo_has_object_file_with_flags(the_repository, &ref->old_oid, OBJECT_INFO_SKIP_FETCH_OBJECT)) + else if (!odb_has_object(the_repository->objects, &ref->old_oid, HAS_OBJECT_RECHECK_PACKED)) reject_reason = REF_STATUS_REJECT_FETCH_FIRST; else if (!lookup_commit_reference_gently(the_repository, &ref->old_oid, 1) || !lookup_commit_reference_gently(the_repository, &ref->new_oid, 1)) @@ -1894,7 +1737,7 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, } } -static void set_merge(struct remote_state *remote_state, struct branch *ret) +static void set_merge(struct repository *repo, struct branch *ret) { struct remote *remote; char *ref; @@ -1903,52 +1746,80 @@ static void set_merge(struct remote_state *remote_state, struct branch *ret) if (!ret) return; /* no branch */ - if (ret->merge) + if (ret->set_merge) return; /* already run */ if (!ret->remote_name || !ret->merge_nr) { /* * no merge config; let's make sure we don't confuse callers * with a non-zero merge_nr but a NULL merge */ - ret->merge_nr = 0; + merge_clear(ret); return; } + ret->set_merge = 1; - remote = remotes_remote_get(remote_state, ret->remote_name); + remote = remotes_remote_get(repo, ret->remote_name); - CALLOC_ARRAY(ret->merge, ret->merge_nr); for (i = 0; i < ret->merge_nr; i++) { - ret->merge[i] = xcalloc(1, sizeof(**ret->merge)); - ret->merge[i]->src = xstrdup(ret->merge_name[i]); if (!remote_find_tracking(remote, ret->merge[i]) || strcmp(ret->remote_name, ".")) continue; - if (repo_dwim_ref(the_repository, ret->merge_name[i], - strlen(ret->merge_name[i]), &oid, &ref, + if (repo_dwim_ref(repo, ret->merge[i]->src, + strlen(ret->merge[i]->src), &oid, &ref, 0) == 1) ret->merge[i]->dst = ref; else - ret->merge[i]->dst = xstrdup(ret->merge_name[i]); + ret->merge[i]->dst = xstrdup(ret->merge[i]->src); } } -struct branch *branch_get(const char *name) +static struct branch *repo_branch_get(struct repository *repo, const char *name) { struct branch *ret; - read_config(the_repository, 0); + read_config(repo, 0); if (!name || !*name || !strcmp(name, "HEAD")) - ret = the_repository->remote_state->current_branch; + ret = repo->remote_state->current_branch; else - ret = make_branch(the_repository->remote_state, name, + ret = make_branch(repo->remote_state, name, strlen(name)); - set_merge(the_repository->remote_state, ret); + set_merge(repo, ret); return ret; } +struct branch *branch_get(const char *name) +{ + return repo_branch_get(the_repository, name); +} + +const char *repo_default_remote(struct repository *repo) +{ + struct branch *branch; + + read_config(repo, 0); + branch = repo_branch_get(repo, "HEAD"); + + return remotes_remote_for_branch(repo->remote_state, branch, NULL); +} + +const char *repo_remote_from_url(struct repository *repo, const char *url) +{ + read_config(repo, 0); + + for (int i = 0; i < repo->remote_state->remotes_nr; i++) { + struct remote *remote = repo->remote_state->remotes[i]; + if (!remote) + continue; + + if (remote_has_url(remote, url)) + return remote->name; + } + return NULL; +} + int branch_has_merge_config(struct branch *branch) { - return branch && !!branch->merge; + return branch && branch->set_merge; } int branch_merge_matches(struct branch *branch, @@ -2013,13 +1884,14 @@ static const char *tracking_for_push_dest(struct remote *remote, return ret; } -static const char *branch_get_push_1(struct remote_state *remote_state, +static const char *branch_get_push_1(struct repository *repo, struct branch *branch, struct strbuf *err) { + struct remote_state *remote_state = repo->remote_state; struct remote *remote; remote = remotes_remote_get( - remote_state, + repo, remotes_pushremote_for_branch(remote_state, branch, NULL)); if (!remote) return error_buf(err, @@ -2086,7 +1958,7 @@ const char *branch_get_push(struct branch *branch, struct strbuf *err) if (!branch->push_tracking_ref) branch->push_tracking_ref = branch_get_push_1( - the_repository->remote_state, branch, err); + the_repository, branch, err); return branch->push_tracking_ref; } @@ -2117,7 +1989,7 @@ static struct ref *get_expanded_map(const struct ref *remote_refs, if (strchr(ref->name, '^')) continue; /* a dereference item */ - if (match_name_with_pattern(refspec->src, ref->name, + if (match_refname_with_pattern(refspec->src, ref->name, refspec->dst, &expn_name) && !ignore_symref_update(expn_name, &scratch)) { struct ref *cpy = copy_ref(ref); @@ -2469,7 +2341,7 @@ struct ref *get_local_heads(void) struct ref *guess_remote_head(const struct ref *head, const struct ref *refs, - int all) + unsigned flags) { const struct ref *r; struct ref *list = NULL; @@ -2487,8 +2359,10 @@ struct ref *guess_remote_head(const struct ref *head, return copy_ref(find_ref_by_name(refs, head->symref)); /* If a remote branch exists with the default branch name, let's use it. */ - if (!all) { - char *default_branch = repo_default_branch_name(the_repository, 0); + if (!(flags & REMOTE_GUESS_HEAD_ALL)) { + char *default_branch = + repo_default_branch_name(the_repository, + flags & REMOTE_GUESS_HEAD_QUIET); char *ref = xstrfmt("refs/heads/%s", default_branch); r = find_ref_by_name(refs, ref); @@ -2511,7 +2385,7 @@ struct ref *guess_remote_head(const struct ref *head, oideq(&r->old_oid, &head->old_oid)) { *tail = copy_ref(r); tail = &((*tail)->next); - if (!all) + if (!(flags & REMOTE_GUESS_HEAD_ALL)) break; } } @@ -2535,7 +2409,7 @@ static int get_stale_heads_cb(const char *refname, const char *referent UNUSED, memset(&query, 0, sizeof(struct refspec_item)); query.dst = (char *)refname; - query_refspecs_multiple(info->rs, &query, &matches); + refspec_find_all_matches(info->rs, &query, &matches); if (matches.nr == 0) goto clean_exit; /* No matches */ @@ -3003,3 +2877,13 @@ char *relative_url(const char *remote_url, const char *url, free(out); return strbuf_detach(&sb, NULL); } + +int valid_remote_name(const char *name) +{ + int result; + struct strbuf refspec = STRBUF_INIT; + strbuf_addf(&refspec, "refs/heads/test:refs/remotes/%s/test", name); + result = valid_fetch_refspec(refspec.buf); + strbuf_release(&refspec); + return result; +} |
