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);
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);
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);
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)
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))
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;
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;
}
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;
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,
*/
int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
{
- struct refspec_item *refspec = parse_push_refspec(nr_refspec, refspec_names);
+ struct refspec refspec = REFSPEC_INIT_PUSH;
int ret = 0;
int i;
- for (i = 0; i < nr_refspec; i++) {
- struct refspec_item *rs = refspec + i;
+ refspec_appendn(&refspec, refspec_names, nr_refspec);
+
+ for (i = 0; i < refspec.nr; i++) {
+ struct refspec_item *rs = &refspec.items[i];
if (rs->pattern || rs->matching)
continue;
ret |= match_explicit_lhs(src, rs, NULL, NULL);
}
- free_refspec(nr_refspec, refspec);
+ refspec_clear(&refspec);
return ret;
}
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;
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) {
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;
/* 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);
}
string_list_clear(&src_ref_index, 0);
}
+
+ refspec_clear(&rs);
+
if (errs)
return -1;
return 0;
{
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"),
_("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,
{
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))