Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'refspec.c')
-rw-r--r--refspec.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/refspec.c b/refspec.c
index f10ef284ce..6350100c7c 100644
--- a/refspec.c
+++ b/refspec.c
@@ -8,6 +8,7 @@ static struct refspec_item s_tag_refspec = {
1,
0,
0,
+ 0,
"refs/tags/*",
"refs/tags/*"
};
@@ -32,10 +33,17 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet
if (*lhs == '+') {
item->force = 1;
lhs++;
+ } else if (*lhs == '^') {
+ item->negative = 1;
+ lhs++;
}
rhs = strrchr(lhs, ':');
+ /* negative refspecs only have one side */
+ if (item->negative && rhs)
+ return 0;
+
/*
* Before going on, special case ":" (or "+:") as a refspec
* for pushing matching refs.
@@ -55,7 +63,7 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet
llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
if (1 <= llen && memchr(lhs, '*', llen)) {
- if ((rhs && !is_glob) || (!rhs && fetch))
+ if ((rhs && !is_glob) || (!rhs && !item->negative && fetch))
return 0;
is_glob = 1;
} else if (rhs && is_glob) {
@@ -66,6 +74,28 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet
item->src = xstrndup(lhs, llen);
flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
+ if (item->negative) {
+ struct object_id unused;
+
+ /*
+ * Negative refspecs only have a LHS, which indicates a ref
+ * (or pattern of refs) to exclude from other matches. This
+ * can either be a simple ref, or a glob pattern. Exact sha1
+ * match is not currently supported.
+ */
+ if (!*item->src)
+ return 0; /* negative refspecs must not be empty */
+ else if (llen == the_hash_algo->hexsz && !get_oid_hex(item->src, &unused))
+ return 0; /* negative refpsecs cannot be exact sha1 */
+ else if (!check_refname_format(item->src, flags))
+ ; /* valid looking ref is ok */
+ else
+ return 0;
+
+ /* the other rules below do not apply to negative refspecs */
+ return 1;
+ }
+
if (fetch) {
struct object_id unused;
@@ -209,7 +239,7 @@ void refspec_ref_prefixes(const struct refspec *rs,
const struct refspec_item *item = &rs->items[i];
const char *prefix = NULL;
- if (item->exact_sha1)
+ if (item->exact_sha1 || item->negative)
continue;
if (rs->fetch == REFSPEC_FETCH)
prefix = item->src;