From: Junio C Hamano Date: Sat, 2 Jun 2007 19:18:51 +0000 (-0700) Subject: Merge branch 'sp/pack' X-Git-Tag: v1.5.3-rc0~171 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/17c2929aa2ed999cbefa75ca5e933e1bf53a95bf?ds=inline;hp=-c Merge branch 'sp/pack' * sp/pack: Style nit - don't put space after function names Ensure the pack index is opened before access Simplify index access condition in count-objects, pack-redundant Test for recent rev-parse $abbrev_sha1 regression rev-parse: Identify short sha1 sums correctly. Attempt to delay prepare_alt_odb during get_sha1 Micro-optimize prepare_alt_odb Lazily open pack index files on demand --- 17c2929aa2ed999cbefa75ca5e933e1bf53a95bf diff --combined cache.h index 0da7070da4,0f4a05b51e..8a9d1f3883 --- a/cache.h +++ b/cache.h @@@ -359,8 -359,8 +359,8 @@@ extern void *map_sha1_file(const unsign extern int has_pack_file(const unsigned char *sha1); extern int has_pack_index(const unsigned char *sha1); -extern signed char hexval_table[256]; -static inline unsigned int hexval(unsigned int c) +extern const signed char hexval_table[256]; +static inline unsigned int hexval(unsigned char c) { return hexval_table[c]; } @@@ -467,6 -467,8 +467,6 @@@ struct ref extern pid_t git_connect(int fd[2], char *url, const char *prog, int flags); extern int finish_connect(pid_t pid); extern int path_match(const char *path, int nr, char **match); -extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, - int nr_refspec, char **refspec, int all); extern int get_ack(int fd, unsigned char *result_sha1); extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags); extern int server_supports(const char *feature); @@@ -483,10 -485,11 +483,11 @@@ extern struct packed_git *find_sha1_pac struct packed_git *packs); extern void pack_report(void); + extern int open_pack_index(struct packed_git *); extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *); extern void unuse_pack(struct pack_window **); extern struct packed_git *add_packed_git(const char *, int, int); - extern const unsigned char *nth_packed_object_sha1(const struct packed_git *, uint32_t); + extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t); extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *); extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *); extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep); diff --combined sha1_file.c index a1b8fca6c9,3093ac9f5f..30bcd46ceb --- a/sha1_file.c +++ b/sha1_file.c @@@ -33,7 -33,7 +33,7 @@@ const unsigned char null_sha1[20] static unsigned int sha1_file_open_flag = O_NOATIME; -signed char hexval_table[256] = { +const signed char hexval_table[256] = { -1, -1, -1, -1, -1, -1, -1, -1, /* 00-07 */ -1, -1, -1, -1, -1, -1, -1, -1, /* 08-0f */ -1, -1, -1, -1, -1, -1, -1, -1, /* 10-17 */ @@@ -376,11 -376,12 +376,12 @@@ void prepare_alt_odb(void { const char *alt; + if (alt_odb_tail) + return; + alt = getenv(ALTERNATE_DB_ENVIRONMENT); if (!alt) alt = ""; - if (alt_odb_tail) - return; alt_odb_tail = &alt_odb_list; link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0); @@@ -530,6 -531,21 +531,21 @@@ static int check_packed_git_idx(const c return 0; } + int open_pack_index(struct packed_git *p) + { + char *idx_name; + int ret; + + if (p->index_data) + return 0; + + idx_name = xstrdup(p->pack_name); + strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx"); + ret = check_packed_git_idx(idx_name, p); + free(idx_name); + return ret; + } + static void scan_windows(struct packed_git *p, struct packed_git **lru_p, struct pack_window **lru_w, @@@ -605,6 -621,9 +621,9 @@@ static int open_packed_git_1(struct pac unsigned char *idx_sha1; long fd_flag; + if (!p->index_data && open_pack_index(p)) + return error("packfile %s index unavailable", p->pack_name); + p->pack_fd = open(p->pack_name, O_RDONLY); if (p->pack_fd < 0 || fstat(p->pack_fd, &st)) return -1; @@@ -757,8 -776,7 +776,7 @@@ struct packed_git *add_packed_git(cons return NULL; memcpy(p->pack_name, path, path_len); strcpy(p->pack_name + path_len, ".pack"); - if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode) || - check_packed_git_idx(path, p)) { + if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) { free(p); return NULL; } @@@ -766,6 -784,10 +784,10 @@@ /* ok, it looks sane as far as we can check without * actually mapping the pack file. */ + p->index_version = 0; + p->index_data = NULL; + p->index_size = 0; + p->num_objects = 0; p->pack_size = st.st_size; p->next = NULL; p->windows = NULL; @@@ -1572,10 -1594,15 +1594,15 @@@ void *unpack_entry(struct packed_git *p return data; } - const unsigned char *nth_packed_object_sha1(const struct packed_git *p, + const unsigned char *nth_packed_object_sha1(struct packed_git *p, uint32_t n) { const unsigned char *index = p->index_data; + if (!index) { + if (open_pack_index(p)) + return NULL; + index = p->index_data; + } if (n >= p->num_objects) return NULL; index += 4 * 256; @@@ -1612,6 -1639,12 +1639,12 @@@ off_t find_pack_entry_one(const unsigne const unsigned char *index = p->index_data; unsigned hi, lo; + if (!index) { + if (open_pack_index(p)) + return 0; + level1_ofs = p->index_data; + index = p->index_data; + } if (p->index_version > 1) { level1_ofs += 2; index += 8; @@@ -1654,25 -1687,20 +1687,25 @@@ static int matches_pack_name(struct pac static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed) { + static struct packed_git *last_found = (void *)1; struct packed_git *p; off_t offset; prepare_packed_git(); + if (!packed_git) + return 0; + p = (last_found == (void *)1) ? packed_git : last_found; - for (p = packed_git; p; p = p->next) { + do { if (ignore_packed) { const char **ig; for (ig = ignore_packed; *ig; ig++) if (!matches_pack_name(p, *ig)) break; if (*ig) - continue; + goto next; } + offset = find_pack_entry_one(sha1, p); if (offset) { /* @@@ -1685,23 -1713,14 +1718,23 @@@ */ if (p->pack_fd == -1 && open_packed_git(p)) { error("packfile %s cannot be accessed", p->pack_name); - continue; + goto next; } e->offset = offset; e->p = p; hashcpy(e->sha1, sha1); + last_found = p; return 1; } - } + + next: + if (p == last_found) + p = packed_git; + else + p = p->next; + if (p == last_found) + p = p->next; + } while (p); return 0; }