X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_file.c;h=942b673dc3c7fa9f057c5c452e3a1b73eaeb8707;hb=071c41a047e4c851836669648716e361f8e0b5ad;hp=bf8fd6aa5fd76c119dd1a84cc540a5219e1987e4;hpb=a1df57abb90d456b6b600b8cf6a5232a39cd3f5e;p=git.git diff --git a/sha1_file.c b/sha1_file.c index bf8fd6aa..942b673d 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -59,6 +59,38 @@ int get_sha1_file(const char *path, unsigned char *result) return get_sha1_hex(buffer, result); } +static char *git_dir, *git_object_dir, *git_index_file; +static void setup_git_env(void) +{ + git_dir = gitenv(GIT_DIR_ENVIRONMENT); + if (!git_dir) + git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; + git_object_dir = gitenv(DB_ENVIRONMENT); + if (!git_object_dir) { + git_object_dir = xmalloc(strlen(git_dir) + 9); + sprintf(git_object_dir, "%s/objects", git_dir); + } + git_index_file = gitenv(INDEX_ENVIRONMENT); + if (!git_index_file) { + git_index_file = xmalloc(strlen(git_dir) + 7); + sprintf(git_index_file, "%s/index", git_dir); + } +} + +char *get_object_directory(void) +{ + if (!git_object_dir) + setup_git_env(); + return git_object_dir; +} + +char *get_index_file(void) +{ + if (!git_index_file) + setup_git_env(); + return git_index_file; +} + int get_sha1(const char *str, unsigned char *sha1) { static char pathname[PATH_MAX]; @@ -70,15 +102,16 @@ int get_sha1(const char *str, unsigned char *sha1) "refs/snap", NULL }; - const char *gitdir; const char **p; if (!get_sha1_hex(str, sha1)) return 0; - gitdir = ".git"; + if (!git_dir) + setup_git_env(); for (p = prefix; *p; p++) { - snprintf(pathname, sizeof(pathname), "%s/%s/%s", gitdir, *p, str); + snprintf(pathname, sizeof(pathname), "%s/%s/%s", + git_dir, *p, str); if (!get_sha1_file(pathname, sha1)) return 0; } @@ -120,7 +153,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1) * * Also note that this returns the location for creating. Reading * SHA1 file can happen from any alternate directory listed in the - * SHA1_FILE_DIRECTORIES environment variable if it is not found in + * DB_ENVIRONMENT environment variable if it is not found in * the primary object database. */ char *sha1_file_name(const unsigned char *sha1) @@ -128,7 +161,7 @@ char *sha1_file_name(const unsigned char *sha1) static char *name, *base; if (!base) { - char *sha1_file_directory = get_object_directory(); + const char *sha1_file_directory = get_object_directory(); int len = strlen(sha1_file_directory); base = xmalloc(len + 60); memcpy(base, sha1_file_directory, len); @@ -141,20 +174,40 @@ char *sha1_file_name(const unsigned char *sha1) return base; } -static struct alternate_object_database -{ +static struct alternate_object_database { char *base; char *name; } *alt_odb; +/* + * Prepare alternate object database registry. + * alt_odb points at an array of struct alternate_object_database. + * This array is terminated with an element that has both its base + * and name set to NULL. alt_odb[n] comes from n'th non-empty + * element from colon separated ALTERNATE_DB_ENVIRONMENT environment + * variable, and its base points at a statically allocated buffer + * that contains "/the/directory/corresponding/to/.git/objects/...", + * while its name points just after the slash at the end of + * ".git/objects/" in the example above, and has enough space to hold + * 40-byte hex SHA1, an extra slash for the first level indirection, + * and the terminating NUL. + * This function allocates the alt_odb array and all the strings + * pointed by base fields of the array elements with one xmalloc(); + * the string pool immediately follows the array. + */ static void prepare_alt_odb(void) { int pass, totlen, i; - void *buf; const char *cp, *last; char *op = 0; - const char *alt = getenv(ALTERNATE_DB_ENVIRONMENT) ? : ""; - + const char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : ""; + + /* The first pass counts how large an area to allocate to + * hold the entire alt_odb structure, including array of + * structs and path buffers for them. The second pass fills + * the structure and prepares the path buffers for use by + * fill_sha1_path(). + */ for (totlen = pass = 0; pass < 2; pass++) { last = alt; i = 0; @@ -182,7 +235,7 @@ static void prepare_alt_odb(void) } while (*cp); if (pass) break; - alt_odb = buf = xmalloc(sizeof(*alt_odb) * (i + 1) + totlen); + alt_odb = xmalloc(sizeof(*alt_odb) * (i + 1) + totlen); alt_odb[i].base = alt_odb[i].name = 0; op = (char*)(&alt_odb[i+1]); } @@ -412,7 +465,7 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha stream.next_in = hdr; stream.avail_in = hdrlen; while (deflate(&stream, 0) == Z_OK) - /* nothing */ + /* nothing */; /* Then the data itself.. */ stream.next_in = buf;