[PATCH v2 33/51] get_ref_dir(): keep track of the current ref_dir
From: <hidden>
Date: 2016-06-15 22:52:36
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Michael Haggerty <redacted> 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 <redacted> --- refs.c | 43 ++++++++++++++++++++++++++----------------- 1 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/refs.c b/refs.c
index 6a11235..6912db3 100644
--- a/refs.c
+++ b/refs.c@@ -730,29 +730,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;
@@ -767,14 +774,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) {
@@ -788,7 +797,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, 1)); + add_entry_to_dir(dir, create_ref_entry(refname, sha1, flag, 1)); } free(refname); closedir(d);
@@ -798,7 +807,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.8