[PATCH 10/28] get_ref_dir(): keep track of the current ref_dir
- From
mhagger@alum.mit.edu <mhagger@alum.mit.edu>
- Date
- Oct 28, 2011, 12:28 UTC
- Message-ID
- <1319804921-17545-11-git-send-email-mhagger@alum.mit.edu>
- In-Reply-To
- <1319804921-17545-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Look up the ref_dir that will hold the new entries once at the start of processing of a directory. This eliminates the need to search down the reference tree to find the place to put each new reference.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> --- refs.c | 43 ++++++++++++++++++++++++++----------------- 1 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/refs.c b/refs.c index 515b44c..bdd90c5 100644 --- a/refs.c +++ b/refs.c @@ -775,29 +775,36 @@ static struct ref_dir *get_packed_refs(struct ref_cache *refs) return &refs->packed; } -static void get_ref_dir(struct ref_cache *refs, const char *base, - struct ref_dir *dir) +/* + * dirname must match the name associated with dir; in particular, it + * must end with '/'. + */ +static void get_ref_dir(struct ref_cache *refs, const char *dirname) { DIR *d; - const char *path; + char *path; + int dirnamelen = strlen(dirname); + int pathlen; + struct ref_dir *dir; + + assert(dirnamelen && dirname[dirnamelen - 1] == '/'); + + dir = find_containing_dir(&refs->loose, dirname, 1); if (*refs->name) - path = git_path_submodule(refs->name, "%s", base); + path = git_path_submodule(refs->name, "%s", dirname); else - path = git_path("%s", base); - + path = git_path("%s", dirname); + pathlen = strlen(path); + assert(pathlen && path[pathlen - 1] == '/'); + path[pathlen - 1] = '\0'; d = opendir(path); if (d) { struct dirent *de; - int baselen = strlen(base); - char *refname = xmalloc(baselen + 257); - - memcpy(refname, base, baselen); - if (baselen && base[baselen-1] != '/') - refname[baselen++] = '/'; - + char *refname = xmalloc(dirnamelen + 257); + memcpy(refname, dirname, dirnamelen); while ((de = readdir(d)) != NULL) { unsigned char sha1[20]; struct stat st; @@ -812,14 +819,16 @@ static void get_ref_dir(struct ref_cache *refs, const char *base, continue; if (has_extension(de->d_name, ".lock")) continue; - memcpy(refname + baselen, de->d_name, namelen+1); + memcpy(refname + dirnamelen, de->d_name, namelen+1); refdir = *refs->name ? git_path_submodule(refs->name, "%s", refname) : git_path("%s", refname); if (stat(refdir, &st) < 0) continue; if (S_ISDIR(st.st_mode)) { - get_ref_dir(refs, refname, dir); + refname[dirnamelen + namelen] = '/'; + refname[dirnamelen + namelen + 1] = '\0'; + get_ref_dir(refs, refname); continue; } if (*refs->name) { @@ -834,7 +843,7 @@ static void get_ref_dir(struct ref_cache *refs, const char *base, hashclr(sha1); flag |= REF_ISBROKEN; } - add_ref(dir, create_ref_entry(refname, sha1, flag)); + add_entry_to_dir(dir, create_ref_entry(refname, sha1, flag)); } free(refname); closedir(d); @@ -844,7 +853,7 @@ static void get_ref_dir(struct ref_cache *refs, const char *base, static struct ref_dir *get_loose_refs(struct ref_cache *refs) { if (!refs->did_loose) { - get_ref_dir(refs, "refs", &refs->loose); + get_ref_dir(refs, "refs/"); refs->did_loose = 1; } return &refs->loose;
-- 1.7.7