#include "config.h"
#include "remote.h"
#include "refs.h"
+#include "refspec.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
enum map_direction { FROM_SRC, FROM_DST };
-static struct refspec s_tag_refspec = {
- 0,
- 1,
- 0,
- 0,
- "refs/tags/*",
- "refs/tags/*"
-};
-
-/* See TAG_REFSPEC for the string version */
-const struct refspec *tag_refspec = &s_tag_refspec;
-
struct counted_string {
size_t len;
const char *s;
{
int nr = remote->fetch_refspec_nr;
int bufsize = nr + 1;
- int size = sizeof(struct refspec);
+ int size = sizeof(struct refspec_item);
remote->fetch = xrealloc(remote->fetch, size * bufsize);
memcpy(&remote->fetch[nr], tag_refspec, size);
alias_all_urls();
}
-static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
-{
- int i;
- struct refspec *rs = xcalloc(nr_refspec, sizeof(*rs));
-
- for (i = 0; i < nr_refspec; i++) {
- size_t llen;
- int is_glob;
- const char *lhs, *rhs;
- int flags;
-
- is_glob = 0;
-
- lhs = refspec[i];
- if (*lhs == '+') {
- rs[i].force = 1;
- lhs++;
- }
-
- rhs = strrchr(lhs, ':');
-
- /*
- * Before going on, special case ":" (or "+:") as a refspec
- * for pushing matching refs.
- */
- if (!fetch && rhs == lhs && rhs[1] == '\0') {
- rs[i].matching = 1;
- continue;
- }
-
- if (rhs) {
- size_t rlen = strlen(++rhs);
- is_glob = (1 <= rlen && strchr(rhs, '*'));
- rs[i].dst = xstrndup(rhs, rlen);
- }
-
- llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
- if (1 <= llen && memchr(lhs, '*', llen)) {
- if ((rhs && !is_glob) || (!rhs && fetch))
- goto invalid;
- is_glob = 1;
- } else if (rhs && is_glob) {
- goto invalid;
- }
-
- rs[i].pattern = is_glob;
- rs[i].src = xstrndup(lhs, llen);
- flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
-
- if (fetch) {
- struct object_id unused;
-
- /* LHS */
- if (!*rs[i].src)
- ; /* empty is ok; it means "HEAD" */
- else if (llen == GIT_SHA1_HEXSZ && !get_oid_hex(rs[i].src, &unused))
- rs[i].exact_sha1 = 1; /* ok */
- else if (!check_refname_format(rs[i].src, flags))
- ; /* valid looking ref is ok */
- else
- goto invalid;
- /* RHS */
- if (!rs[i].dst)
- ; /* missing is ok; it is the same as empty */
- else if (!*rs[i].dst)
- ; /* empty is ok; it means "do not store" */
- else if (!check_refname_format(rs[i].dst, flags))
- ; /* valid looking ref is ok */
- else
- goto invalid;
- } else {
- /*
- * LHS
- * - empty is allowed; it means delete.
- * - when wildcarded, it must be a valid looking ref.
- * - otherwise, it must be an extended SHA-1, but
- * there is no existing way to validate this.
- */
- if (!*rs[i].src)
- ; /* empty is ok */
- else if (is_glob) {
- if (check_refname_format(rs[i].src, flags))
- goto invalid;
- }
- else
- ; /* anything goes, for now */
- /*
- * RHS
- * - missing is allowed, but LHS then must be a
- * valid looking ref.
- * - empty is not allowed.
- * - otherwise it must be a valid looking ref.
- */
- if (!rs[i].dst) {
- if (check_refname_format(rs[i].src, flags))
- goto invalid;
- } else if (!*rs[i].dst) {
- goto invalid;
- } else {
- if (check_refname_format(rs[i].dst, flags))
- goto invalid;
- }
- }
- }
- return rs;
-
- invalid:
- if (verify) {
- /*
- * nr_refspec must be greater than zero and i must be valid
- * since it is only possible to reach this point from within
- * the for loop above.
- */
- free_refspec(i+1, rs);
- return NULL;
- }
- die("Invalid refspec '%s'", refspec[i]);
-}
-
-int valid_fetch_refspec(const char *fetch_refspec_str)
-{
- struct refspec *refspec;
-
- refspec = parse_refspec_internal(1, &fetch_refspec_str, 1, 1);
- free_refspec(1, refspec);
- return !!refspec;
-}
-
-struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec)
-{
- return parse_refspec_internal(nr_refspec, refspec, 1, 0);
-}
-
-struct refspec *parse_push_refspec(int nr_refspec, const char **refspec)
-{
- return parse_refspec_internal(nr_refspec, refspec, 0, 0);
-}
-
-void free_refspec(int nr_refspec, struct refspec *refspec)
-{
- int i;
-
- if (!refspec)
- return;
-
- for (i = 0; i < nr_refspec; i++) {
- free(refspec[i].src);
- free(refspec[i].dst);
- }
- free(refspec);
-}
-
static int valid_remote_nick(const char *name)
{
if (!name[0] || is_dot_or_dotdot(name))
return ret;
}
-static void query_refspecs_multiple(struct refspec *refs, int ref_count, struct refspec *query, struct string_list *results)
+static void query_refspecs_multiple(struct refspec_item *refs, int ref_count, struct refspec_item *query, struct string_list *results)
{
int i;
int find_src = !query->src;
error("query_refspecs_multiple: need either src or dst");
for (i = 0; i < ref_count; i++) {
- struct refspec *refspec = &refs[i];
+ struct refspec_item *refspec = &refs[i];
const char *key = find_src ? refspec->dst : refspec->src;
const char *value = find_src ? refspec->src : refspec->dst;
const char *needle = find_src ? query->dst : query->src;
}
}
-int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
+int query_refspecs(struct refspec_item *refs, int ref_count, struct refspec_item *query)
{
int i;
int find_src = !query->src;
return error("query_refspecs: need either src or dst");
for (i = 0; i < ref_count; i++) {
- struct refspec *refspec = &refs[i];
+ struct refspec_item *refspec = &refs[i];
const char *key = find_src ? refspec->dst : refspec->src;
const char *value = find_src ? refspec->src : refspec->dst;
return -1;
}
-char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
+char *apply_refspecs(struct refspec_item *refspecs, int nr_refspec,
const char *name)
{
- struct refspec query;
+ struct refspec_item query;
- memset(&query, 0, sizeof(struct refspec));
+ memset(&query, 0, sizeof(struct refspec_item));
query.src = (char *)name;
if (query_refspecs(refspecs, nr_refspec, &query))
return query.dst;
}
-int remote_find_tracking(struct remote *remote, struct refspec *refspec)
+int remote_find_tracking(struct remote *remote, struct refspec_item *refspec)
{
return query_refspecs(remote->fetch, remote->fetch_refspec_nr, refspec);
}
}
static int match_explicit_lhs(struct ref *src,
- struct refspec *rs,
+ struct refspec_item *rs,
struct ref **match,
int *allocated_match)
{
static int match_explicit(struct ref *src, struct ref *dst,
struct ref ***dst_tail,
- struct refspec *rs)
+ struct refspec_item *rs)
{
struct ref *matched_src, *matched_dst;
int allocated_src;
}
static int match_explicit_refs(struct ref *src, struct ref *dst,
- struct ref ***dst_tail, struct refspec *rs,
+ struct ref ***dst_tail, struct refspec_item *rs,
int rs_nr)
{
int i, errs;
return errs;
}
-static char *get_ref_match(const struct refspec *rs, int rs_nr, const struct ref *ref,
- int send_mirror, int direction, const struct refspec **ret_pat)
+static char *get_ref_match(const struct refspec_item *rs, int rs_nr, const struct ref *ref,
+ int send_mirror, int direction, const struct refspec_item **ret_pat)
{
- const struct refspec *pat;
+ const struct refspec_item *pat;
char *name;
int i;
int matching_refs = -1;
continue; /* not a tag */
if (string_list_has_string(&dst_tag, ref->name))
continue; /* they already have it */
- if (sha1_object_info(ref->new_oid.hash, NULL) != OBJ_TAG)
+ if (oid_object_info(&ref->new_oid, NULL) != OBJ_TAG)
continue; /* be conservative */
item = string_list_append(&src_tag, ref->name);
item->util = ref;
*/
int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
{
- struct refspec *refspec = parse_push_refspec(nr_refspec, refspec_names);
+ struct refspec_item *refspec = parse_push_refspec(nr_refspec, refspec_names);
int ret = 0;
int i;
for (i = 0; i < nr_refspec; i++) {
- struct refspec *rs = refspec + i;
+ struct refspec_item *rs = refspec + i;
if (rs->pattern || rs->matching)
continue;
int match_push_refs(struct ref *src, struct ref **dst,
int nr_refspec, const char **refspec, int flags)
{
- struct refspec *rs;
+ struct refspec_item *rs;
int send_all = flags & MATCH_REFS_ALL;
int send_mirror = flags & MATCH_REFS_MIRROR;
int send_prune = flags & MATCH_REFS_PRUNE;
for (ref = src; ref; ref = ref->next) {
struct string_list_item *dst_item;
struct ref *dst_peer;
- const struct refspec *pat = NULL;
+ const struct refspec_item *pat = NULL;
char *dst_name;
dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_SRC, &pat);
* local symbolic ref.
*/
static struct ref *get_expanded_map(const struct ref *remote_refs,
- const struct refspec *refspec)
+ const struct refspec_item *refspec)
{
const struct ref *ref;
struct ref *ret = NULL;
}
int get_fetch_map(const struct ref *remote_refs,
- const struct refspec *refspec,
+ const struct refspec_item *refspec,
struct ref ***tail,
int missing_ok)
{
struct stale_heads_info {
struct string_list *ref_names;
struct ref **stale_refs_tail;
- struct refspec *refs;
+ struct refspec_item *refs;
int ref_count;
};
{
struct stale_heads_info *info = cb_data;
struct string_list matches = STRING_LIST_INIT_DUP;
- struct refspec query;
+ struct refspec_item query;
int i, stale = 1;
- memset(&query, 0, sizeof(struct refspec));
+ memset(&query, 0, sizeof(struct refspec_item));
query.dst = (char *)refname;
query_refspecs_multiple(info->refs, info->ref_count, &query, &matches);
return 0;
}
-struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fetch_map)
+struct ref *get_stale_heads(struct refspec_item *refs, int ref_count, struct ref *fetch_map)
{
struct ref *ref, *stale_refs = NULL;
struct string_list ref_names = STRING_LIST_INIT_NODUP;