summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-count-objects.c2
-rw-r--r--cache.h3
-rw-r--r--pack-check.c9
-rw-r--r--pack-redundant.c3
-rw-r--r--sha1_file.c38
5 files changed, 49 insertions, 6 deletions
diff --git a/builtin-count-objects.c b/builtin-count-objects.c
index ff90ebd..ac65e03 100644
--- a/builtin-count-objects.c
+++ b/builtin-count-objects.c
@@ -111,6 +111,8 @@ int cmd_count_objects(int ac, const char **av, const char *prefix)
for (p = packed_git; p; p = p->next) {
if (!p->pack_local)
continue;
+ if (!p->index_data && open_pack_index(p))
+ continue;
packed += p->num_objects;
num_pack++;
}
diff --git a/cache.h b/cache.h
index cd875bc..0f4a05b 100644
--- a/cache.h
+++ b/cache.h
@@ -485,10 +485,11 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
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 --git a/pack-check.c b/pack-check.c
index c168642..3623c71 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -128,12 +128,17 @@ static void show_pack_info(struct packed_git *p)
int verify_pack(struct packed_git *p, int verbose)
{
- off_t index_size = p->index_size;
- const unsigned char *index_base = p->index_data;
+ off_t index_size;
+ const unsigned char *index_base;
SHA_CTX ctx;
unsigned char sha1[20];
int ret;
+ if (open_pack_index(p))
+ return error("packfile %s index not opened", p->pack_name);
+ index_size = p->index_size;
+ index_base = p->index_data;
+
ret = 0;
/* Verify SHA1 sum of the index file */
SHA1_Init(&ctx);
diff --git a/pack-redundant.c b/pack-redundant.c
index 87077e1..0617320 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -550,6 +550,9 @@ static struct pack_list * add_pack(struct packed_git *p)
l.pack = p;
llist_init(&l.all_objects);
+ if (!p->index_data && open_pack_index(p))
+ return NULL;
+
base = p->index_data;
base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
step = (p->index_version < 2) ? 24 : 20;
diff --git a/sha1_file.c b/sha1_file.c
index 12d2ef2..6a5ba63 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -530,6 +530,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 +620,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 +775,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 +783,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 +1593,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 +1638,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;