summaryrefslogtreecommitdiff
path: root/midx.c
diff options
context:
space:
mode:
Diffstat (limited to 'midx.c')
-rw-r--r--midx.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/midx.c b/midx.c
index 6d1584ca51..0de42ffdfb 100644
--- a/midx.c
+++ b/midx.c
@@ -17,7 +17,6 @@
#define MIDX_BYTE_HASH_VERSION 5
#define MIDX_BYTE_NUM_CHUNKS 6
#define MIDX_BYTE_NUM_PACKS 8
-#define MIDX_HASH_VERSION 1
#define MIDX_HEADER_SIZE 12
#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + the_hash_algo->rawsz)
@@ -36,6 +35,18 @@
#define PACK_EXPIRED UINT_MAX
+static uint8_t oid_version(void)
+{
+ switch (hash_algo_by_ptr(the_hash_algo)) {
+ case GIT_HASH_SHA1:
+ return 1;
+ case GIT_HASH_SHA256:
+ return 2;
+ default:
+ die(_("invalid hash version"));
+ }
+}
+
static char *get_midx_filename(const char *object_dir)
{
return xstrfmt("%s/pack/multi-pack-index", object_dir);
@@ -90,8 +101,11 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
m->version);
hash_version = m->data[MIDX_BYTE_HASH_VERSION];
- if (hash_version != MIDX_HASH_VERSION)
- die(_("hash version %u does not match"), hash_version);
+ if (hash_version != oid_version()) {
+ error(_("multi-pack-index hash version %u does not match version %u"),
+ hash_version, oid_version());
+ goto cleanup_fail;
+ }
m->hash_len = the_hash_algo->rawsz;
m->num_chunks = m->data[MIDX_BYTE_NUM_CHUNKS];
@@ -402,8 +416,12 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i
m = load_multi_pack_index(object_dir, local);
if (m) {
- m->next = r->objects->multi_pack_index;
- r->objects->multi_pack_index = m;
+ struct multi_pack_index *mp = r->objects->multi_pack_index;
+ if (mp) {
+ m->next = mp->next;
+ mp->next = m;
+ } else
+ r->objects->multi_pack_index = m;
return 1;
}
@@ -414,14 +432,11 @@ static size_t write_midx_header(struct hashfile *f,
unsigned char num_chunks,
uint32_t num_packs)
{
- unsigned char byte_values[4];
-
hashwrite_be32(f, MIDX_SIGNATURE);
- byte_values[0] = MIDX_VERSION;
- byte_values[1] = MIDX_HASH_VERSION;
- byte_values[2] = num_chunks;
- byte_values[3] = 0; /* unused */
- hashwrite(f, byte_values, sizeof(byte_values));
+ hashwrite_u8(f, MIDX_VERSION);
+ hashwrite_u8(f, oid_version());
+ hashwrite_u8(f, num_chunks);
+ hashwrite_u8(f, 0); /* unused */
hashwrite_be32(f, num_packs);
return MIDX_HEADER_SIZE;
@@ -807,11 +822,9 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *
int result = 0;
midx_name = get_midx_filename(object_dir);
- if (safe_create_leading_directories(midx_name)) {
- UNLEAK(midx_name);
+ if (safe_create_leading_directories(midx_name))
die_errno(_("unable to create leading directories of %s"),
midx_name);
- }
if (m)
packs.m = m;
@@ -1051,10 +1064,8 @@ void clear_midx_file(struct repository *r)
r->objects->multi_pack_index = NULL;
}
- if (remove_path(midx)) {
- UNLEAK(midx);
+ if (remove_path(midx))
die(_("failed to clear multi-pack-index at %s"), midx);
- }
free(midx);
}
@@ -1105,8 +1116,17 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
struct multi_pack_index *m = load_multi_pack_index(object_dir, 1);
verify_midx_error = 0;
- if (!m)
- return 0;
+ if (!m) {
+ int result = 0;
+ struct stat sb;
+ char *filename = get_midx_filename(object_dir);
+ if (!stat(filename, &sb)) {
+ error(_("multi-pack-index file exists, but failed to parse"));
+ result = 1;
+ }
+ free(filename);
+ return result;
+ }
if (flags & MIDX_PROGRESS)
progress = start_progress(_("Looking for referenced packfiles"),
@@ -1371,7 +1391,7 @@ static int fill_included_packs_batch(struct repository *r,
free(pack_info);
- if (total_size < batch_size || packs_to_repack < 2)
+ if (packs_to_repack < 2)
return 1;
return 0;
@@ -1383,6 +1403,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
uint32_t i;
unsigned char *include_pack;
struct child_process cmd = CHILD_PROCESS_INIT;
+ FILE *cmd_in;
struct strbuf base_name = STRBUF_INIT;
struct multi_pack_index *m = load_multi_pack_index(object_dir, 1);
@@ -1408,21 +1429,21 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
repo_config_get_bool(r, "repack.usedeltabaseoffset", &delta_base_offset);
repo_config_get_bool(r, "repack.usedeltaislands", &use_delta_islands);
- argv_array_push(&cmd.args, "pack-objects");
+ strvec_push(&cmd.args, "pack-objects");
strbuf_addstr(&base_name, object_dir);
strbuf_addstr(&base_name, "/pack/pack");
- argv_array_push(&cmd.args, base_name.buf);
+ strvec_push(&cmd.args, base_name.buf);
if (delta_base_offset)
- argv_array_push(&cmd.args, "--delta-base-offset");
+ strvec_push(&cmd.args, "--delta-base-offset");
if (use_delta_islands)
- argv_array_push(&cmd.args, "--delta-islands");
+ strvec_push(&cmd.args, "--delta-islands");
if (flags & MIDX_PROGRESS)
- argv_array_push(&cmd.args, "--progress");
+ strvec_push(&cmd.args, "--progress");
else
- argv_array_push(&cmd.args, "-q");
+ strvec_push(&cmd.args, "-q");
strbuf_release(&base_name);
@@ -1435,6 +1456,8 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
goto cleanup;
}
+ cmd_in = xfdopen(cmd.in, "w");
+
for (i = 0; i < m->num_objects; i++) {
struct object_id oid;
uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
@@ -1443,10 +1466,9 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
continue;
nth_midxed_object_oid(&oid, m, i);
- xwrite(cmd.in, oid_to_hex(&oid), the_hash_algo->hexsz);
- xwrite(cmd.in, "\n", 1);
+ fprintf(cmd_in, "%s\n", oid_to_hex(&oid));
}
- close(cmd.in);
+ fclose(cmd_in);
if (finish_command(&cmd)) {
error(_("could not finish pack-objects"));