summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 971f229)
raw | patch | inline | side by side (parent: 971f229)
author | Daniel Barkalow <barkalow@iabervon.org> | |
Tue, 18 Mar 2008 02:05:23 +0000 (22:05 -0400) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Wed, 19 Mar 2008 05:18:57 +0000 (22:18 -0700) |
This changes the pattern matching code to not store the required final
/ before the *, and then to require each side to be a valid ref (or
empty). In particular, any refspec that looks like it should be a
pattern but doesn't quite meet the requirements will be found to be
invalid as a fallback non-pattern.
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
/ before the *, and then to require each side to be a valid ref (or
empty). In particular, any refspec that looks like it should be a
pattern but doesn't quite meet the requirements will be found to be
invalid as a fallback non-pattern.
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
remote.c | patch | blob | history |
diff --git a/remote.c b/remote.c
index f3f7375eea6d8c09e4ab6f561be22b08e545efcb..9700a33c57d796144a3b2f2e47b53d1d32d14c0d 100644 (file)
--- a/remote.c
+++ b/remote.c
struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
{
int i;
+ int st;
struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
for (i = 0; i < nr_refspec; i++) {
const char *sp, *ep, *gp;
rs[i].force = 1;
sp++;
}
- gp = strchr(sp, '*');
+ gp = strstr(sp, "/*");
ep = strchr(sp, ':');
if (gp && ep && gp > ep)
gp = NULL;
if (ep) {
if (ep[1]) {
- const char *glob = strchr(ep + 1, '*');
+ const char *glob = strstr(ep + 1, "/*");
+ if (glob && glob[2])
+ glob = NULL;
if (!glob)
gp = NULL;
if (gp)
} else {
ep = sp + strlen(sp);
}
+ if (gp && gp + 2 != ep)
+ gp = NULL;
if (gp) {
rs[i].pattern = 1;
ep = gp;
}
rs[i].src = xstrndup(sp, ep - sp);
+
+ if (*rs[i].src) {
+ st = check_ref_format(rs[i].src);
+ if (st && st != CHECK_REF_FORMAT_ONELEVEL)
+ die("Invalid refspec '%s'", refspec[i]);
+ }
+ if (rs[i].dst && *rs[i].dst) {
+ st = check_ref_format(rs[i].dst);
+ if (st && st != CHECK_REF_FORMAT_ONELEVEL)
+ die("Invalid refspec '%s'", refspec[i]);
+ }
}
return rs;
}
if (!fetch->dst)
continue;
if (fetch->pattern) {
- if (!prefixcmp(needle, key)) {
+ if (!prefixcmp(needle, key) &&
+ needle[strlen(key)] == '/') {
*result = xmalloc(strlen(value) +
strlen(needle) -
strlen(key) + 1);
{
int i;
for (i = 0; i < rs_nr; i++) {
- if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
+ if (rs[i].pattern &&
+ !prefixcmp(src->name, rs[i].src) &&
+ src->name[strlen(rs[i].src)] == '/')
return rs + i;
}
return NULL;
struct ref ***tail,
int missing_ok)
{
- struct ref *ref_map, *rm;
+ struct ref *ref_map, **rmp;
if (refspec->pattern) {
ref_map = get_expanded_map(remote_refs, refspec);
}
}
- for (rm = ref_map; rm; rm = rm->next) {
- if (rm->peer_ref && check_ref_format(rm->peer_ref->name + 5))
- die("* refusing to create funny ref '%s' locally",
- rm->peer_ref->name);
+ for (rmp = &ref_map; *rmp; ) {
+ if ((*rmp)->peer_ref) {
+ int st = check_ref_format((*rmp)->peer_ref->name + 5);
+ if (st && st != CHECK_REF_FORMAT_ONELEVEL) {
+ struct ref *ignore = *rmp;
+ error("* Ignoring funny ref '%s' locally",
+ (*rmp)->peer_ref->name);
+ *rmp = (*rmp)->next;
+ free(ignore->peer_ref);
+ free(ignore);
+ continue;
+ }
+ }
+ rmp = &((*rmp)->next);
}
if (ref_map)