for (weak_match = match = 0; refs; refs = refs->next) {
char *name = refs->name;
int namelen = strlen(name);
- int weak_match;
if (namelen < patlen ||
memcmp(name + namelen - patlen, pattern, patlen))
return ref;
}
+static struct ref *make_dst(const char *name, struct ref ***dst_tail)
+{
+ struct ref *dst;
+ size_t len;
+
+ len = strlen(name) + 1;
+ dst = xcalloc(1, sizeof(*dst) + len);
+ memcpy(dst->name, name, len);
+ link_dst_tail(dst, dst_tail);
+ return dst;
+}
+
static int match_explicit(struct ref *src, struct ref *dst,
struct ref ***dst_tail,
struct refspec *rs,
if (rs->pattern)
return errs;
- if (dst_value == NULL)
- dst_value = rs->src;
-
matched_src = matched_dst = NULL;
switch (count_refspec_match(rs->src, src, &matched_src)) {
case 1:
matched_src = try_explicit_object_name(rs->src);
if (matched_src)
break;
- errs = 1;
error("src refspec %s does not match any.",
rs->src);
break;
default:
- errs = 1;
+ matched_src = NULL;
error("src refspec %s matches more than one.",
rs->src);
break;
}
+
+ if (!matched_src)
+ errs = 1;
+
+ if (dst_value == NULL)
+ dst_value = matched_src->name;
+
switch (count_refspec_match(dst_value, dst, &matched_dst)) {
case 1:
break;
case 0:
- if (!memcmp(dst_value, "refs/", 5)) {
- int len = strlen(dst_value) + 1;
- matched_dst = xcalloc(1, sizeof(*dst) + len);
- memcpy(matched_dst->name, dst_value, len);
- link_dst_tail(matched_dst, dst_tail);
- }
- else if (!strcmp(rs->src, dst_value) &&
- matched_src) {
- /* pushing "master:master" when
- * remote does not have master yet.
- */
- int len = strlen(matched_src->name) + 1;
- matched_dst = xcalloc(1, sizeof(*dst) + len);
- memcpy(matched_dst->name, matched_src->name,
- len);
- link_dst_tail(matched_dst, dst_tail);
- }
- else {
- errs = 1;
+ if (!memcmp(dst_value, "refs/", 5))
+ matched_dst = make_dst(dst_value, dst_tail);
+ else
error("dst refspec %s does not match any "
"existing ref on the remote and does "
"not start with refs/.", dst_value);
- }
break;
default:
- errs = 1;
+ matched_dst = NULL;
error("dst refspec %s matches more than one.",
dst_value);
break;
}
- if (errs)
- return errs;
+ if (errs || matched_dst == NULL)
+ return 1;
if (matched_dst->peer_ref) {
errs = 1;
error("dst ref %s receives from more than one src.",
}
if (pat) {
- dst_name = xmalloc(strlen(pat->dst) +
+ const char *dst_side = pat->dst ? pat->dst : pat->src;
+ dst_name = xmalloc(strlen(dst_side) +
strlen(src->name) -
strlen(pat->src) + 2);
- strcpy(dst_name, pat->dst);
+ strcpy(dst_name, dst_side);
strcat(dst_name, src->name + strlen(pat->src));
} else
- dst_name = strdup(src->name);
+ dst_name = xstrdup(src->name);
dst_peer = find_ref_by_name(dst, dst_name);
if (dst_peer && dst_peer->peer_ref)
/* We're already sending something to this ref. */
goto free_name;
if (!dst_peer) {
/* Create a new one and link it */
- int len = strlen(dst_name) + 1;
- dst_peer = xcalloc(1, sizeof(*dst_peer) + len);
- memcpy(dst_peer->name, dst_name, len);
+ dst_peer = make_dst(dst_name, dst_tail);
hashcpy(dst_peer->new_sha1, src->new_sha1);
- link_dst_tail(dst_peer, dst_tail);
}
dst_peer->peer_ref = src;
free_name: