@ -376,11 +376,12 @@ void prepare_alt_odb(void)
@@ -376,11 +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 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
@@ -530,6 +531,21 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
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 @@ static int open_packed_git_1(struct packed_git *p)
@@ -605,6 +621,9 @@ static int open_packed_git_1(struct packed_git *p)
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 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
@@ -757,8 +776,7 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
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 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
@@ -766,6 +784,10 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
/* 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 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
@@ -1572,10 +1594,15 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
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 @@ off_t find_pack_entry_one(const unsigned char *sha1,
@@ -1612,6 +1639,12 @@ off_t find_pack_entry_one(const unsigned char *sha1,
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;