builtin/index-pack.c: write reverse indexes

Teach 'git index-pack' to optionally write and verify reverse index with
'--[no-]rev-index', as well as respecting the 'pack.writeReverseIndex'
configuration option.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Taylor Blau
2021-01-25 18:37:26 -05:00
committed by Junio C Hamano
parent 84d544943c
commit e37d0b8730
3 changed files with 131 additions and 8 deletions

View File

@ -17,7 +17,7 @@
#include "promisor-remote.h"
static const char index_pack_usage[] =
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
struct object_entry {
struct pack_idx_entry idx;
@ -1484,12 +1484,14 @@ static void write_special_file(const char *suffix, const char *msg,
static void final(const char *final_pack_name, const char *curr_pack_name,
const char *final_index_name, const char *curr_index_name,
const char *final_rev_index_name, const char *curr_rev_index_name,
const char *keep_msg, const char *promisor_msg,
unsigned char *hash)
{
const char *report = "pack";
struct strbuf pack_name = STRBUF_INIT;
struct strbuf index_name = STRBUF_INIT;
struct strbuf rev_index_name = STRBUF_INIT;
int err;
if (!from_stdin) {
@ -1524,6 +1526,16 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
} else
chmod(final_index_name, 0444);
if (curr_rev_index_name) {
if (final_rev_index_name != curr_rev_index_name) {
if (!final_rev_index_name)
final_rev_index_name = odb_pack_name(&rev_index_name, hash, "rev");
if (finalize_object_file(curr_rev_index_name, final_rev_index_name))
die(_("cannot store reverse index file"));
} else
chmod(final_rev_index_name, 0444);
}
if (do_fsck_object) {
struct packed_git *p;
p = add_packed_git(final_index_name, strlen(final_index_name), 0);
@ -1553,6 +1565,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
}
}
strbuf_release(&rev_index_name);
strbuf_release(&index_name);
strbuf_release(&pack_name);
}
@ -1578,6 +1591,12 @@ static int git_index_pack_config(const char *k, const char *v, void *cb)
}
return 0;
}
if (!strcmp(k, "pack.writereverseindex")) {
if (git_config_bool(k, v))
opts->flags |= WRITE_REV;
else
opts->flags &= ~WRITE_REV;
}
return git_default_config(k, v, cb);
}
@ -1695,12 +1714,14 @@ static void show_pack_info(int stat_only)
int cmd_index_pack(int argc, const char **argv, const char *prefix)
{
int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
int i, fix_thin_pack = 0, verify = 0, stat_only = 0, rev_index;
const char *curr_index;
const char *index_name = NULL, *pack_name = NULL;
const char *curr_rev_index = NULL;
const char *index_name = NULL, *pack_name = NULL, *rev_index_name = NULL;
const char *keep_msg = NULL;
const char *promisor_msg = NULL;
struct strbuf index_name_buf = STRBUF_INIT;
struct strbuf rev_index_name_buf = STRBUF_INIT;
struct pack_idx_entry **idx_objects;
struct pack_idx_option opts;
unsigned char pack_hash[GIT_MAX_RAWSZ];
@ -1727,6 +1748,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (prefix && chdir(prefix))
die(_("Cannot come back to cwd"));
rev_index = !!(opts.flags & (WRITE_REV_VERIFY | WRITE_REV));
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@ -1805,6 +1828,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (hash_algo == GIT_HASH_UNKNOWN)
die(_("unknown hash algorithm '%s'"), arg);
repo_set_hash_algo(the_repository, hash_algo);
} else if (!strcmp(arg, "--rev-index")) {
rev_index = 1;
} else if (!strcmp(arg, "--no-rev-index")) {
rev_index = 0;
} else
usage(index_pack_usage);
continue;
@ -1826,6 +1853,15 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (!index_name && pack_name)
index_name = derive_filename(pack_name, "pack", "idx", &index_name_buf);
opts.flags &= ~(WRITE_REV | WRITE_REV_VERIFY);
if (rev_index) {
opts.flags |= verify ? WRITE_REV_VERIFY : WRITE_REV;
if (index_name)
rev_index_name = derive_filename(index_name,
"idx", "rev",
&rev_index_name_buf);
}
if (verify) {
if (!index_name)
die(_("--verify with no packfile name given"));
@ -1878,11 +1914,16 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
for (i = 0; i < nr_objects; i++)
idx_objects[i] = &objects[i].idx;
curr_index = write_idx_file(index_name, idx_objects, nr_objects, &opts, pack_hash);
if (rev_index)
curr_rev_index = write_rev_file(rev_index_name, idx_objects,
nr_objects, pack_hash,
opts.flags);
free(idx_objects);
if (!verify)
final(pack_name, curr_pack,
index_name, curr_index,
rev_index_name, curr_rev_index,
keep_msg, promisor_msg,
pack_hash);
else
@ -1893,10 +1934,13 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
free(objects);
strbuf_release(&index_name_buf);
strbuf_release(&rev_index_name_buf);
if (pack_name == NULL)
free((void *) curr_pack);
if (index_name == NULL)
free((void *) curr_index);
if (rev_index_name == NULL)
free((void *) curr_rev_index);
/*
* Let the caller know this pack is not self contained