X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_file.c;h=895c1fab6fc00b8131e44851f33b79b1d2310b12;hb=babfaba23d530e2818db62161825a65e582adbdc;hp=b6ebbc5c9a29438f365478bced6845bf78854ee2;hpb=1f40c7c24d999675df818f9d7824937a964f9f40;p=git.git diff --git a/sha1_file.c b/sha1_file.c index b6ebbc5c..895c1fab 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -20,6 +20,8 @@ #endif #endif +const unsigned char null_sha1[20] = { 0, }; + static unsigned int sha1_file_open_flag = O_NOATIME; static unsigned hexval(char c) @@ -50,26 +52,33 @@ static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file; static void setup_git_env(void) { - git_dir = gitenv(GIT_DIR_ENVIRONMENT); + git_dir = getenv(GIT_DIR_ENVIRONMENT); if (!git_dir) git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; - git_object_dir = gitenv(DB_ENVIRONMENT); + git_object_dir = getenv(DB_ENVIRONMENT); if (!git_object_dir) { git_object_dir = xmalloc(strlen(git_dir) + 9); sprintf(git_object_dir, "%s/objects", git_dir); } git_refs_dir = xmalloc(strlen(git_dir) + 6); sprintf(git_refs_dir, "%s/refs", git_dir); - git_index_file = gitenv(INDEX_ENVIRONMENT); + git_index_file = getenv(INDEX_ENVIRONMENT); if (!git_index_file) { git_index_file = xmalloc(strlen(git_dir) + 7); sprintf(git_index_file, "%s/index", git_dir); } - git_graft_file = gitenv(GRAFT_ENVIRONMENT); + git_graft_file = getenv(GRAFT_ENVIRONMENT); if (!git_graft_file) git_graft_file = strdup(git_path("info/grafts")); } +char *get_git_dir(void) +{ + if (!git_dir) + setup_git_env(); + return git_dir; +} + char *get_object_directory(void) { if (!git_object_dir) @@ -240,50 +249,75 @@ static struct alternate_object_database **alt_odb_tail; * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -static void link_alt_odb_entries(const char *alt, const char *ep) +static void link_alt_odb_entries(const char *alt, const char *ep, int sep, + const char *relative_base) { const char *cp, *last; struct alternate_object_database *ent; + int base_len = -1; last = alt; - do { - for (cp = last; cp < ep && *cp != ':'; cp++) + while (last < ep) { + cp = last; + if (cp < ep && *cp == '#') { + while (cp < ep && *cp != sep) + cp++; + last = cp + 1; + continue; + } + for ( ; cp < ep && *cp != sep; cp++) ; if (last != cp) { /* 43 = 40-byte + 2 '/' + terminating NUL */ int pfxlen = cp - last; int entlen = pfxlen + 43; + if (*last != '/' && relative_base) { + /* Relative alt-odb */ + if (base_len < 0) + base_len = strlen(relative_base) + 1; + entlen += base_len; + pfxlen += base_len; + } ent = xmalloc(sizeof(*ent) + entlen); *alt_odb_tail = ent; alt_odb_tail = &(ent->next); ent->next = NULL; - - memcpy(ent->base, last, pfxlen); + if (*last != '/' && relative_base) { + memcpy(ent->base, relative_base, base_len - 1); + ent->base[base_len - 1] = '/'; + memcpy(ent->base + base_len, + last, cp - last); + } + else + memcpy(ent->base, last, pfxlen); ent->name = ent->base + pfxlen + 1; ent->base[pfxlen] = ent->base[pfxlen + 3] = '/'; ent->base[entlen-1] = 0; } - while (cp < ep && *cp == ':') + while (cp < ep && *cp == sep) cp++; last = cp; - } while (cp < ep); + } } void prepare_alt_odb(void) { char path[PATH_MAX]; - char *map, *ep; + char *map; int fd; struct stat st; - char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : ""; + char *alt; + + alt = getenv(ALTERNATE_DB_ENVIRONMENT); + if (!alt) alt = ""; - sprintf(path, "%s/info/alternates", get_object_directory()); if (alt_odb_tail) return; alt_odb_tail = &alt_odb_list; - link_alt_odb_entries(alt, alt + strlen(alt)); + link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL); + sprintf(path, "%s/info/alternates", get_object_directory()); fd = open(path, O_RDONLY); if (fd < 0) return; @@ -296,10 +330,8 @@ void prepare_alt_odb(void) if (map == MAP_FAILED) return; - /* Remove the trailing newline */ - for (ep = map + st.st_size - 1; map < ep && ep[-1] == '\n'; ep--) - ; - link_alt_odb_entries(map, ep); + link_alt_odb_entries(map, map + st.st_size, '\n', + get_object_directory()); munmap(map, st.st_size); } @@ -480,7 +512,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1) return parse_pack_index_file(sha1, path); } -struct packed_git *parse_pack_index_file(unsigned char *sha1, char *idx_path) +struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_path) { struct packed_git *p; unsigned long idx_size; @@ -841,7 +873,8 @@ void packed_object_info_detail(struct pack_entry *e, strcpy(type, "tag"); break; default: - die("corrupted pack file"); + die("corrupted pack file %s containing object of kind %d", + p->pack_name, kind); } *store_size = 0; /* notyet */ } @@ -880,7 +913,8 @@ static int packed_object_info(struct pack_entry *entry, strcpy(type, "tag"); break; default: - die("corrupted pack file"); + die("corrupted pack file %s containing object of kind %d", + p->pack_name, kind); } if (sizep) *sizep = size; @@ -980,7 +1014,7 @@ static void *unpack_entry(struct pack_entry *entry, retval = unpack_entry_gently(entry, type, sizep); unuse_packed_git(p); if (!retval) - die("corrupted pack file"); + die("corrupted pack file %s", p->pack_name); return retval; }