#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]);
-}
-
-int valid_fetch_refspec(const char *fetch_refspec_str)
-{
- struct refspec_item *refspec;
-
- refspec = parse_refspec_internal(1, &fetch_refspec_str, 1, 1);
- free_refspec(1, refspec);
- return !!refspec;
-}
-
-struct refspec_item *parse_fetch_refspec(int nr_refspec, const char **refspec)
-{
- 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);
-}
-
void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
{
memset(item, 0, sizeof(*item));
rs->fetch = 0;
}
+
+int valid_fetch_refspec(const char *fetch_refspec_str)
+{
+ struct refspec_item refspec;
+ int ret = parse_refspec(&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);
+ }
+ }
+ }
+}