#include "cache.h"
+#include "argv-array.h"
#include "refs.h"
#include "refspec.h"
size_t rlen = strlen(++rhs);
is_glob = (1 <= rlen && strchr(rhs, '*'));
item->dst = xstrndup(rhs, rlen);
+ } else {
+ item->dst = NULL;
}
llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
return 1;
}
-static struct refspec_item *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
-{
- int i;
- struct refspec_item *rs = xcalloc(nr_refspec, sizeof(*rs));
-
- for (i = 0; i < nr_refspec; i++) {
- if (!parse_refspec(&rs[i], refspec[i], fetch))
- 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]);
-}
-
-struct refspec_item *parse_fetch_refspec(int nr_refspec, const char **refspec)
+int refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
{
- return parse_refspec_internal(nr_refspec, refspec, 1, 0);
-}
-
-struct refspec_item *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_item *refspec)
-{
- int i;
-
- if (!refspec)
- return;
-
- for (i = 0; i < nr_refspec; i++) {
- free(refspec[i].src);
- free(refspec[i].dst);
- }
- free(refspec);
+ memset(item, 0, sizeof(*item));
+ return parse_refspec(item, refspec, fetch);
}
-void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
+void refspec_item_init_or_die(struct refspec_item *item, const char *refspec,
+ int fetch)
{
- memset(item, 0, sizeof(*item));
-
- if (!parse_refspec(item, refspec, fetch))
+ if (!refspec_item_init(item, refspec, fetch))
die("Invalid refspec '%s'", refspec);
}
{
struct refspec_item item;
- refspec_item_init(&item, refspec, rs->fetch);
+ refspec_item_init_or_die(&item, refspec, rs->fetch);
ALLOC_GROW(rs->items, rs->nr + 1, rs->alloc);
rs->items[rs->nr++] = item;
int valid_fetch_refspec(const char *fetch_refspec_str)
{
struct refspec_item refspec;
- int ret = parse_refspec(&refspec, fetch_refspec_str, REFSPEC_FETCH);
+ int ret = refspec_item_init(&refspec, fetch_refspec_str, REFSPEC_FETCH);
refspec_item_clear(&refspec);
return ret;
}
+
+void refspec_ref_prefixes(const struct refspec *rs,
+ struct argv_array *ref_prefixes)
+{
+ int i;
+ for (i = 0; i < rs->nr; i++) {
+ const struct refspec_item *item = &rs->items[i];
+ const char *prefix = NULL;
+
+ if (item->exact_sha1)
+ continue;
+ if (rs->fetch == REFSPEC_FETCH)
+ prefix = item->src;
+ else if (item->dst)
+ prefix = item->dst;
+ else if (item->src && !item->exact_sha1)
+ prefix = item->src;
+
+ if (prefix) {
+ if (item->pattern) {
+ const char *glob = strchr(prefix, '*');
+ argv_array_pushf(ref_prefixes, "%.*s",
+ (int)(glob - prefix),
+ prefix);
+ } else {
+ expand_ref_prefix(ref_prefixes, prefix);
+ }
+ }
+ }
+}