From d1e0ef6cc89e5ef2f914c37719b9c2327e534834 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 16 Jan 2007 02:31:36 -0800 Subject: git-fetch: rewrite another shell loop in C Move another shell loop that canonicalizes the list of refs for underlying git-fetch-pack and fetch-native-store into C. This seems to shave the runtime for the same 1000 branch repository from 30 seconds down to 15 seconds (it used to be 2 and half minutes with the original version). Signed-off-by: Junio C Hamano --- builtin-fetch--tool.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ git-fetch.sh | 30 ++---------------------------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index 24343ac9b0..705a6649a9 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -283,6 +283,46 @@ static int fetch_native_store(FILE *fp, return err; } +static int parse_reflist(const char *reflist) +{ + const char *ref; + + printf("refs='"); + for (ref = reflist; ref; ) { + const char *next; + while (*ref && isspace(*ref)) + ref++; + if (!*ref) + break; + for (next = ref; *next && !isspace(*next); next++) + ; + printf("\n%.*s", (int)(next - ref), ref); + ref = next; + } + printf("'\n"); + + printf("rref='"); + for (ref = reflist; ref; ) { + const char *next, *colon; + while (*ref && isspace(*ref)) + ref++; + if (!*ref) + break; + for (next = ref; *next && !isspace(*next); next++) + ; + if (*ref == '.') + ref++; + if (*ref == '+') + ref++; + colon = strchr(ref, ':'); + putchar('\n'); + printf("%.*s", (int)((colon ? colon : next) - ref), ref); + ref = next; + } + printf("'\n"); + return 0; +} + int cmd_fetch__tool(int argc, const char **argv, const char *prefix) { int verbose = 0; @@ -335,5 +375,11 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix) fclose(fp); return result; } + if (!strcmp("parse-reflist", argv[1])) { + if (argc != 3) + return error("parse-reflist takes 1 arg"); + return parse_reflist(argv[2]); + } + return error("Unknown subcommand: %s", argv[1]); } diff --git a/git-fetch.sh b/git-fetch.sh index b74dd9a309..3bed4091a3 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -155,35 +155,9 @@ then fi fetch_native () { - reflist="$1" - refs= - rref= - - for ref in $reflist - do - refs="$refs$LF$ref" - - # These are relative path from $GIT_DIR, typically starting at refs/ - # but may be HEAD - if expr "z$ref" : 'z\.' >/dev/null - then - not_for_merge=t - ref=$(expr "z$ref" : 'z\.\(.*\)') - else - not_for_merge= - fi - if expr "z$ref" : 'z+' >/dev/null - then - single_force=t - ref=$(expr "z$ref" : 'z+\(.*\)') - else - single_force= - fi - remote_name=$(expr "z$ref" : 'z\([^:]*\):') - local_name=$(expr "z$ref" : 'z[^:]*:\(.*\)') - rref="$rref$LF$remote_name" - done + eval=$(git-fetch--tool parse-reflist "$1") + eval "$eval" ( : subshell because we muck with IFS IFS=" $LF" -- cgit v1.2.3