Merge branch 'ps/object-store-midx-dedup-info'

Further code clean-up for multi-pack-index code paths.

* ps/object-store-midx-dedup-info:
  midx: compute paths via their source
  midx: stop duplicating info redundant with its owning source
  midx: write multi-pack indices via their source
  midx: load multi-pack indices via their source
  midx: drop redundant `struct repository` parameter
  odb: simplify calling `link_alt_odb_entry()`
  odb: return newly created in-memory sources
  odb: consistently use "dir" to refer to alternate's directory
  odb: allow `odb_find_source()` to fail
  odb: store locality in object database sources
This commit is contained in:
Junio C Hamano
2025-09-12 10:41:18 -07:00
15 changed files with 254 additions and 248 deletions

View File

@@ -102,7 +102,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix,
if (opts.progress) if (opts.progress)
flags |= COMMIT_GRAPH_WRITE_PROGRESS; flags |= COMMIT_GRAPH_WRITE_PROGRESS;
source = odb_find_source(the_repository->objects, opts.obj_dir); source = odb_find_source_or_die(the_repository->objects, opts.obj_dir);
graph_name = get_commit_graph_filename(source); graph_name = get_commit_graph_filename(source);
chain_name = get_commit_graph_chain_filename(source); chain_name = get_commit_graph_chain_filename(source);
if (open_commit_graph(graph_name, &fd, &st)) if (open_commit_graph(graph_name, &fd, &st))
@@ -291,7 +291,7 @@ static int graph_write(int argc, const char **argv, const char *prefix,
git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0)) git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0))
flags |= COMMIT_GRAPH_WRITE_BLOOM_FILTERS; flags |= COMMIT_GRAPH_WRITE_BLOOM_FILTERS;
source = odb_find_source(the_repository->objects, opts.obj_dir); source = odb_find_source_or_die(the_repository->objects, opts.obj_dir);
if (opts.reachable) { if (opts.reachable) {
if (write_commit_graph_reachable(source, flags, &write_opts)) if (write_commit_graph_reachable(source, flags, &write_opts))

View File

@@ -65,12 +65,20 @@ static int parse_object_dir(const struct option *opt, const char *arg,
char **value = opt->value; char **value = opt->value;
free(*value); free(*value);
if (unset) if (unset)
*value = xstrdup(repo_get_object_directory(the_repository)); *value = xstrdup(the_repository->objects->sources->path);
else else
*value = real_pathdup(arg, 1); *value = real_pathdup(arg, 1);
return 0; return 0;
} }
static struct odb_source *handle_object_dir_option(struct repository *repo)
{
struct odb_source *source = odb_find_source(repo->objects, opts.object_dir);
if (!source)
source = odb_add_to_alternates_memory(repo->objects, opts.object_dir);
return source;
}
static struct option common_opts[] = { static struct option common_opts[] = {
OPT_CALLBACK(0, "object-dir", &opts.object_dir, OPT_CALLBACK(0, "object-dir", &opts.object_dir,
N_("directory"), N_("directory"),
@@ -140,6 +148,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
N_("refs snapshot for selecting bitmap commits")), N_("refs snapshot for selecting bitmap commits")),
OPT_END(), OPT_END(),
}; };
struct odb_source *source;
int ret; int ret;
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
@@ -158,6 +167,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
if (argc) if (argc)
usage_with_options(builtin_multi_pack_index_write_usage, usage_with_options(builtin_multi_pack_index_write_usage,
options); options);
source = handle_object_dir_option(repo);
FREE_AND_NULL(options); FREE_AND_NULL(options);
@@ -166,7 +176,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
read_packs_from_stdin(&packs); read_packs_from_stdin(&packs);
ret = write_midx_file_only(repo, opts.object_dir, &packs, ret = write_midx_file_only(source, &packs,
opts.preferred_pack, opts.preferred_pack,
opts.refs_snapshot, opts.flags); opts.refs_snapshot, opts.flags);
@@ -177,7 +187,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
} }
ret = write_midx_file(repo, opts.object_dir, opts.preferred_pack, ret = write_midx_file(source, opts.preferred_pack,
opts.refs_snapshot, opts.flags); opts.refs_snapshot, opts.flags);
free(opts.refs_snapshot); free(opts.refs_snapshot);
@@ -194,6 +204,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
N_("force progress reporting"), MIDX_PROGRESS), N_("force progress reporting"), MIDX_PROGRESS),
OPT_END(), OPT_END(),
}; };
struct odb_source *source;
options = add_common_options(builtin_multi_pack_index_verify_options); options = add_common_options(builtin_multi_pack_index_verify_options);
trace2_cmd_mode(argv[0]); trace2_cmd_mode(argv[0]);
@@ -206,10 +218,11 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
if (argc) if (argc)
usage_with_options(builtin_multi_pack_index_verify_usage, usage_with_options(builtin_multi_pack_index_verify_usage,
options); options);
source = handle_object_dir_option(the_repository);
FREE_AND_NULL(options); FREE_AND_NULL(options);
return verify_midx_file(the_repository, opts.object_dir, opts.flags); return verify_midx_file(source, opts.flags);
} }
static int cmd_multi_pack_index_expire(int argc, const char **argv, static int cmd_multi_pack_index_expire(int argc, const char **argv,
@@ -222,6 +235,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,
N_("force progress reporting"), MIDX_PROGRESS), N_("force progress reporting"), MIDX_PROGRESS),
OPT_END(), OPT_END(),
}; };
struct odb_source *source;
options = add_common_options(builtin_multi_pack_index_expire_options); options = add_common_options(builtin_multi_pack_index_expire_options);
trace2_cmd_mode(argv[0]); trace2_cmd_mode(argv[0]);
@@ -234,10 +249,11 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,
if (argc) if (argc)
usage_with_options(builtin_multi_pack_index_expire_usage, usage_with_options(builtin_multi_pack_index_expire_usage,
options); options);
source = handle_object_dir_option(the_repository);
FREE_AND_NULL(options); FREE_AND_NULL(options);
return expire_midx_packs(the_repository, opts.object_dir, opts.flags); return expire_midx_packs(source, opts.flags);
} }
static int cmd_multi_pack_index_repack(int argc, const char **argv, static int cmd_multi_pack_index_repack(int argc, const char **argv,
@@ -252,6 +268,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,
N_("force progress reporting"), MIDX_PROGRESS), N_("force progress reporting"), MIDX_PROGRESS),
OPT_END(), OPT_END(),
}; };
struct odb_source *source;
options = add_common_options(builtin_multi_pack_index_repack_options); options = add_common_options(builtin_multi_pack_index_repack_options);
@@ -266,11 +283,11 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,
if (argc) if (argc)
usage_with_options(builtin_multi_pack_index_repack_usage, usage_with_options(builtin_multi_pack_index_repack_usage,
options); options);
source = handle_object_dir_option(the_repository);
FREE_AND_NULL(options); FREE_AND_NULL(options);
return midx_repack(the_repository, opts.object_dir, return midx_repack(source, (size_t)opts.batch_size, opts.flags);
(size_t)opts.batch_size, opts.flags);
} }
int cmd_multi_pack_index(int argc, int cmd_multi_pack_index(int argc,

View File

@@ -1741,7 +1741,7 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
struct multi_pack_index *m = get_multi_pack_index(source); struct multi_pack_index *m = get_multi_pack_index(source);
struct pack_entry e; struct pack_entry e;
if (m && fill_midx_entry(the_repository, oid, &e, m)) { if (m && fill_midx_entry(m, oid, &e)) {
want = want_object_in_pack_one(e.p, oid, exclude, found_pack, found_offset, found_mtime); want = want_object_in_pack_one(e.p, oid, exclude, found_pack, found_offset, found_mtime);
if (want != -1) if (want != -1)
return want; return want;

View File

@@ -223,9 +223,10 @@ static void mark_packs_for_deletion(struct existing_packs *existing,
static void remove_redundant_pack(const char *dir_name, const char *base_name) static void remove_redundant_pack(const char *dir_name, const char *base_name)
{ {
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
struct multi_pack_index *m = get_multi_pack_index(the_repository->objects->sources); struct odb_source *source = the_repository->objects->sources;
struct multi_pack_index *m = get_multi_pack_index(source);
strbuf_addf(&buf, "%s.pack", base_name); strbuf_addf(&buf, "%s.pack", base_name);
if (m && m->local && midx_contains_pack(m, buf.buf)) if (m && source->local && midx_contains_pack(m, buf.buf))
clear_midx_file(the_repository); clear_midx_file(the_repository);
strbuf_insertf(&buf, 0, "%s/", dir_name); strbuf_insertf(&buf, 0, "%s/", dir_name);
unlink_pack_path(buf.buf, 1); unlink_pack_path(buf.buf, 1);
@@ -1711,7 +1712,7 @@ int cmd_repack(int argc,
unsigned flags = 0; unsigned flags = 0;
if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0)) if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0))
flags |= MIDX_WRITE_INCREMENTAL; flags |= MIDX_WRITE_INCREMENTAL;
write_midx_file(the_repository, repo_get_object_directory(the_repository), write_midx_file(the_repository->objects->sources,
NULL, NULL, flags); NULL, NULL, flags);
} }

View File

@@ -26,9 +26,9 @@
#define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t)) #define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t))
extern int midx_checksum_valid(struct multi_pack_index *m); extern int midx_checksum_valid(struct multi_pack_index *m);
extern void clear_midx_files_ext(const char *object_dir, const char *ext, extern void clear_midx_files_ext(struct odb_source *source, const char *ext,
const char *keep_hash); const char *keep_hash);
extern void clear_incremental_midx_files_ext(const char *object_dir, extern void clear_incremental_midx_files_ext(struct odb_source *source,
const char *ext, const char *ext,
const char **keep_hashes, const char **keep_hashes,
uint32_t hashes_nr); uint32_t hashes_nr);
@@ -112,6 +112,7 @@ struct write_midx_context {
struct string_list *to_include; struct string_list *to_include;
struct repository *repo; struct repository *repo;
struct odb_source *source;
}; };
static int should_include_pack(const struct write_midx_context *ctx, static int should_include_pack(const struct write_midx_context *ctx,
@@ -648,7 +649,6 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx)
} }
static void write_midx_reverse_index(struct write_midx_context *ctx, static void write_midx_reverse_index(struct write_midx_context *ctx,
const char *object_dir,
unsigned char *midx_hash) unsigned char *midx_hash)
{ {
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
@@ -657,11 +657,10 @@ static void write_midx_reverse_index(struct write_midx_context *ctx,
trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo); trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo);
if (ctx->incremental) if (ctx->incremental)
get_split_midx_filename_ext(ctx->repo->hash_algo, &buf, get_split_midx_filename_ext(ctx->source, &buf,
object_dir, midx_hash, midx_hash, MIDX_EXT_REV);
MIDX_EXT_REV);
else else
get_midx_filename_ext(ctx->repo->hash_algo, &buf, object_dir, get_midx_filename_ext(ctx->source, &buf,
midx_hash, MIDX_EXT_REV); midx_hash, MIDX_EXT_REV);
tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order, tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order,
@@ -836,7 +835,6 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
} }
static int write_midx_bitmap(struct write_midx_context *ctx, static int write_midx_bitmap(struct write_midx_context *ctx,
const char *object_dir,
const unsigned char *midx_hash, const unsigned char *midx_hash,
struct packing_data *pdata, struct packing_data *pdata,
struct commit **commits, struct commit **commits,
@@ -852,12 +850,11 @@ static int write_midx_bitmap(struct write_midx_context *ctx,
trace2_region_enter("midx", "write_midx_bitmap", ctx->repo); trace2_region_enter("midx", "write_midx_bitmap", ctx->repo);
if (ctx->incremental) if (ctx->incremental)
get_split_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name, get_split_midx_filename_ext(ctx->source, &bitmap_name,
object_dir, midx_hash, midx_hash, MIDX_EXT_BITMAP);
MIDX_EXT_BITMAP);
else else
get_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name, get_midx_filename_ext(ctx->source, &bitmap_name,
object_dir, midx_hash, MIDX_EXT_BITMAP); midx_hash, MIDX_EXT_BITMAP);
if (flags & MIDX_WRITE_BITMAP_HASH_CACHE) if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
options |= BITMAP_OPT_HASH_CACHE; options |= BITMAP_OPT_HASH_CACHE;
@@ -913,13 +910,6 @@ cleanup:
return ret; return ret;
} }
static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
const char *object_dir)
{
struct odb_source *source = odb_find_source(r->objects, object_dir);
return get_multi_pack_index(source);
}
static int fill_packs_from_midx(struct write_midx_context *ctx, static int fill_packs_from_midx(struct write_midx_context *ctx,
const char *preferred_pack_name, uint32_t flags) const char *preferred_pack_name, uint32_t flags)
{ {
@@ -942,8 +932,7 @@ static int fill_packs_from_midx(struct write_midx_context *ctx,
*/ */
if (flags & MIDX_WRITE_REV_INDEX || if (flags & MIDX_WRITE_REV_INDEX ||
preferred_pack_name) { preferred_pack_name) {
if (prepare_midx_pack(ctx->repo, m, if (prepare_midx_pack(m, m->num_packs_in_base + i)) {
m->num_packs_in_base + i)) {
error(_("could not load pack")); error(_("could not load pack"));
return 1; return 1;
} }
@@ -989,10 +978,9 @@ static int link_midx_to_chain(struct multi_pack_index *m)
for (i = 0; i < ARRAY_SIZE(midx_exts); i++) { for (i = 0; i < ARRAY_SIZE(midx_exts); i++) {
const unsigned char *hash = get_midx_checksum(m); const unsigned char *hash = get_midx_checksum(m);
get_midx_filename_ext(m->repo->hash_algo, &from, m->object_dir, get_midx_filename_ext(m->source, &from,
hash, midx_exts[i].non_split); hash, midx_exts[i].non_split);
get_split_midx_filename_ext(m->repo->hash_algo, &to, get_split_midx_filename_ext(m->source, &to, hash,
m->object_dir, hash,
midx_exts[i].split); midx_exts[i].split);
if (link(from.buf, to.buf) < 0 && errno != ENOENT) { if (link(from.buf, to.buf) < 0 && errno != ENOENT) {
@@ -1011,7 +999,7 @@ done:
return ret; return ret;
} }
static void clear_midx_files(struct repository *r, const char *object_dir, static void clear_midx_files(struct odb_source *source,
const char **hashes, uint32_t hashes_nr, const char **hashes, uint32_t hashes_nr,
unsigned incremental) unsigned incremental)
{ {
@@ -1030,16 +1018,16 @@ static void clear_midx_files(struct repository *r, const char *object_dir,
uint32_t i, j; uint32_t i, j;
for (i = 0; i < ARRAY_SIZE(exts); i++) { for (i = 0; i < ARRAY_SIZE(exts); i++) {
clear_incremental_midx_files_ext(object_dir, exts[i], clear_incremental_midx_files_ext(source, exts[i],
hashes, hashes_nr); hashes, hashes_nr);
for (j = 0; j < hashes_nr; j++) for (j = 0; j < hashes_nr; j++)
clear_midx_files_ext(object_dir, exts[i], hashes[j]); clear_midx_files_ext(source, exts[i], hashes[j]);
} }
if (incremental) if (incremental)
get_midx_filename(r->hash_algo, &buf, object_dir); get_midx_filename(source, &buf);
else else
get_midx_chain_filename(&buf, object_dir); get_midx_chain_filename(source, &buf);
if (unlink(buf.buf) && errno != ENOENT) if (unlink(buf.buf) && errno != ENOENT)
die_errno(_("failed to clear multi-pack-index at %s"), buf.buf); die_errno(_("failed to clear multi-pack-index at %s"), buf.buf);
@@ -1047,13 +1035,14 @@ static void clear_midx_files(struct repository *r, const char *object_dir,
strbuf_release(&buf); strbuf_release(&buf);
} }
static int write_midx_internal(struct repository *r, const char *object_dir, static int write_midx_internal(struct odb_source *source,
struct string_list *packs_to_include, struct string_list *packs_to_include,
struct string_list *packs_to_drop, struct string_list *packs_to_drop,
const char *preferred_pack_name, const char *preferred_pack_name,
const char *refs_snapshot, const char *refs_snapshot,
unsigned flags) unsigned flags)
{ {
struct repository *r = source->odb->repo;
struct strbuf midx_name = STRBUF_INIT; struct strbuf midx_name = STRBUF_INIT;
unsigned char midx_hash[GIT_MAX_RAWSZ]; unsigned char midx_hash[GIT_MAX_RAWSZ];
uint32_t i, start_pack; uint32_t i, start_pack;
@@ -1071,21 +1060,22 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
trace2_region_enter("midx", "write_midx_internal", r); trace2_region_enter("midx", "write_midx_internal", r);
ctx.repo = r; ctx.repo = r;
ctx.source = source;
ctx.incremental = !!(flags & MIDX_WRITE_INCREMENTAL); ctx.incremental = !!(flags & MIDX_WRITE_INCREMENTAL);
if (ctx.incremental) if (ctx.incremental)
strbuf_addf(&midx_name, strbuf_addf(&midx_name,
"%s/pack/multi-pack-index.d/tmp_midx_XXXXXX", "%s/pack/multi-pack-index.d/tmp_midx_XXXXXX",
object_dir); source->path);
else else
get_midx_filename(r->hash_algo, &midx_name, object_dir); get_midx_filename(source, &midx_name);
if (safe_create_leading_directories(r, midx_name.buf)) if (safe_create_leading_directories(r, midx_name.buf))
die_errno(_("unable to create leading directories of %s"), die_errno(_("unable to create leading directories of %s"),
midx_name.buf); midx_name.buf);
if (!packs_to_include || ctx.incremental) { if (!packs_to_include || ctx.incremental) {
struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); struct multi_pack_index *m = get_multi_pack_index(source);
if (m && !midx_checksum_valid(m)) { if (m && !midx_checksum_valid(m)) {
warning(_("ignoring existing multi-pack-index; checksum mismatch")); warning(_("ignoring existing multi-pack-index; checksum mismatch"));
m = NULL; m = NULL;
@@ -1116,7 +1106,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (flags & MIDX_WRITE_BITMAP && load_midx_revindex(m)) { if (flags & MIDX_WRITE_BITMAP && load_midx_revindex(m)) {
error(_("could not load reverse index for MIDX %s"), error(_("could not load reverse index for MIDX %s"),
hash_to_hex_algop(get_midx_checksum(m), hash_to_hex_algop(get_midx_checksum(m),
m->repo->hash_algo)); m->source->odb->repo->hash_algo));
result = 1; result = 1;
goto cleanup; goto cleanup;
} }
@@ -1139,7 +1129,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
ctx.to_include = packs_to_include; ctx.to_include = packs_to_include;
for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &ctx); for_each_file_in_pack_dir(source->path, add_pack_to_midx, &ctx);
stop_progress(&ctx.progress); stop_progress(&ctx.progress);
if ((ctx.m && ctx.nr == ctx.m->num_packs + ctx.m->num_packs_in_base) && if ((ctx.m && ctx.nr == ctx.m->num_packs + ctx.m->num_packs_in_base) &&
@@ -1159,7 +1149,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
* corresponding bitmap (or one wasn't requested). * corresponding bitmap (or one wasn't requested).
*/ */
if (!want_bitmap) if (!want_bitmap)
clear_midx_files_ext(object_dir, "bitmap", NULL); clear_midx_files_ext(source, "bitmap", NULL);
goto cleanup; goto cleanup;
} }
} }
@@ -1327,7 +1317,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (ctx.incremental) { if (ctx.incremental) {
struct strbuf lock_name = STRBUF_INIT; struct strbuf lock_name = STRBUF_INIT;
get_midx_chain_filename(&lock_name, object_dir); get_midx_chain_filename(source, &lock_name);
hold_lock_file_for_update(&lk, lock_name.buf, LOCK_DIE_ON_ERROR); hold_lock_file_for_update(&lk, lock_name.buf, LOCK_DIE_ON_ERROR);
strbuf_release(&lock_name); strbuf_release(&lock_name);
@@ -1390,7 +1380,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (flags & MIDX_WRITE_REV_INDEX && if (flags & MIDX_WRITE_REV_INDEX &&
git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0)) git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
write_midx_reverse_index(&ctx, object_dir, midx_hash); write_midx_reverse_index(&ctx, midx_hash);
if (flags & MIDX_WRITE_BITMAP) { if (flags & MIDX_WRITE_BITMAP) {
struct packing_data pdata; struct packing_data pdata;
@@ -1413,7 +1403,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
FREE_AND_NULL(ctx.entries); FREE_AND_NULL(ctx.entries);
ctx.entries_nr = 0; ctx.entries_nr = 0;
if (write_midx_bitmap(&ctx, object_dir, if (write_midx_bitmap(&ctx,
midx_hash, &pdata, commits, commits_nr, midx_hash, &pdata, commits, commits_nr,
flags) < 0) { flags) < 0) {
error(_("could not write multi-pack bitmap")); error(_("could not write multi-pack bitmap"));
@@ -1446,8 +1436,8 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (link_midx_to_chain(ctx.base_midx) < 0) if (link_midx_to_chain(ctx.base_midx) < 0)
return -1; return -1;
get_split_midx_filename_ext(r->hash_algo, &final_midx_name, get_split_midx_filename_ext(source, &final_midx_name,
object_dir, midx_hash, MIDX_EXT_MIDX); midx_hash, MIDX_EXT_MIDX);
if (rename_tempfile(&incr, final_midx_name.buf) < 0) { if (rename_tempfile(&incr, final_midx_name.buf) < 0) {
error_errno(_("unable to rename new multi-pack-index layer")); error_errno(_("unable to rename new multi-pack-index layer"));
@@ -1480,7 +1470,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (commit_lock_file(&lk) < 0) if (commit_lock_file(&lk) < 0)
die_errno(_("could not write multi-pack-index")); die_errno(_("could not write multi-pack-index"));
clear_midx_files(r, object_dir, keep_hashes, clear_midx_files(source, keep_hashes,
ctx.num_multi_pack_indexes_before + 1, ctx.num_multi_pack_indexes_before + 1,
ctx.incremental); ctx.incremental);
@@ -1509,29 +1499,29 @@ cleanup:
return result; return result;
} }
int write_midx_file(struct repository *r, const char *object_dir, int write_midx_file(struct odb_source *source,
const char *preferred_pack_name, const char *preferred_pack_name,
const char *refs_snapshot, unsigned flags) const char *refs_snapshot, unsigned flags)
{ {
return write_midx_internal(r, object_dir, NULL, NULL, return write_midx_internal(source, NULL, NULL,
preferred_pack_name, refs_snapshot, preferred_pack_name, refs_snapshot,
flags); flags);
} }
int write_midx_file_only(struct repository *r, const char *object_dir, int write_midx_file_only(struct odb_source *source,
struct string_list *packs_to_include, struct string_list *packs_to_include,
const char *preferred_pack_name, const char *preferred_pack_name,
const char *refs_snapshot, unsigned flags) const char *refs_snapshot, unsigned flags)
{ {
return write_midx_internal(r, object_dir, packs_to_include, NULL, return write_midx_internal(source, packs_to_include, NULL,
preferred_pack_name, refs_snapshot, flags); preferred_pack_name, refs_snapshot, flags);
} }
int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags) int expire_midx_packs(struct odb_source *source, unsigned flags)
{ {
uint32_t i, *count, result = 0; uint32_t i, *count, result = 0;
struct string_list packs_to_drop = STRING_LIST_INIT_DUP; struct string_list packs_to_drop = STRING_LIST_INIT_DUP;
struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); struct multi_pack_index *m = get_multi_pack_index(source);
struct progress *progress = NULL; struct progress *progress = NULL;
if (!m) if (!m)
@@ -1544,7 +1534,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
if (flags & MIDX_PROGRESS) if (flags & MIDX_PROGRESS)
progress = start_delayed_progress( progress = start_delayed_progress(
r, source->odb->repo,
_("Counting referenced objects"), _("Counting referenced objects"),
m->num_objects); m->num_objects);
for (i = 0; i < m->num_objects; i++) { for (i = 0; i < m->num_objects; i++) {
@@ -1556,7 +1546,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
if (flags & MIDX_PROGRESS) if (flags & MIDX_PROGRESS)
progress = start_delayed_progress( progress = start_delayed_progress(
r, source->odb->repo,
_("Finding and deleting unreferenced packfiles"), _("Finding and deleting unreferenced packfiles"),
m->num_packs); m->num_packs);
for (i = 0; i < m->num_packs; i++) { for (i = 0; i < m->num_packs; i++) {
@@ -1566,7 +1556,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
if (count[i]) if (count[i])
continue; continue;
if (prepare_midx_pack(r, m, i)) if (prepare_midx_pack(m, i))
continue; continue;
if (m->packs[i]->pack_keep || m->packs[i]->is_cruft) if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
@@ -1584,7 +1574,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
free(count); free(count);
if (packs_to_drop.nr) if (packs_to_drop.nr)
result = write_midx_internal(r, object_dir, NULL, result = write_midx_internal(source, NULL,
&packs_to_drop, NULL, NULL, flags); &packs_to_drop, NULL, NULL, flags);
string_list_clear(&packs_to_drop, 0); string_list_clear(&packs_to_drop, 0);
@@ -1612,13 +1602,12 @@ static int compare_by_mtime(const void *a_, const void *b_)
return 0; return 0;
} }
static int want_included_pack(struct repository *r, static int want_included_pack(struct multi_pack_index *m,
struct multi_pack_index *m,
int pack_kept_objects, int pack_kept_objects,
uint32_t pack_int_id) uint32_t pack_int_id)
{ {
struct packed_git *p; struct packed_git *p;
if (prepare_midx_pack(r, m, pack_int_id)) if (prepare_midx_pack(m, pack_int_id))
return 0; return 0;
p = m->packs[pack_int_id]; p = m->packs[pack_int_id];
if (!pack_kept_objects && p->pack_keep) if (!pack_kept_objects && p->pack_keep)
@@ -1640,7 +1629,7 @@ static void fill_included_packs_all(struct repository *r,
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects); repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
for (i = 0; i < m->num_packs; i++) { for (i = 0; i < m->num_packs; i++) {
if (!want_included_pack(r, m, pack_kept_objects, i)) if (!want_included_pack(m, pack_kept_objects, i))
continue; continue;
include_pack[i] = 1; include_pack[i] = 1;
@@ -1664,7 +1653,7 @@ static void fill_included_packs_batch(struct repository *r,
for (i = 0; i < m->num_packs; i++) { for (i = 0; i < m->num_packs; i++) {
pack_info[i].pack_int_id = i; pack_info[i].pack_int_id = i;
if (prepare_midx_pack(r, m, i)) if (prepare_midx_pack(m, i))
continue; continue;
pack_info[i].mtime = m->packs[i]->mtime; pack_info[i].mtime = m->packs[i]->mtime;
@@ -1683,7 +1672,7 @@ static void fill_included_packs_batch(struct repository *r,
struct packed_git *p = m->packs[pack_int_id]; struct packed_git *p = m->packs[pack_int_id];
uint64_t expected_size; uint64_t expected_size;
if (!want_included_pack(r, m, pack_kept_objects, pack_int_id)) if (!want_included_pack(m, pack_kept_objects, pack_int_id))
continue; continue;
/* /*
@@ -1710,14 +1699,15 @@ static void fill_included_packs_batch(struct repository *r,
free(pack_info); free(pack_info);
} }
int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags) int midx_repack(struct odb_source *source, size_t batch_size, unsigned flags)
{ {
struct repository *r = source->odb->repo;
int result = 0; int result = 0;
uint32_t i, packs_to_repack = 0; uint32_t i, packs_to_repack = 0;
unsigned char *include_pack; unsigned char *include_pack;
struct child_process cmd = CHILD_PROCESS_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
FILE *cmd_in; FILE *cmd_in;
struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); struct multi_pack_index *m = get_multi_pack_index(source);
/* /*
* When updating the default for these configuration * When updating the default for these configuration
@@ -1751,7 +1741,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
strvec_push(&cmd.args, "pack-objects"); strvec_push(&cmd.args, "pack-objects");
strvec_pushf(&cmd.args, "%s/pack/pack", object_dir); strvec_pushf(&cmd.args, "%s/pack/pack", source->path);
if (delta_base_offset) if (delta_base_offset)
strvec_push(&cmd.args, "--delta-base-offset"); strvec_push(&cmd.args, "--delta-base-offset");
@@ -1792,7 +1782,7 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size,
goto cleanup; goto cleanup;
} }
result = write_midx_internal(r, object_dir, NULL, NULL, NULL, NULL, result = write_midx_internal(source, NULL, NULL, NULL, NULL,
flags); flags);
cleanup: cleanup:

135
midx.c
View File

@@ -16,9 +16,9 @@
#define MIDX_PACK_ERROR ((void *)(intptr_t)-1) #define MIDX_PACK_ERROR ((void *)(intptr_t)-1)
int midx_checksum_valid(struct multi_pack_index *m); int midx_checksum_valid(struct multi_pack_index *m);
void clear_midx_files_ext(const char *object_dir, const char *ext, void clear_midx_files_ext(struct odb_source *source, const char *ext,
const char *keep_hash); const char *keep_hash);
void clear_incremental_midx_files_ext(const char *object_dir, const char *ext, void clear_incremental_midx_files_ext(struct odb_source *source, const char *ext,
char **keep_hashes, char **keep_hashes,
uint32_t hashes_nr); uint32_t hashes_nr);
int cmp_idx_or_pack_name(const char *idx_or_pack_name, int cmp_idx_or_pack_name(const char *idx_or_pack_name,
@@ -26,22 +26,20 @@ int cmp_idx_or_pack_name(const char *idx_or_pack_name,
const unsigned char *get_midx_checksum(struct multi_pack_index *m) const unsigned char *get_midx_checksum(struct multi_pack_index *m)
{ {
return m->data + m->data_len - m->repo->hash_algo->rawsz; return m->data + m->data_len - m->source->odb->repo->hash_algo->rawsz;
} }
void get_midx_filename(const struct git_hash_algo *hash_algo, void get_midx_filename(struct odb_source *source, struct strbuf *out)
struct strbuf *out, const char *object_dir)
{ {
get_midx_filename_ext(hash_algo, out, object_dir, NULL, NULL); get_midx_filename_ext(source, out, NULL, NULL);
} }
void get_midx_filename_ext(const struct git_hash_algo *hash_algo, void get_midx_filename_ext(struct odb_source *source, struct strbuf *out,
struct strbuf *out, const char *object_dir,
const unsigned char *hash, const char *ext) const unsigned char *hash, const char *ext)
{ {
strbuf_addf(out, "%s/pack/multi-pack-index", object_dir); strbuf_addf(out, "%s/pack/multi-pack-index", source->path);
if (ext) if (ext)
strbuf_addf(out, "-%s.%s", hash_to_hex_algop(hash, hash_algo), ext); strbuf_addf(out, "-%s.%s", hash_to_hex_algop(hash, source->odb->repo->hash_algo), ext);
} }
static int midx_read_oid_fanout(const unsigned char *chunk_start, static int midx_read_oid_fanout(const unsigned char *chunk_start,
@@ -95,11 +93,10 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
return 0; return 0;
} }
static struct multi_pack_index *load_multi_pack_index_one(struct repository *r, static struct multi_pack_index *load_multi_pack_index_one(struct odb_source *source,
const char *object_dir, const char *midx_name)
const char *midx_name,
int local)
{ {
struct repository *r = source->odb->repo;
struct multi_pack_index *m = NULL; struct multi_pack_index *m = NULL;
int fd; int fd;
struct stat st; struct stat st;
@@ -129,11 +126,10 @@ static struct multi_pack_index *load_multi_pack_index_one(struct repository *r,
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0); midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd); close(fd);
FLEX_ALLOC_STR(m, object_dir, object_dir); CALLOC_ARRAY(m, 1);
m->data = midx_map; m->data = midx_map;
m->data_len = midx_size; m->data_len = midx_size;
m->local = local; m->source = source;
m->repo = r;
m->signature = get_be32(m->data); m->signature = get_be32(m->data);
if (m->signature != MIDX_SIGNATURE) if (m->signature != MIDX_SIGNATURE)
@@ -224,24 +220,23 @@ cleanup_fail:
return NULL; return NULL;
} }
void get_midx_chain_dirname(struct strbuf *buf, const char *object_dir) void get_midx_chain_dirname(struct odb_source *source, struct strbuf *buf)
{ {
strbuf_addf(buf, "%s/pack/multi-pack-index.d", object_dir); strbuf_addf(buf, "%s/pack/multi-pack-index.d", source->path);
} }
void get_midx_chain_filename(struct strbuf *buf, const char *object_dir) void get_midx_chain_filename(struct odb_source *source, struct strbuf *buf)
{ {
get_midx_chain_dirname(buf, object_dir); get_midx_chain_dirname(source, buf);
strbuf_addstr(buf, "/multi-pack-index-chain"); strbuf_addstr(buf, "/multi-pack-index-chain");
} }
void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo, void get_split_midx_filename_ext(struct odb_source *source, struct strbuf *buf,
struct strbuf *buf, const char *object_dir,
const unsigned char *hash, const char *ext) const unsigned char *hash, const char *ext)
{ {
get_midx_chain_dirname(buf, object_dir); get_midx_chain_dirname(source, buf);
strbuf_addf(buf, "/multi-pack-index-%s.%s", strbuf_addf(buf, "/multi-pack-index-%s.%s",
hash_to_hex_algop(hash, hash_algo), ext); hash_to_hex_algop(hash, source->odb->repo->hash_algo), ext);
} }
static int open_multi_pack_index_chain(const struct git_hash_algo *hash_algo, static int open_multi_pack_index_chain(const struct git_hash_algo *hash_algo,
@@ -297,19 +292,18 @@ static int add_midx_to_chain(struct multi_pack_index *midx,
return 1; return 1;
} }
static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r, static struct multi_pack_index *load_midx_chain_fd_st(struct odb_source *source,
const char *object_dir,
int local,
int fd, struct stat *st, int fd, struct stat *st,
int *incomplete_chain) int *incomplete_chain)
{ {
const struct git_hash_algo *hash_algo = source->odb->repo->hash_algo;
struct multi_pack_index *midx_chain = NULL; struct multi_pack_index *midx_chain = NULL;
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
int valid = 1; int valid = 1;
uint32_t i, count; uint32_t i, count;
FILE *fp = xfdopen(fd, "r"); FILE *fp = xfdopen(fd, "r");
count = st->st_size / (r->hash_algo->hexsz + 1); count = st->st_size / (hash_algo->hexsz + 1);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
struct multi_pack_index *m; struct multi_pack_index *m;
@@ -318,7 +312,7 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
if (strbuf_getline_lf(&buf, fp) == EOF) if (strbuf_getline_lf(&buf, fp) == EOF)
break; break;
if (get_oid_hex_algop(buf.buf, &layer, r->hash_algo)) { if (get_oid_hex_algop(buf.buf, &layer, hash_algo)) {
warning(_("invalid multi-pack-index chain: line '%s' " warning(_("invalid multi-pack-index chain: line '%s' "
"not a hash"), "not a hash"),
buf.buf); buf.buf);
@@ -329,9 +323,9 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
valid = 0; valid = 0;
strbuf_reset(&buf); strbuf_reset(&buf);
get_split_midx_filename_ext(r->hash_algo, &buf, object_dir, get_split_midx_filename_ext(source, &buf,
layer.hash, MIDX_EXT_MIDX); layer.hash, MIDX_EXT_MIDX);
m = load_multi_pack_index_one(r, object_dir, buf.buf, local); m = load_multi_pack_index_one(source, buf.buf);
if (m) { if (m) {
if (add_midx_to_chain(m, midx_chain)) { if (add_midx_to_chain(m, midx_chain)) {
@@ -354,40 +348,34 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
return midx_chain; return midx_chain;
} }
static struct multi_pack_index *load_multi_pack_index_chain(struct repository *r, static struct multi_pack_index *load_multi_pack_index_chain(struct odb_source *source)
const char *object_dir,
int local)
{ {
struct strbuf chain_file = STRBUF_INIT; struct strbuf chain_file = STRBUF_INIT;
struct stat st; struct stat st;
int fd; int fd;
struct multi_pack_index *m = NULL; struct multi_pack_index *m = NULL;
get_midx_chain_filename(&chain_file, object_dir); get_midx_chain_filename(source, &chain_file);
if (open_multi_pack_index_chain(r->hash_algo, chain_file.buf, &fd, &st)) { if (open_multi_pack_index_chain(source->odb->repo->hash_algo, chain_file.buf, &fd, &st)) {
int incomplete; int incomplete;
/* ownership of fd is taken over by load function */ /* ownership of fd is taken over by load function */
m = load_midx_chain_fd_st(r, object_dir, local, fd, &st, m = load_midx_chain_fd_st(source, fd, &st, &incomplete);
&incomplete);
} }
strbuf_release(&chain_file); strbuf_release(&chain_file);
return m; return m;
} }
struct multi_pack_index *load_multi_pack_index(struct repository *r, struct multi_pack_index *load_multi_pack_index(struct odb_source *source)
const char *object_dir,
int local)
{ {
struct strbuf midx_name = STRBUF_INIT; struct strbuf midx_name = STRBUF_INIT;
struct multi_pack_index *m; struct multi_pack_index *m;
get_midx_filename(r->hash_algo, &midx_name, object_dir); get_midx_filename(source, &midx_name);
m = load_multi_pack_index_one(r, object_dir, m = load_multi_pack_index_one(source, midx_name.buf);
midx_name.buf, local);
if (!m) if (!m)
m = load_multi_pack_index_chain(r, object_dir, local); m = load_multi_pack_index_chain(source);
strbuf_release(&midx_name); strbuf_release(&midx_name);
@@ -450,9 +438,10 @@ static uint32_t midx_for_pack(struct multi_pack_index **_m,
return pack_int_id - m->num_packs_in_base; return pack_int_id - m->num_packs_in_base;
} }
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, int prepare_midx_pack(struct multi_pack_index *m,
uint32_t pack_int_id) uint32_t pack_int_id)
{ {
struct repository *r = m->source->odb->repo;
struct strbuf pack_name = STRBUF_INIT; struct strbuf pack_name = STRBUF_INIT;
struct strbuf key = STRBUF_INIT; struct strbuf key = STRBUF_INIT;
struct packed_git *p; struct packed_git *p;
@@ -464,7 +453,7 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
if (m->packs[pack_int_id]) if (m->packs[pack_int_id])
return 0; return 0;
strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir, strbuf_addf(&pack_name, "%s/pack/%s", m->source->path,
m->pack_names[pack_int_id]); m->pack_names[pack_int_id]);
/* pack_map holds the ".pack" name, but we have the .idx */ /* pack_map holds the ".pack" name, but we have the .idx */
@@ -475,7 +464,8 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
strhash(key.buf), key.buf, strhash(key.buf), key.buf,
struct packed_git, packmap_ent); struct packed_git, packmap_ent);
if (!p) { if (!p) {
p = add_packed_git(r, pack_name.buf, pack_name.len, m->local); p = add_packed_git(r, pack_name.buf, pack_name.len,
m->source->local);
if (p) { if (p) {
install_packed_git(r, p); install_packed_git(r, p);
list_add_tail(&p->mru, &r->objects->packed_git_mru); list_add_tail(&p->mru, &r->objects->packed_git_mru);
@@ -507,7 +497,7 @@ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
#define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t)) #define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t))
int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m, int nth_bitmapped_pack(struct multi_pack_index *m,
struct bitmapped_pack *bp, uint32_t pack_int_id) struct bitmapped_pack *bp, uint32_t pack_int_id)
{ {
uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id); uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
@@ -515,7 +505,7 @@ int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
if (!m->chunk_bitmapped_packs) if (!m->chunk_bitmapped_packs)
return error(_("MIDX does not contain the BTMP chunk")); return error(_("MIDX does not contain the BTMP chunk"));
if (prepare_midx_pack(r, m, pack_int_id)) if (prepare_midx_pack(m, pack_int_id))
return error(_("could not load bitmapped pack %"PRIu32), pack_int_id); return error(_("could not load bitmapped pack %"PRIu32), pack_int_id);
bp->p = m->packs[local_pack_int_id]; bp->p = m->packs[local_pack_int_id];
@@ -534,7 +524,8 @@ int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m,
uint32_t *result) uint32_t *result)
{ {
int ret = bsearch_hash(oid->hash, m->chunk_oid_fanout, int ret = bsearch_hash(oid->hash, m->chunk_oid_fanout,
m->chunk_oid_lookup, m->repo->hash_algo->rawsz, m->chunk_oid_lookup,
m->source->odb->repo->hash_algo->rawsz,
result); result);
if (result) if (result)
*result += m->num_objects_in_base; *result += m->num_objects_in_base;
@@ -565,7 +556,7 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid,
n = midx_for_object(&m, n); n = midx_for_object(&m, n);
oidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n), oidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n),
m->repo->hash_algo); m->source->odb->repo->hash_algo);
return oid; return oid;
} }
@@ -600,10 +591,9 @@ uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos)
(off_t)pos * MIDX_CHUNK_OFFSET_WIDTH); (off_t)pos * MIDX_CHUNK_OFFSET_WIDTH);
} }
int fill_midx_entry(struct repository *r, int fill_midx_entry(struct multi_pack_index *m,
const struct object_id *oid, const struct object_id *oid,
struct pack_entry *e, struct pack_entry *e)
struct multi_pack_index *m)
{ {
uint32_t pos; uint32_t pos;
uint32_t pack_int_id; uint32_t pack_int_id;
@@ -615,7 +605,7 @@ int fill_midx_entry(struct repository *r,
midx_for_object(&m, pos); midx_for_object(&m, pos);
pack_int_id = nth_midxed_pack_int_id(m, pos); pack_int_id = nth_midxed_pack_int_id(m, pos);
if (prepare_midx_pack(r, m, pack_int_id)) if (prepare_midx_pack(m, pack_int_id))
return 0; return 0;
p = m->packs[pack_int_id - m->num_packs_in_base]; p = m->packs[pack_int_id - m->num_packs_in_base];
@@ -723,7 +713,7 @@ int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id)
return 0; return 0;
} }
int prepare_multi_pack_index_one(struct odb_source *source, int local) int prepare_multi_pack_index_one(struct odb_source *source)
{ {
struct repository *r = source->odb->repo; struct repository *r = source->odb->repo;
@@ -734,14 +724,14 @@ int prepare_multi_pack_index_one(struct odb_source *source, int local)
if (source->midx) if (source->midx)
return 1; return 1;
source->midx = load_multi_pack_index(r, source->path, local); source->midx = load_multi_pack_index(source);
return !!source->midx; return !!source->midx;
} }
int midx_checksum_valid(struct multi_pack_index *m) int midx_checksum_valid(struct multi_pack_index *m)
{ {
return hashfile_checksum_valid(m->repo->hash_algo, return hashfile_checksum_valid(m->source->odb->repo->hash_algo,
m->data, m->data_len); m->data, m->data_len);
} }
@@ -768,7 +758,7 @@ static void clear_midx_file_ext(const char *full_path, size_t full_path_len UNUS
die_errno(_("failed to remove %s"), full_path); die_errno(_("failed to remove %s"), full_path);
} }
void clear_midx_files_ext(const char *object_dir, const char *ext, void clear_midx_files_ext(struct odb_source *source, const char *ext,
const char *keep_hash) const char *keep_hash)
{ {
struct clear_midx_data data; struct clear_midx_data data;
@@ -782,7 +772,7 @@ void clear_midx_files_ext(const char *object_dir, const char *ext,
} }
data.ext = ext; data.ext = ext;
for_each_file_in_pack_dir(object_dir, for_each_file_in_pack_dir(source->path,
clear_midx_file_ext, clear_midx_file_ext,
&data); &data);
@@ -791,7 +781,7 @@ void clear_midx_files_ext(const char *object_dir, const char *ext,
free(data.keep); free(data.keep);
} }
void clear_incremental_midx_files_ext(const char *object_dir, const char *ext, void clear_incremental_midx_files_ext(struct odb_source *source, const char *ext,
char **keep_hashes, char **keep_hashes,
uint32_t hashes_nr) uint32_t hashes_nr)
{ {
@@ -807,7 +797,7 @@ void clear_incremental_midx_files_ext(const char *object_dir, const char *ext,
data.keep_nr = hashes_nr; data.keep_nr = hashes_nr;
data.ext = ext; data.ext = ext;
for_each_file_in_pack_subdir(object_dir, "multi-pack-index.d", for_each_file_in_pack_subdir(source->path, "multi-pack-index.d",
clear_midx_file_ext, &data); clear_midx_file_ext, &data);
for (i = 0; i < hashes_nr; i++) for (i = 0; i < hashes_nr; i++)
@@ -819,7 +809,7 @@ void clear_midx_file(struct repository *r)
{ {
struct strbuf midx = STRBUF_INIT; struct strbuf midx = STRBUF_INIT;
get_midx_filename(r->hash_algo, &midx, r->objects->sources->path); get_midx_filename(r->objects->sources, &midx);
if (r->objects) { if (r->objects) {
struct odb_source *source; struct odb_source *source;
@@ -834,8 +824,8 @@ void clear_midx_file(struct repository *r)
if (remove_path(midx.buf)) if (remove_path(midx.buf))
die(_("failed to clear multi-pack-index at %s"), midx.buf); die(_("failed to clear multi-pack-index at %s"), midx.buf);
clear_midx_files_ext(r->objects->sources->path, MIDX_EXT_BITMAP, NULL); clear_midx_files_ext(r->objects->sources, MIDX_EXT_BITMAP, NULL);
clear_midx_files_ext(r->objects->sources->path, MIDX_EXT_REV, NULL); clear_midx_files_ext(r->objects->sources, MIDX_EXT_REV, NULL);
strbuf_release(&midx); strbuf_release(&midx);
} }
@@ -879,12 +869,13 @@ static int compare_pair_pos_vs_id(const void *_a, const void *_b)
display_progress(progress, _n); \ display_progress(progress, _n); \
} while (0) } while (0)
int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags) int verify_midx_file(struct odb_source *source, unsigned flags)
{ {
struct repository *r = source->odb->repo;
struct pair_pos_vs_id *pairs = NULL; struct pair_pos_vs_id *pairs = NULL;
uint32_t i; uint32_t i;
struct progress *progress = NULL; struct progress *progress = NULL;
struct multi_pack_index *m = load_multi_pack_index(r, object_dir, 1); struct multi_pack_index *m = load_multi_pack_index(source);
struct multi_pack_index *curr; struct multi_pack_index *curr;
verify_midx_error = 0; verify_midx_error = 0;
@@ -893,7 +884,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
struct stat sb; struct stat sb;
struct strbuf filename = STRBUF_INIT; struct strbuf filename = STRBUF_INIT;
get_midx_filename(r->hash_algo, &filename, object_dir); get_midx_filename(source, &filename);
if (!stat(filename.buf, &sb)) { if (!stat(filename.buf, &sb)) {
error(_("multi-pack-index file exists, but failed to parse")); error(_("multi-pack-index file exists, but failed to parse"));
@@ -911,7 +902,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
_("Looking for referenced packfiles"), _("Looking for referenced packfiles"),
m->num_packs + m->num_packs_in_base); m->num_packs + m->num_packs_in_base);
for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) { for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
if (prepare_midx_pack(r, m, i)) if (prepare_midx_pack(m, i))
midx_report("failed to load pack in position %d", i); midx_report("failed to load pack in position %d", i);
display_progress(progress, i + 1); display_progress(progress, i + 1);
@@ -988,7 +979,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
nth_midxed_object_oid(&oid, m, pairs[i].pos); nth_midxed_object_oid(&oid, m, pairs[i].pos);
if (!fill_midx_entry(r, &oid, &e, m)) { if (!fill_midx_entry(m, &oid, &e)) {
midx_report(_("failed to load pack entry for oid[%d] = %s"), midx_report(_("failed to load pack entry for oid[%d] = %s"),
pairs[i].pos, oid_to_hex(&oid)); pairs[i].pos, oid_to_hex(&oid));
continue; continue;

42
midx.h
View File

@@ -35,6 +35,8 @@ struct odb_source;
"GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL" "GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL"
struct multi_pack_index { struct multi_pack_index {
struct odb_source *source;
const unsigned char *data; const unsigned char *data;
size_t data_len; size_t data_len;
@@ -50,7 +52,6 @@ struct multi_pack_index {
uint32_t num_objects; uint32_t num_objects;
int preferred_pack_idx; int preferred_pack_idx;
int local;
int has_chain; int has_chain;
const unsigned char *chunk_pack_names; const unsigned char *chunk_pack_names;
@@ -71,10 +72,6 @@ struct multi_pack_index {
const char **pack_names; const char **pack_names;
struct packed_git **packs; struct packed_git **packs;
struct repository *repo;
char object_dir[FLEX_ARRAY];
}; };
#define MIDX_PROGRESS (1 << 0) #define MIDX_PROGRESS (1 << 0)
@@ -89,24 +86,19 @@ struct multi_pack_index {
#define MIDX_EXT_MIDX "midx" #define MIDX_EXT_MIDX "midx"
const unsigned char *get_midx_checksum(struct multi_pack_index *m); const unsigned char *get_midx_checksum(struct multi_pack_index *m);
void get_midx_filename(const struct git_hash_algo *hash_algo, void get_midx_filename(struct odb_source *source, struct strbuf *out);
struct strbuf *out, const char *object_dir); void get_midx_filename_ext(struct odb_source *source, struct strbuf *out,
void get_midx_filename_ext(const struct git_hash_algo *hash_algo,
struct strbuf *out, const char *object_dir,
const unsigned char *hash, const char *ext); const unsigned char *hash, const char *ext);
void get_midx_chain_dirname(struct strbuf *buf, const char *object_dir); void get_midx_chain_dirname(struct odb_source *source, struct strbuf *out);
void get_midx_chain_filename(struct strbuf *buf, const char *object_dir); void get_midx_chain_filename(struct odb_source *source, struct strbuf *out);
void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo, void get_split_midx_filename_ext(struct odb_source *source, struct strbuf *buf,
struct strbuf *buf, const char *object_dir,
const unsigned char *hash, const char *ext); const unsigned char *hash, const char *ext);
struct multi_pack_index *load_multi_pack_index(struct repository *r, struct multi_pack_index *load_multi_pack_index(struct odb_source *source);
const char *object_dir, int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id);
int local);
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
struct packed_git *nth_midxed_pack(struct multi_pack_index *m, struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
uint32_t pack_int_id); uint32_t pack_int_id);
int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m, int nth_bitmapped_pack(struct multi_pack_index *m,
struct bitmapped_pack *bp, uint32_t pack_int_id); struct bitmapped_pack *bp, uint32_t pack_int_id);
int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m, int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m,
uint32_t *result); uint32_t *result);
@@ -118,27 +110,27 @@ uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos);
struct object_id *nth_midxed_object_oid(struct object_id *oid, struct object_id *nth_midxed_object_oid(struct object_id *oid,
struct multi_pack_index *m, struct multi_pack_index *m,
uint32_t n); uint32_t n);
int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m); int fill_midx_entry(struct multi_pack_index *m, const struct object_id *oid, struct pack_entry *e);
int midx_contains_pack(struct multi_pack_index *m, int midx_contains_pack(struct multi_pack_index *m,
const char *idx_or_pack_name); const char *idx_or_pack_name);
int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id); int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id);
int prepare_multi_pack_index_one(struct odb_source *source, int local); int prepare_multi_pack_index_one(struct odb_source *source);
/* /*
* Variant of write_midx_file which writes a MIDX containing only the packs * Variant of write_midx_file which writes a MIDX containing only the packs
* specified in packs_to_include. * specified in packs_to_include.
*/ */
int write_midx_file(struct repository *r, const char *object_dir, int write_midx_file(struct odb_source *source,
const char *preferred_pack_name, const char *refs_snapshot, const char *preferred_pack_name, const char *refs_snapshot,
unsigned flags); unsigned flags);
int write_midx_file_only(struct repository *r, const char *object_dir, int write_midx_file_only(struct odb_source *source,
struct string_list *packs_to_include, struct string_list *packs_to_include,
const char *preferred_pack_name, const char *preferred_pack_name,
const char *refs_snapshot, unsigned flags); const char *refs_snapshot, unsigned flags);
void clear_midx_file(struct repository *r); void clear_midx_file(struct repository *r);
int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags); int verify_midx_file(struct odb_source *source, unsigned flags);
int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags); int expire_midx_packs(struct odb_source *source, unsigned flags);
int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags); int midx_repack(struct odb_source *source, size_t batch_size, unsigned flags);
void close_midx(struct multi_pack_index *m); void close_midx(struct multi_pack_index *m);

64
odb.c
View File

@@ -139,23 +139,21 @@ static void read_info_alternates(struct object_database *odb,
const char *relative_base, const char *relative_base,
int depth); int depth);
static int link_alt_odb_entry(struct object_database *odb, static struct odb_source *link_alt_odb_entry(struct object_database *odb,
const struct strbuf *entry, const char *dir,
const char *relative_base, const char *relative_base,
int depth, int depth)
const char *normalized_objdir)
{ {
struct odb_source *alternate; struct odb_source *alternate = NULL;
struct strbuf pathbuf = STRBUF_INIT; struct strbuf pathbuf = STRBUF_INIT;
struct strbuf tmp = STRBUF_INIT; struct strbuf tmp = STRBUF_INIT;
khiter_t pos; khiter_t pos;
int ret = -1;
if (!is_absolute_path(entry->buf) && relative_base) { if (!is_absolute_path(dir) && relative_base) {
strbuf_realpath(&pathbuf, relative_base, 1); strbuf_realpath(&pathbuf, relative_base, 1);
strbuf_addch(&pathbuf, '/'); strbuf_addch(&pathbuf, '/');
} }
strbuf_addbuf(&pathbuf, entry); strbuf_addstr(&pathbuf, dir);
if (!strbuf_realpath(&tmp, pathbuf.buf, 0)) { if (!strbuf_realpath(&tmp, pathbuf.buf, 0)) {
error(_("unable to normalize alternate object path: %s"), error(_("unable to normalize alternate object path: %s"),
@@ -171,11 +169,15 @@ static int link_alt_odb_entry(struct object_database *odb,
while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
strbuf_setlen(&pathbuf, pathbuf.len - 1); strbuf_setlen(&pathbuf, pathbuf.len - 1);
if (!alt_odb_usable(odb, &pathbuf, normalized_objdir, &pos)) strbuf_reset(&tmp);
strbuf_realpath(&tmp, odb->sources->path, 1);
if (!alt_odb_usable(odb, &pathbuf, tmp.buf, &pos))
goto error; goto error;
CALLOC_ARRAY(alternate, 1); CALLOC_ARRAY(alternate, 1);
alternate->odb = odb; alternate->odb = odb;
alternate->local = false;
/* pathbuf.buf is already in r->objects->source_by_path */ /* pathbuf.buf is already in r->objects->source_by_path */
alternate->path = strbuf_detach(&pathbuf, NULL); alternate->path = strbuf_detach(&pathbuf, NULL);
@@ -188,11 +190,11 @@ static int link_alt_odb_entry(struct object_database *odb,
/* recursively add alternates */ /* recursively add alternates */
read_info_alternates(odb, alternate->path, depth + 1); read_info_alternates(odb, alternate->path, depth + 1);
ret = 0;
error: error:
strbuf_release(&tmp); strbuf_release(&tmp);
strbuf_release(&pathbuf); strbuf_release(&pathbuf);
return ret; return alternate;
} }
static const char *parse_alt_odb_entry(const char *string, static const char *parse_alt_odb_entry(const char *string,
@@ -227,8 +229,7 @@ static const char *parse_alt_odb_entry(const char *string,
static void link_alt_odb_entries(struct object_database *odb, const char *alt, static void link_alt_odb_entries(struct object_database *odb, const char *alt,
int sep, const char *relative_base, int depth) int sep, const char *relative_base, int depth)
{ {
struct strbuf objdirbuf = STRBUF_INIT; struct strbuf dir = STRBUF_INIT;
struct strbuf entry = STRBUF_INIT;
if (!alt || !*alt) if (!alt || !*alt)
return; return;
@@ -239,17 +240,13 @@ static void link_alt_odb_entries(struct object_database *odb, const char *alt,
return; return;
} }
strbuf_realpath(&objdirbuf, odb->sources->path, 1);
while (*alt) { while (*alt) {
alt = parse_alt_odb_entry(alt, sep, &entry); alt = parse_alt_odb_entry(alt, sep, &dir);
if (!entry.len) if (!dir.len)
continue; continue;
link_alt_odb_entry(odb, &entry, link_alt_odb_entry(odb, dir.buf, relative_base, depth);
relative_base, depth, objdirbuf.buf);
} }
strbuf_release(&entry); strbuf_release(&dir);
strbuf_release(&objdirbuf);
} }
static void read_info_alternates(struct object_database *odb, static void read_info_alternates(struct object_database *odb,
@@ -272,7 +269,7 @@ static void read_info_alternates(struct object_database *odb,
} }
void odb_add_to_alternates_file(struct object_database *odb, void odb_add_to_alternates_file(struct object_database *odb,
const char *reference) const char *dir)
{ {
struct lock_file lock = LOCK_INIT; struct lock_file lock = LOCK_INIT;
char *alts = repo_git_path(odb->repo, "objects/info/alternates"); char *alts = repo_git_path(odb->repo, "objects/info/alternates");
@@ -289,7 +286,7 @@ void odb_add_to_alternates_file(struct object_database *odb,
struct strbuf line = STRBUF_INIT; struct strbuf line = STRBUF_INIT;
while (strbuf_getline(&line, in) != EOF) { while (strbuf_getline(&line, in) != EOF) {
if (!strcmp(reference, line.buf)) { if (!strcmp(dir, line.buf)) {
found = 1; found = 1;
break; break;
} }
@@ -305,27 +302,24 @@ void odb_add_to_alternates_file(struct object_database *odb,
if (found) { if (found) {
rollback_lock_file(&lock); rollback_lock_file(&lock);
} else { } else {
fprintf_or_die(out, "%s\n", reference); fprintf_or_die(out, "%s\n", dir);
if (commit_lock_file(&lock)) if (commit_lock_file(&lock))
die_errno(_("unable to move new alternates file into place")); die_errno(_("unable to move new alternates file into place"));
if (odb->loaded_alternates) if (odb->loaded_alternates)
link_alt_odb_entries(odb, reference, link_alt_odb_entries(odb, dir, '\n', NULL, 0);
'\n', NULL, 0);
} }
free(alts); free(alts);
} }
void odb_add_to_alternates_memory(struct object_database *odb, struct odb_source *odb_add_to_alternates_memory(struct object_database *odb,
const char *reference) const char *dir)
{ {
/* /*
* Make sure alternates are initialized, or else our entry may be * Make sure alternates are initialized, or else our entry may be
* overwritten when they are. * overwritten when they are.
*/ */
odb_prepare_alternates(odb); odb_prepare_alternates(odb);
return link_alt_odb_entry(odb, dir, NULL, 0);
link_alt_odb_entries(odb, reference,
'\n', NULL, 0);
} }
struct odb_source *odb_set_temporary_primary_source(struct object_database *odb, struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,
@@ -463,6 +457,12 @@ struct odb_source *odb_find_source(struct object_database *odb, const char *obj_
free(obj_dir_real); free(obj_dir_real);
strbuf_release(&odb_path_real); strbuf_release(&odb_path_real);
return source;
}
struct odb_source *odb_find_source_or_die(struct object_database *odb, const char *obj_dir)
{
struct odb_source *source = odb_find_source(odb, obj_dir);
if (!source) if (!source)
die(_("could not find object directory matching %s"), obj_dir); die(_("could not find object directory matching %s"), obj_dir);
return source; return source;

19
odb.h
View File

@@ -63,6 +63,14 @@ struct odb_source {
*/ */
struct multi_pack_index *midx; struct multi_pack_index *midx;
/*
* Figure out whether this is the local source of the owning
* repository, which would typically be its ".git/objects" directory.
* This local object directory is usually where objects would be
* written to.
*/
bool local;
/* /*
* This is a temporary object store created by the tmp_objdir * This is a temporary object store created by the tmp_objdir
* facility. Disable ref updates since the objects in the store * facility. Disable ref updates since the objects in the store
@@ -178,11 +186,14 @@ struct object_database *odb_new(struct repository *repo);
void odb_clear(struct object_database *o); void odb_clear(struct object_database *o);
/* /*
* Find source by its object directory path. Dies in case the source couldn't * Find source by its object directory path. Returns a `NULL` pointer in case
* be found. * the source could not be found.
*/ */
struct odb_source *odb_find_source(struct object_database *odb, const char *obj_dir); struct odb_source *odb_find_source(struct object_database *odb, const char *obj_dir);
/* Same as `odb_find_source()`, but dies in case the source doesn't exist. */
struct odb_source *odb_find_source_or_die(struct object_database *odb, const char *obj_dir);
/* /*
* Replace the current writable object directory with the specified temporary * Replace the current writable object directory with the specified temporary
* object directory; returns the former primary source. * object directory; returns the former primary source.
@@ -257,8 +268,8 @@ void odb_add_to_alternates_file(struct object_database *odb,
* recursive alternates it points to), but do not modify the on-disk alternates * recursive alternates it points to), but do not modify the on-disk alternates
* file. * file.
*/ */
void odb_add_to_alternates_memory(struct object_database *odb, struct odb_source *odb_add_to_alternates_memory(struct object_database *odb,
const char *dir); const char *dir);
/* /*
* Read an object from the database. Returns the object data and assigns object * Read an object from the database. Returns the object data and assigns object

View File

@@ -216,7 +216,7 @@ static uint32_t bitmap_num_objects(struct bitmap_index *index)
static struct repository *bitmap_repo(struct bitmap_index *bitmap_git) static struct repository *bitmap_repo(struct bitmap_index *bitmap_git)
{ {
if (bitmap_is_midx(bitmap_git)) if (bitmap_is_midx(bitmap_git))
return bitmap_git->midx->repo; return bitmap_git->midx->source->odb->repo;
return bitmap_git->pack->repo; return bitmap_git->pack->repo;
} }
@@ -418,13 +418,12 @@ char *midx_bitmap_filename(struct multi_pack_index *midx)
{ {
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
if (midx->has_chain) if (midx->has_chain)
get_split_midx_filename_ext(midx->repo->hash_algo, &buf, get_split_midx_filename_ext(midx->source, &buf,
midx->object_dir,
get_midx_checksum(midx), get_midx_checksum(midx),
MIDX_EXT_BITMAP); MIDX_EXT_BITMAP);
else else
get_midx_filename_ext(midx->repo->hash_algo, &buf, get_midx_filename_ext(midx->source, &buf,
midx->object_dir, get_midx_checksum(midx), get_midx_checksum(midx),
MIDX_EXT_BITMAP); MIDX_EXT_BITMAP);
return strbuf_detach(&buf, NULL); return strbuf_detach(&buf, NULL);
@@ -463,7 +462,7 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
if (bitmap_git->pack || bitmap_git->midx) { if (bitmap_git->pack || bitmap_git->midx) {
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
get_midx_filename(midx->repo->hash_algo, &buf, midx->object_dir); get_midx_filename(midx->source, &buf);
trace2_data_string("bitmap", bitmap_repo(bitmap_git), trace2_data_string("bitmap", bitmap_repo(bitmap_git),
"ignoring extra midx bitmap file", buf.buf); "ignoring extra midx bitmap file", buf.buf);
close(fd); close(fd);
@@ -493,7 +492,7 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
} }
for (i = 0; i < bitmap_git->midx->num_packs + bitmap_git->midx->num_packs_in_base; i++) { for (i = 0; i < bitmap_git->midx->num_packs + bitmap_git->midx->num_packs_in_base; i++) {
if (prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) { if (prepare_midx_pack(bitmap_git->midx, i)) {
warning(_("could not open pack %s"), warning(_("could not open pack %s"),
bitmap_git->midx->pack_names[i]); bitmap_git->midx->pack_names[i]);
goto cleanup; goto cleanup;
@@ -2466,7 +2465,7 @@ void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
struct multi_pack_index *m = bitmap_git->midx; struct multi_pack_index *m = bitmap_git->midx;
for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) { for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
struct bitmapped_pack pack; struct bitmapped_pack pack;
if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) { if (nth_bitmapped_pack(bitmap_git->midx, &pack, i) < 0) {
warning(_("unable to load pack: '%s', disabling pack-reuse"), warning(_("unable to load pack: '%s', disabling pack-reuse"),
bitmap_git->midx->pack_names[i]); bitmap_git->midx->pack_names[i]);
free(packs); free(packs);

View File

@@ -379,25 +379,25 @@ int load_midx_revindex(struct multi_pack_index *m)
* not want to accidentally call munmap() in the middle of the * not want to accidentally call munmap() in the middle of the
* MIDX. * MIDX.
*/ */
trace2_data_string("load_midx_revindex", m->repo, trace2_data_string("load_midx_revindex", m->source->odb->repo,
"source", "midx"); "source", "midx");
m->revindex_data = (const uint32_t *)m->chunk_revindex; m->revindex_data = (const uint32_t *)m->chunk_revindex;
return 0; return 0;
} }
trace2_data_string("load_midx_revindex", m->repo, trace2_data_string("load_midx_revindex", m->source->odb->repo,
"source", "rev"); "source", "rev");
if (m->has_chain) if (m->has_chain)
get_split_midx_filename_ext(m->repo->hash_algo, &revindex_name, get_split_midx_filename_ext(m->source, &revindex_name,
m->object_dir, get_midx_checksum(m), get_midx_checksum(m),
MIDX_EXT_REV); MIDX_EXT_REV);
else else
get_midx_filename_ext(m->repo->hash_algo, &revindex_name, get_midx_filename_ext(m->source, &revindex_name,
m->object_dir, get_midx_checksum(m), get_midx_checksum(m),
MIDX_EXT_REV); MIDX_EXT_REV);
ret = load_revindex_from_disk(m->repo->hash_algo, ret = load_revindex_from_disk(m->source->odb->repo->hash_algo,
revindex_name.buf, revindex_name.buf,
m->num_objects, m->num_objects,
&m->revindex_map, &m->revindex_map,

View File

@@ -935,14 +935,14 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
report_garbage(PACKDIR_FILE_GARBAGE, full_name); report_garbage(PACKDIR_FILE_GARBAGE, full_name);
} }
static void prepare_packed_git_one(struct odb_source *source, int local) static void prepare_packed_git_one(struct odb_source *source)
{ {
struct string_list garbage = STRING_LIST_INIT_DUP; struct string_list garbage = STRING_LIST_INIT_DUP;
struct prepare_pack_data data = { struct prepare_pack_data data = {
.m = source->midx, .m = source->midx,
.r = source->odb->repo, .r = source->odb->repo,
.garbage = &garbage, .garbage = &garbage,
.local = local, .local = source->local,
}; };
for_each_file_in_pack_dir(source->path, prepare_pack, &data); for_each_file_in_pack_dir(source->path, prepare_pack, &data);
@@ -1037,9 +1037,8 @@ static void prepare_packed_git(struct repository *r)
odb_prepare_alternates(r->objects); odb_prepare_alternates(r->objects);
for (source = r->objects->sources; source; source = source->next) { for (source = r->objects->sources; source; source = source->next) {
int local = (source == r->objects->sources); prepare_multi_pack_index_one(source);
prepare_multi_pack_index_one(source, local); prepare_packed_git_one(source);
prepare_packed_git_one(source, local);
} }
rearrange_packed_git(r); rearrange_packed_git(r);
@@ -1092,7 +1091,7 @@ struct packed_git *get_all_packs(struct repository *r)
if (!m) if (!m)
continue; continue;
for (uint32_t i = 0; i < m->num_packs + m->num_packs_in_base; i++) for (uint32_t i = 0; i < m->num_packs + m->num_packs_in_base; i++)
prepare_midx_pack(r, m, i); prepare_midx_pack(m, i);
} }
return r->objects->packed_git; return r->objects->packed_git;
@@ -2078,7 +2077,7 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa
prepare_packed_git(r); prepare_packed_git(r);
for (struct odb_source *source = r->objects->sources; source; source = source->next) for (struct odb_source *source = r->objects->sources; source; source = source->next)
if (source->midx && fill_midx_entry(r, oid, e, source->midx)) if (source->midx && fill_midx_entry(source->midx, oid, e))
return 1; return 1;
if (!r->objects->packed_git) if (!r->objects->packed_git)

View File

@@ -168,6 +168,7 @@ void repo_set_gitdir(struct repository *repo,
if (!repo->objects->sources) { if (!repo->objects->sources) {
CALLOC_ARRAY(repo->objects->sources, 1); CALLOC_ARRAY(repo->objects->sources, 1);
repo->objects->sources->odb = repo->objects; repo->objects->sources->odb = repo->objects;
repo->objects->sources->local = true;
repo->objects->sources_tail = &repo->objects->sources->next; repo->objects->sources_tail = &repo->objects->sources->next;
} }
expand_base_dir(&repo->objects->sources->path, o->object_dir, expand_base_dir(&repo->objects->sources->path, o->object_dir,

View File

@@ -11,14 +11,24 @@
#include "gettext.h" #include "gettext.h"
#include "pack-revindex.h" #include "pack-revindex.h"
static struct multi_pack_index *setup_midx(const char *object_dir)
{
struct odb_source *source;
setup_git_directory();
source = odb_find_source(the_repository->objects, object_dir);
if (!source)
source = odb_add_to_alternates_memory(the_repository->objects,
object_dir);
return load_multi_pack_index(source);
}
static int read_midx_file(const char *object_dir, const char *checksum, static int read_midx_file(const char *object_dir, const char *checksum,
int show_objects) int show_objects)
{ {
uint32_t i; uint32_t i;
struct multi_pack_index *m; struct multi_pack_index *m;
setup_git_directory(); m = setup_midx(object_dir);
m = load_multi_pack_index(the_repository, object_dir, 1);
if (!m) if (!m)
return 1; return 1;
@@ -56,7 +66,7 @@ static int read_midx_file(const char *object_dir, const char *checksum,
for (i = 0; i < m->num_packs; i++) for (i = 0; i < m->num_packs; i++)
printf("%s\n", m->pack_names[i]); printf("%s\n", m->pack_names[i]);
printf("object-dir: %s\n", m->object_dir); printf("object-dir: %s\n", m->source->path);
if (show_objects) { if (show_objects) {
struct object_id oid; struct object_id oid;
@@ -65,7 +75,7 @@ static int read_midx_file(const char *object_dir, const char *checksum,
for (i = 0; i < m->num_objects; i++) { for (i = 0; i < m->num_objects; i++) {
nth_midxed_object_oid(&oid, m, nth_midxed_object_oid(&oid, m,
i + m->num_objects_in_base); i + m->num_objects_in_base);
fill_midx_entry(the_repository, &oid, &e, m); fill_midx_entry(m, &oid, &e);
printf("%s %"PRIu64"\t%s\n", printf("%s %"PRIu64"\t%s\n",
oid_to_hex(&oid), e.offset, e.p->pack_name); oid_to_hex(&oid), e.offset, e.p->pack_name);
@@ -81,8 +91,7 @@ static int read_midx_checksum(const char *object_dir)
{ {
struct multi_pack_index *m; struct multi_pack_index *m;
setup_git_directory(); m = setup_midx(object_dir);
m = load_multi_pack_index(the_repository, object_dir, 1);
if (!m) if (!m)
return 1; return 1;
printf("%s\n", hash_to_hex(get_midx_checksum(m))); printf("%s\n", hash_to_hex(get_midx_checksum(m)));
@@ -96,9 +105,7 @@ static int read_midx_preferred_pack(const char *object_dir)
struct multi_pack_index *midx = NULL; struct multi_pack_index *midx = NULL;
uint32_t preferred_pack; uint32_t preferred_pack;
setup_git_directory(); midx = setup_midx(object_dir);
midx = load_multi_pack_index(the_repository, object_dir, 1);
if (!midx) if (!midx)
return 1; return 1;
@@ -119,14 +126,12 @@ static int read_midx_bitmapped_packs(const char *object_dir)
struct bitmapped_pack pack; struct bitmapped_pack pack;
uint32_t i; uint32_t i;
setup_git_directory(); midx = setup_midx(object_dir);
midx = load_multi_pack_index(the_repository, object_dir, 1);
if (!midx) if (!midx)
return 1; return 1;
for (i = 0; i < midx->num_packs + midx->num_packs_in_base; i++) { for (i = 0; i < midx->num_packs + midx->num_packs_in_base; i++) {
if (nth_bitmapped_pack(the_repository, midx, &pack, i) < 0) { if (nth_bitmapped_pack(midx, &pack, i) < 0) {
close_midx(midx); close_midx(midx);
return 1; return 1;
} }

View File

@@ -28,11 +28,11 @@ midx_read_expect () {
EOF EOF
if test $NUM_PACKS -ge 1 if test $NUM_PACKS -ge 1
then then
ls $OBJECT_DIR/pack/ | grep idx | sort ls "$OBJECT_DIR"/pack/ | grep idx | sort
fi && fi &&
printf "object-dir: $OBJECT_DIR\n" printf "object-dir: $OBJECT_DIR\n"
} >expect && } >expect &&
test-tool read-midx $OBJECT_DIR >actual && test-tool read-midx "$OBJECT_DIR" >actual &&
test_cmp expect actual test_cmp expect actual
} }
@@ -305,7 +305,7 @@ test_expect_success 'midx picks objects from preferred pack' '
ofs=$(git show-index <objects/pack/test-BC-$bc.idx | grep $b | ofs=$(git show-index <objects/pack/test-BC-$bc.idx | grep $b |
cut -d" " -f1) && cut -d" " -f1) &&
printf "%s %s\tobjects/pack/test-BC-%s.pack\n" \ printf "%s %s\t./objects/pack/test-BC-%s.pack\n" \
"$b" "$ofs" "$bc" >expect && "$b" "$ofs" "$bc" >expect &&
grep ^$b out >actual && grep ^$b out >actual &&
@@ -639,7 +639,7 @@ test_expect_success 'force some 64-bit offsets with pack-objects' '
( cd ../objects64 && pwd ) >.git/objects/info/alternates && ( cd ../objects64 && pwd ) >.git/objects/info/alternates &&
midx64=$(git multi-pack-index --object-dir=../objects64 write) midx64=$(git multi-pack-index --object-dir=../objects64 write)
) && ) &&
midx_read_expect 1 63 5 objects64 " large-offsets" midx_read_expect 1 63 5 "$(pwd)/objects64" " large-offsets"
' '
test_expect_success 'verify multi-pack-index with 64-bit offsets' ' test_expect_success 'verify multi-pack-index with 64-bit offsets' '