summaryrefslogtreecommitdiff
path: root/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'remote.c')
-rw-r--r--remote.c436
1 files changed, 160 insertions, 276 deletions
diff --git a/remote.c b/remote.c
index 18e5ccf391..88f991795b 100644
--- a/remote.c
+++ b/remote.c
@@ -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;
+}