remote->push_refspec_nr = nr;
}
+static void add_fetch_refspec(struct remote *remote, const char *ref)
+{
+ int nr = remote->fetch_refspec_nr + 1;
+ remote->fetch_refspec =
+ xrealloc(remote->fetch_refspec, nr * sizeof(char *));
+ remote->fetch_refspec[nr-1] = ref;
+ remote->fetch_refspec_nr = nr;
+}
+
static void add_uri(struct remote *remote, const char *uri)
{
int nr = remote->uri_nr + 1;
} else if (!prefixcmp(buffer, "Push:")) {
value_list = 1;
s = buffer + 5;
+ } else if (!prefixcmp(buffer, "Pull:")) {
+ value_list = 2;
+ s = buffer + 5;
} else
continue;
case 1:
add_push_refspec(remote, xstrdup(s));
break;
+ case 2:
+ add_fetch_refspec(remote, xstrdup(s));
+ break;
}
}
fclose(f);
add_uri(remote, xstrdup(value));
} else if (!strcmp(subkey, ".push")) {
add_push_refspec(remote, xstrdup(value));
+ } else if (!strcmp(subkey, ".fetch")) {
+ add_fetch_refspec(remote, xstrdup(value));
} else if (!strcmp(subkey, ".receivepack")) {
if (!remote->receivepack)
remote->receivepack = xstrdup(value);
add_uri(ret, name);
if (!ret->uri)
return NULL;
+ ret->fetch = parse_ref_spec(ret->fetch_refspec_nr, ret->fetch_refspec);
ret->push = parse_ref_spec(ret->push_refspec_nr, ret->push_refspec);
return ret;
}
+int remote_has_uri(struct remote *remote, const char *uri)
+{
+ int i;
+ for (i = 0; i < remote->uri_nr; i++) {
+ if (!strcmp(remote->uri[i], uri))
+ return 1;
+ }
+ return 0;
+}
+
+int remote_find_tracking(struct remote *remote, struct refspec *refspec)
+{
+ int i;
+ for (i = 0; i < remote->fetch_refspec_nr; i++) {
+ struct refspec *fetch = &remote->fetch[i];
+ if (!fetch->dst)
+ continue;
+ if (fetch->pattern) {
+ if (!prefixcmp(refspec->src, fetch->src)) {
+ refspec->dst =
+ xmalloc(strlen(fetch->dst) +
+ strlen(refspec->src) -
+ strlen(fetch->src) + 1);
+ strcpy(refspec->dst, fetch->dst);
+ strcpy(refspec->dst + strlen(fetch->dst),
+ refspec->src + strlen(fetch->src));
+ refspec->force = fetch->force;
+ return 0;
+ }
+ } else {
+ if (!strcmp(refspec->src, fetch->src)) {
+ refspec->dst = xstrdup(fetch->dst);
+ refspec->force = fetch->force;
+ return 0;
+ }
+ }
+ }
+ refspec->dst = NULL;
+ return -1;
+}
+
static int count_refspec_match(const char *pattern,
struct ref *refs,
struct ref **matched_ref)
struct ref *matched_src, *matched_dst;
const char *dst_value = rs[i].dst;
+
+ if (rs[i].pattern)
+ continue;
+
if (dst_value == NULL)
dst_value = rs[i].src;
return NULL;
}
+static int check_pattern_match(struct refspec *rs, int rs_nr, struct ref *src)
+{
+ int i;
+ if (!rs_nr)
+ return 1;
+ for (i = 0; i < rs_nr; i++) {
+ if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
+ return 1;
+ }
+ return 0;
+}
+
int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
int nr_refspec, char **refspec, int all)
{
struct refspec *rs =
parse_ref_spec(nr_refspec, (const char **) refspec);
- if (nr_refspec)
- return match_explicit_refs(src, dst, dst_tail, rs, nr_refspec);
+ if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
+ return -1;
/* pick the remainder */
for ( ; src; src = src->next) {
struct ref *dst_peer;
if (src->peer_ref)
continue;
+ if (!check_pattern_match(rs, nr_refspec, src))
+ continue;
+
dst_peer = find_ref_by_name(dst, src->name);
- if ((dst_peer && dst_peer->peer_ref) || (!dst_peer && !all))
+ if (dst_peer && dst_peer->peer_ref)
+ /* We're already sending something to this ref. */
+ continue;
+ if (!dst_peer && !nr_refspec && !all)
+ /* Remote doesn't have it, and we have no
+ * explicit pattern, and we don't have
+ * --all. */
continue;
if (!dst_peer) {
/* Create a new one and link it */