diff options
author | Junio C Hamano <junkio@cox.net> | 2007-01-16 13:43:28 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-02-13 21:43:53 -0800 |
commit | 86551586da8cba6c06ac04783a656843a4e47f35 (patch) | |
tree | fdc192784ed672835244a55220fb35869ec1b274 /builtin-fetch--tool.c | |
parent | d1e0ef6cc89e5ef2f914c37719b9c2327e534834 (diff) | |
download | git-86551586da8cba6c06ac04783a656843a4e47f35.tar.gz |
git-fetch: rewrite expand_ref_wildcard in C
This does not seem to make measurable improvement when dealing
with 1000 unpacked refs, but we would need something like it
if we were to do a full rewrite in C somedaoy.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'builtin-fetch--tool.c')
-rw-r--r-- | builtin-fetch--tool.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index 705a6649a9..3090ffea20 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -323,6 +323,91 @@ static int parse_reflist(const char *reflist) return 0; } +static int expand_refs_wildcard(const char *ls_remote_result, int numrefs, + const char **refs) +{ + int i, matchlen, replacelen; + int found_one = 0; + const char *remote = *refs++; + numrefs--; + + if (numrefs == 0) { + fprintf(stderr, "Nothing specified for fetching with remote.%s.fetch\n", + remote); + printf("empty\n"); + } + + for (i = 0; i < numrefs; i++) { + const char *ref = refs[i]; + const char *lref = ref; + const char *colon; + const char *tail; + const char *ls; + const char *next; + + if (*lref == '+') + lref++; + colon = strchr(lref, ':'); + tail = lref + strlen(lref); + if (!(colon && + 2 < colon - lref && + colon[-1] == '*' && + colon[-2] == '/' && + 2 < tail - (colon + 1) && + tail[-1] == '*' && + tail[-2] == '/')) { + /* not a glob */ + if (!found_one++) + printf("explicit\n"); + printf("%s\n", ref); + continue; + } + + /* glob */ + if (!found_one++) + printf("glob\n"); + + /* lref to colon-2 is remote hierarchy name; + * colon+1 to tail-2 is local. + */ + matchlen = (colon-1) - lref; + replacelen = (tail-1) - (colon+1); + for (ls = ls_remote_result; ls; ls = next) { + const char *eol; + unsigned char sha1[20]; + int namelen; + + while (*ls && isspace(*ls)) + ls++; + next = strchr(ls, '\n'); + eol = !next ? (ls + strlen(ls)) : next; + if (!memcmp("^{}", eol-3, 3)) + continue; + if (get_sha1_hex(ls, sha1)) + continue; + ls += 40; + while (ls < eol && isspace(*ls)) + ls++; + /* ls to next (or eol) is the name. + * is it identical to lref to colon-2? + */ + if ((eol - ls) <= matchlen || + strncmp(ls, lref, matchlen)) + continue; + + /* Yes, it is a match */ + namelen = eol - ls; + if (lref != ref) + putchar('+'); + printf("%.*s:%.*s%.*s\n", + namelen, ls, + replacelen, colon + 1, + namelen - matchlen, ls + matchlen); + } + } + return 0; +} + int cmd_fetch__tool(int argc, const char **argv, const char *prefix) { int verbose = 0; @@ -380,6 +465,11 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix) return error("parse-reflist takes 1 arg"); return parse_reflist(argv[2]); } + if (!strcmp("expand-refs-wildcard", argv[1])) { + if (argc < 4) + return error("expand-refs-wildcard takes at least 2 args"); + return expand_refs_wildcard(argv[2], argc - 3, argv + 3); + } return error("Unknown subcommand: %s", argv[1]); } |