if (!r->rewrite[i])
continue;
for (j = 0; j < r->rewrite[i]->instead_of_nr; j++) {
- if (!prefixcmp(url, r->rewrite[i]->instead_of[j].s) &&
+ if (starts_with(url, r->rewrite[i]->instead_of[j].s) &&
(!longest ||
longest->len < r->rewrite[i]->instead_of[j].len)) {
longest = &(r->rewrite[i]->instead_of[j]);
int value_list;
char *s, *p;
- if (!prefixcmp(buffer, "URL:")) {
+ if (starts_with(buffer, "URL:")) {
value_list = 0;
s = buffer + 4;
- } else if (!prefixcmp(buffer, "Push:")) {
+ } else if (starts_with(buffer, "Push:")) {
value_list = 1;
s = buffer + 5;
- } else if (!prefixcmp(buffer, "Pull:")) {
+ } else if (starts_with(buffer, "Pull:")) {
value_list = 2;
s = buffer + 5;
} else
const char *subkey;
struct remote *remote;
struct branch *branch;
- if (!prefixcmp(key, "branch.")) {
+ if (starts_with(key, "branch.")) {
name = key + 7;
subkey = strrchr(name, '.');
if (!subkey)
}
return 0;
}
- if (!prefixcmp(key, "url.")) {
+ if (starts_with(key, "url.")) {
struct rewrite *rewrite;
name = key + 4;
subkey = strrchr(name, '.');
}
}
- if (prefixcmp(key, "remote."))
+ if (!starts_with(key, "remote."))
return 0;
name = key + 7;
int flag;
if (default_remote_name) /* did this already */
return;
- default_remote_name = xstrdup("origin");
+ default_remote_name = "origin";
current_branch = NULL;
head_ref = resolve_ref_unsafe("HEAD", sha1, 0, &flag);
if (head_ref && (flag & REF_ISSYMREF) &&
- !prefixcmp(head_ref, "refs/heads/")) {
+ starts_with(head_ref, "refs/heads/")) {
current_branch =
make_branch(head_ref + strlen("refs/heads/"), 0);
}
static void handle_duplicate(struct ref *ref1, struct ref *ref2)
{
- if (strcmp(ref1->name, ref2->name))
- die(_("%s tracks both %s and %s"),
- ref2->peer_ref->name, ref1->name, ref2->name);
+ if (strcmp(ref1->name, ref2->name)) {
+ if (ref1->fetch_head_status != FETCH_HEAD_IGNORE &&
+ ref2->fetch_head_status != FETCH_HEAD_IGNORE) {
+ die(_("Cannot fetch both %s and %s to %s"),
+ ref1->name, ref2->name, ref2->peer_ref->name);
+ } else if (ref1->fetch_head_status != FETCH_HEAD_IGNORE &&
+ ref2->fetch_head_status == FETCH_HEAD_IGNORE) {
+ warning(_("%s usually tracks %s, not %s"),
+ ref2->peer_ref->name, ref2->name, ref1->name);
+ } else if (ref1->fetch_head_status == FETCH_HEAD_IGNORE &&
+ ref2->fetch_head_status == FETCH_HEAD_IGNORE) {
+ die(_("%s tracks both %s and %s"),
+ ref2->peer_ref->name, ref1->name, ref2->name);
+ } else {
+ /*
+ * This last possibility doesn't occur because
+ * FETCH_HEAD_IGNORE entries always appear at
+ * the end of the list.
+ */
+ die(_("Internal error"));
+ }
+ }
free(ref2->peer_ref);
free(ref2);
}
return ret;
}
-static int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
+int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
{
int i;
int find_src = !query->src;
*l = llist_mergesort(*l, ref_list_get_next, ref_list_set_next, cmp);
}
-static int count_refspec_match(const char *pattern,
- struct ref *refs,
- struct ref **matched_ref)
+int count_refspec_match(const char *pattern,
+ struct ref *refs,
+ struct ref **matched_ref)
{
int patlen = strlen(pattern);
struct ref *matched_weak = NULL;
char *name = refs->name;
int namelen = strlen(name);
- if (!refname_match(pattern, name, ref_rev_parse_rules))
+ if (!refname_match(pattern, name))
continue;
/* A match is "weak" if it is with refs outside
*/
if (namelen != patlen &&
patlen != namelen - 5 &&
- prefixcmp(name, "refs/heads/") &&
- prefixcmp(name, "refs/tags/")) {
+ !starts_with(name, "refs/heads/") &&
+ !starts_with(name, "refs/tags/")) {
/* We want to catch the case where only weak
* matches are found and there are multiple
* matches, and where more than one strong
if (!r)
return NULL;
- if (!prefixcmp(r, "refs/heads/"))
+ if (starts_with(r, "refs/heads/"))
strbuf_addstr(&buf, "refs/heads/");
- else if (!prefixcmp(r, "refs/tags/"))
+ else if (starts_with(r, "refs/tags/"))
strbuf_addstr(&buf, "refs/tags/");
else
return NULL;
return strbuf_detach(&buf, NULL);
}
+static int match_explicit_lhs(struct ref *src,
+ struct refspec *rs,
+ struct ref **match,
+ int *allocated_match)
+{
+ switch (count_refspec_match(rs->src, src, match)) {
+ case 1:
+ *allocated_match = 0;
+ return 0;
+ case 0:
+ /* The source could be in the get_sha1() format
+ * not a reference name. :refs/other is a
+ * way to delete 'other' ref at the remote end.
+ */
+ *match = try_explicit_object_name(rs->src);
+ if (!*match)
+ return error("src refspec %s does not match any.", rs->src);
+ *allocated_match = 1;
+ return 0;
+ default:
+ return error("src refspec %s matches more than one.", rs->src);
+ }
+}
+
static int match_explicit(struct ref *src, struct ref *dst,
struct ref ***dst_tail,
struct refspec *rs)
{
struct ref *matched_src, *matched_dst;
- int copy_src;
+ int allocated_src;
const char *dst_value = rs->dst;
char *dst_guess;
return 0;
matched_src = matched_dst = NULL;
- switch (count_refspec_match(rs->src, src, &matched_src)) {
- case 1:
- copy_src = 1;
- break;
- case 0:
- /* The source could be in the get_sha1() format
- * not a reference name. :refs/other is a
- * way to delete 'other' ref at the remote end.
- */
- matched_src = try_explicit_object_name(rs->src);
- if (!matched_src)
- return error("src refspec %s does not match any.", rs->src);
- copy_src = 0;
- break;
- default:
- return error("src refspec %s matches more than one.", rs->src);
- }
+ if (match_explicit_lhs(src, rs, &matched_src, &allocated_src) < 0)
+ return -1;
if (!dst_value) {
unsigned char sha1[20];
dst_value = resolve_ref_unsafe(matched_src->name, sha1, 1, &flag);
if (!dst_value ||
((flag & REF_ISSYMREF) &&
- prefixcmp(dst_value, "refs/heads/")))
+ !starts_with(dst_value, "refs/heads/")))
die("%s cannot be resolved to branch.",
matched_src->name);
}
return error("dst ref %s receives from more than one src.",
matched_dst->name);
else {
- matched_dst->peer_ref = copy_src ? copy_ref(matched_src) : matched_src;
+ matched_dst->peer_ref = allocated_src ?
+ matched_src :
+ copy_ref(matched_src);
matched_dst->force = rs->force;
}
return 0;
* including refs outside refs/heads/ hierarchy, but
* that does not make much sense these days.
*/
- if (!send_mirror && prefixcmp(ref->name, "refs/heads/"))
+ if (!send_mirror && !starts_with(ref->name, "refs/heads/"))
return NULL;
name = xstrdup(ref->name);
}
add_to_tips(&sent_tips, ref->peer_ref->new_sha1);
else
add_to_tips(&sent_tips, ref->old_sha1);
- if (!prefixcmp(ref->name, "refs/tags/"))
+ if (starts_with(ref->name, "refs/tags/"))
string_list_append(&dst_tag, ref->name);
}
clear_commit_marks_many(sent_tips.nr, sent_tips.tip, TMP_MARK);
/* Collect tags they do not have. */
for (ref = src; ref; ref = ref->next) {
- if (prefixcmp(ref->name, "refs/tags/"))
+ if (!starts_with(ref->name, "refs/tags/"))
continue; /* not a tag */
if (string_list_has_string(&dst_tag, ref->name))
continue; /* they already have it */
*/
else if (!ref->deletion && !is_null_sha1(ref->old_sha1)) {
- if (!prefixcmp(ref->name, "refs/tags/"))
+ if (starts_with(ref->name, "refs/tags/"))
reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS;
else if (!has_sha1_file(ref->old_sha1))
reject_reason = REF_STATUS_REJECT_FETCH_FIRST;
{
if (!branch || i < 0 || i >= branch->merge_nr)
return 0;
- return refname_match(branch->merge[i]->src, refname, ref_fetch_rules);
+ return refname_match(branch->merge[i]->src, refname);
}
static int ignore_symref_update(const char *refname)
{
const struct ref *ref;
for (ref = refs; ref; ref = ref->next) {
- if (refname_match(name, ref->name, ref_fetch_rules))
+ if (refname_match(name, ref->name))
return ref;
}
return NULL;
if (!name || name[0] == '\0')
return NULL;
- if (!prefixcmp(name, "refs/"))
+ if (starts_with(name, "refs/"))
return alloc_ref(name);
- if (!prefixcmp(name, "heads/") ||
- !prefixcmp(name, "tags/") ||
- !prefixcmp(name, "remotes/"))
+ if (starts_with(name, "heads/") ||
+ starts_with(name, "tags/") ||
+ starts_with(name, "remotes/"))
return alloc_ref_with_prefix("refs/", 5, name);
return alloc_ref_with_prefix("refs/heads/", 11, name);
for (rmp = &ref_map; *rmp; ) {
if ((*rmp)->peer_ref) {
- if (prefixcmp((*rmp)->peer_ref->name, "refs/") ||
+ if (!starts_with((*rmp)->peer_ref->name, "refs/") ||
check_refname_format((*rmp)->peer_ref->name, 0)) {
struct ref *ignore = *rmp;
error("* Ignoring funny ref '%s' locally",
/* Look for another ref that points there */
for (r = refs; r; r = r->next) {
if (r != head &&
- !prefixcmp(r->name, "refs/heads/") &&
+ starts_with(r->name, "refs/heads/") &&
!hashcmp(r->old_sha1, head->old_sha1)) {
*tail = copy_ref(r);
tail = &((*tail)->next);
/* Find an explicit --<option>=<name>[:<value>] entry */
for (i = 0; i < cas->nr; i++) {
struct push_cas *entry = &cas->entry[i];
- if (!refname_match(entry->refname, ref->name, ref_rev_parse_rules))
+ if (!refname_match(entry->refname, ref->name))
continue;
ref->expect_old_sha1 = 1;
if (!entry->use_tracking)