#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)
#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);
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];
hashwrite_be32(f, MIDX_SIGNATURE);
byte_values[0] = MIDX_VERSION;
- byte_values[1] = MIDX_HASH_VERSION;
+ byte_values[1] = oid_version();
byte_values[2] = num_chunks;
byte_values[3] = 0; /* unused */
hashwrite(f, byte_values, sizeof(byte_values));
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"),
free(pack_info);
- if (total_size < batch_size || packs_to_repack < 2)
+ if (packs_to_repack < 2)
return 1;
return 0;
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);
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);
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);
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"));