fetch: convert prune_refs to take a struct refspec
[gitweb.git] / remote.c
index 1918551182fd40dfcea05ae4aec75805bf369b81..4a9bddf0d7af66f2e1705bf459432ae69fd6735f 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -77,33 +77,6 @@ static const char *alias_url(const char *url, struct rewrites *r)
        return xstrfmt("%s%s", r->rewrite[longest_i]->base, url + longest->len);
 }
 
-static void add_push_refspec(struct remote *remote, const char *ref)
-{
-       ALLOC_GROW(remote->push_refspec,
-                  remote->push_refspec_nr + 1,
-                  remote->push_refspec_alloc);
-       remote->push_refspec[remote->push_refspec_nr++] = ref;
-}
-
-static void add_fetch_refspec(struct remote *remote, const char *ref)
-{
-       ALLOC_GROW(remote->fetch_refspec,
-                  remote->fetch_refspec_nr + 1,
-                  remote->fetch_refspec_alloc);
-       remote->fetch_refspec[remote->fetch_refspec_nr++] = ref;
-}
-
-void add_prune_tags_to_fetch_refspec(struct remote *remote)
-{
-       int nr = remote->fetch_refspec_nr;
-       int bufsize = nr  + 1;
-       int size = sizeof(struct refspec_item);
-
-       remote->fetch = xrealloc(remote->fetch, size  * bufsize);
-       memcpy(&remote->fetch[nr], tag_refspec, size);
-       add_fetch_refspec(remote, xstrdup(TAG_REFSPEC));
-}
-
 static void add_url(struct remote *remote, const char *url)
 {
        ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc);
@@ -175,9 +148,12 @@ static struct remote *make_remote(const char *name, int len)
        ret = xcalloc(1, sizeof(struct remote));
        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);
+
        ALLOC_GROW(remotes, remotes_nr + 1, remotes_alloc);
        remotes[remotes_nr++] = ret;
-       ret->name = xstrndup(name, len);
 
        hashmap_entry_init(ret, lookup_entry.hash);
        replaced = hashmap_put(&remotes_hash, ret);
@@ -275,9 +251,9 @@ static void read_remotes_file(struct remote *remote)
                if (skip_prefix(buf.buf, "URL:", &v))
                        add_url_alias(remote, xstrdup(skip_spaces(v)));
                else if (skip_prefix(buf.buf, "Push:", &v))
-                       add_push_refspec(remote, xstrdup(skip_spaces(v)));
+                       refspec_append(&remote->push, skip_spaces(v));
                else if (skip_prefix(buf.buf, "Pull:", &v))
-                       add_fetch_refspec(remote, xstrdup(skip_spaces(v)));
+                       refspec_append(&remote->fetch, skip_spaces(v));
        }
        strbuf_release(&buf);
        fclose(f);
@@ -316,15 +292,19 @@ static void read_branches_file(struct remote *remote)
                frag = "master";
 
        add_url_alias(remote, strbuf_detach(&buf, NULL));
-       add_fetch_refspec(remote, xstrfmt("refs/heads/%s:refs/heads/%s",
-                                         frag, remote->name));
+       strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
+                   frag, remote->name);
+       refspec_append(&remote->fetch, buf.buf);
 
        /*
         * Cogito compatible push: push current HEAD to remote #branch
         * (master if missing)
         */
-       add_push_refspec(remote, xstrfmt("HEAD:refs/heads/%s", frag));
+       strbuf_reset(&buf);
+       strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
+       refspec_append(&remote->push, buf.buf);
        remote->fetch_tags = 1; /* always auto-follow */
+       strbuf_release(&buf);
 }
 
 static int handle_config(const char *key, const char *value, void *cb)
@@ -409,12 +389,14 @@ static int handle_config(const char *key, const char *value, void *cb)
                const char *v;
                if (git_config_string(&v, key, value))
                        return -1;
-               add_push_refspec(remote, v);
+               refspec_append(&remote->push, v);
+               free((char *)v);
        } else if (!strcmp(subkey, "fetch")) {
                const char *v;
                if (git_config_string(&v, key, value))
                        return -1;
-               add_fetch_refspec(remote, v);
+               refspec_append(&remote->fetch, v);
+               free((char *)v);
        } else if (!strcmp(subkey, "receivepack")) {
                const char *v;
                if (git_config_string(&v, key, value))
@@ -542,9 +524,9 @@ const char *remote_ref_for_branch(struct branch *branch, int for_push,
                                pushremote_for_branch(branch, NULL);
                        struct remote *remote = remote_get(remote_name);
 
-                       if (remote && remote->push_refspec_nr &&
-                           (dst = apply_refspecs(remote->push,
-                                                 remote->push_refspec_nr,
+                       if (remote && remote->push.nr &&
+                           (dst = apply_refspecs(remote->push.items,
+                                                 remote->push.nr,
                                                  branch->refname))) {
                                if (explicit)
                                        *explicit = 1;
@@ -581,8 +563,6 @@ static struct remote *remote_get_1(const char *name,
                add_url_alias(ret, name);
        if (!valid_remote(ret))
                return NULL;
-       ret->fetch = parse_fetch_refspec(ret->fetch_refspec_nr, ret->fetch_refspec);
-       ret->push = parse_push_refspec(ret->push_refspec_nr, ret->push_refspec);
        return ret;
 }
 
@@ -613,12 +593,6 @@ int for_each_remote(each_remote_fn fn, void *priv)
                struct remote *r = remotes[i];
                if (!r)
                        continue;
-               if (!r->fetch)
-                       r->fetch = parse_fetch_refspec(r->fetch_refspec_nr,
-                                                      r->fetch_refspec);
-               if (!r->push)
-                       r->push = parse_push_refspec(r->push_refspec_nr,
-                                                    r->push_refspec);
                result = fn(r, priv);
        }
        return result;
@@ -797,7 +771,7 @@ char *apply_refspecs(struct refspec_item *refspecs, int nr_refspec,
 
 int remote_find_tracking(struct remote *remote, struct refspec_item *refspec)
 {
-       return query_refspecs(remote->fetch, remote->fetch_refspec_nr, refspec);
+       return query_refspecs(remote->fetch.items, remote->fetch.nr, refspec);
 }
 
 static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen,
@@ -1312,7 +1286,7 @@ int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
 int match_push_refs(struct ref *src, struct ref **dst,
                    int nr_refspec, const char **refspec, int flags)
 {
-       struct refspec_item *rs;
+       struct refspec rs = REFSPEC_INIT_PUSH;
        int send_all = flags & MATCH_REFS_ALL;
        int send_mirror = flags & MATCH_REFS_MIRROR;
        int send_prune = flags & MATCH_REFS_PRUNE;
@@ -1325,8 +1299,8 @@ int match_push_refs(struct ref *src, struct ref **dst,
                nr_refspec = 1;
                refspec = default_refspec;
        }
-       rs = parse_push_refspec(nr_refspec, (const char **) refspec);
-       errs = match_explicit_refs(src, *dst, &dst_tail, rs, nr_refspec);
+       refspec_appendn(&rs, refspec, nr_refspec);
+       errs = match_explicit_refs(src, *dst, &dst_tail, rs.items, rs.nr);
 
        /* pick the remainder */
        for (ref = src; ref; ref = ref->next) {
@@ -1335,7 +1309,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
                const struct refspec_item *pat = NULL;
                char *dst_name;
 
-               dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_SRC, &pat);
+               dst_name = get_ref_match(rs.items, rs.nr, ref, send_mirror, FROM_SRC, &pat);
                if (!dst_name)
                        continue;
 
@@ -1384,7 +1358,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
                                /* We're already sending something to this ref. */
                                continue;
 
-                       src_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_DST, NULL);
+                       src_name = get_ref_match(rs.items, rs.nr, ref, send_mirror, FROM_DST, NULL);
                        if (src_name) {
                                if (!src_ref_index.nr)
                                        prepare_ref_index(&src_ref_index, src);
@@ -1396,6 +1370,9 @@ int match_push_refs(struct ref *src, struct ref **dst,
                }
                string_list_clear(&src_ref_index, 0);
        }
+
+       refspec_clear(&rs);
+
        if (errs)
                return -1;
        return 0;
@@ -1592,7 +1569,7 @@ static const char *tracking_for_push_dest(struct remote *remote,
 {
        char *ret;
 
-       ret = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
+       ret = apply_refspecs(remote->fetch.items, remote->fetch.nr, refname);
        if (!ret)
                return error_buf(err,
                                 _("push destination '%s' on remote '%s' has no local tracking branch"),
@@ -1610,11 +1587,11 @@ static const char *branch_get_push_1(struct branch *branch, struct strbuf *err)
                                 _("branch '%s' has no remote for pushing"),
                                 branch->name);
 
-       if (remote->push_refspec_nr) {
+       if (remote->push.nr) {
                char *dst;
                const char *ret;
 
-               dst = apply_refspecs(remote->push, remote->push_refspec_nr,
+               dst = apply_refspecs(remote->push.items, remote->push.nr,
                                     branch->refname);
                if (!dst)
                        return error_buf(err,
@@ -2226,7 +2203,7 @@ static int remote_tracking(struct remote *remote, const char *refname,
 {
        char *dst;
 
-       dst = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
+       dst = apply_refspecs(remote->fetch.items, remote->fetch.nr, refname);
        if (!dst)
                return -1; /* no tracking ref for refname at remote */
        if (read_ref(dst, oid))