424
alias_all_urls();
425
}
426
427
+/*
428
+ * We need to make sure the tracking branches are well formed, but a
429
+ * wildcard refspec in "struct refspec" must have a trailing slash. We
430
+ * temporarily drop the trailing '/' while calling check_ref_format(),
431
+ * and put it back. The caller knows that a CHECK_REF_FORMAT_ONELEVEL
432
+ * error return is Ok for a wildcard refspec.
433
+ */
434
+static int verify_refname(char *name, int is_glob)
435
+{
436
+ int result, len = -1;
437
+
438
+ if (is_glob) {
439
+ len = strlen(name);
440
+ assert(name[len - 1] == '/');
441
+ name[len - 1] = '\0';
442
+ }
443
+ result = check_ref_format(name);
444
+ if (is_glob)
445
+ name[len - 1] = '/';
446
+ return result;
447
+}
448
+
449
static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
450
{
451
int i;
453
struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
454
455
for (i = 0; i < nr_refspec; i++) {
434
- size_t llen, rlen;
456
+ size_t llen;
457
int is_glob;
458
const char *lhs, *rhs;
459
438
- llen = rlen = is_glob = 0;
460
+ llen = is_glob = 0;
461
462
lhs = refspec[i];
463
if (*lhs == '+') {
477
}
478
479
if (rhs) {
458
- rhs++;
459
- rlen = strlen(rhs);
480
+ size_t rlen = strlen(++rhs);
481
is_glob = (2 <= rlen && !strcmp(rhs + rlen - 2, "/*"));
461
- if (is_glob)
462
- rlen -= 2;
463
- rs[i].dst = xstrndup(rhs, rlen);
482
+ rs[i].dst = xstrndup(rhs, rlen - is_glob);
483
}
484
485
llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
487
if ((rhs && !is_glob) || (!rhs && fetch))
488
goto invalid;
489
is_glob = 1;
471
- llen -= 2;
490
+ llen--;
491
} else if (rhs && is_glob) {
492
goto invalid;
493
}
504
if (!*rs[i].src)
505
; /* empty is ok */
506
else {
488
- st = check_ref_format(rs[i].src);
507
+ st = verify_refname(rs[i].src, is_glob);
508
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
509
goto invalid;
510
}
519
} else if (!*rs[i].dst) {
520
; /* ok */
521
} else {
503
- st = check_ref_format(rs[i].dst);
522
+ st = verify_refname(rs[i].dst, is_glob);
523
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
524
goto invalid;
525
}
534
if (!*rs[i].src)
535
; /* empty is ok */
536
else if (is_glob) {
518
- st = check_ref_format(rs[i].src);
537
+ st = verify_refname(rs[i].src, is_glob);
538
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
539
goto invalid;
540
}
548
* - otherwise it must be a valid looking ref.
549
*/
550
if (!rs[i].dst) {
532
- st = check_ref_format(rs[i].src);
551
+ st = verify_refname(rs[i].src, is_glob);
552
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
553
goto invalid;
554
} else if (!*rs[i].dst) {
555
goto invalid;
556
} else {
538
- st = check_ref_format(rs[i].dst);
557
+ st = verify_refname(rs[i].dst, is_glob);
558
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
559
goto invalid;
560
}
703
if (!fetch->dst)
704
continue;
705
if (fetch->pattern) {
687
- if (!prefixcmp(needle, key) &&
688
- needle[strlen(key)] == '/') {
706
+ if (!prefixcmp(needle, key)) {
707
*result = xmalloc(strlen(value) +
708
strlen(needle) -
709
strlen(key) + 1);
981
continue;
982
}
983
966
- if (rs[i].pattern &&
967
- !prefixcmp(src->name, rs[i].src) &&
968
- src->name[strlen(rs[i].src)] == '/')
984
+ if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
985
return rs + i;
986
}
987
if (matching_refs != -1)