From 2cf3fe63f6eedd6d132c530b897595345a05088b Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Tue, 3 Dec 2024 15:43:55 +0100 Subject: packfile: add repository to struct `packed_git` The struct `packed_git` holds information regarding a packed object file. Let's add the repository variable to this object, to represent the repository that this packfile belongs to. This helps remove dependency on the global `the_repository` object in `packfile.c` by simply using repository information now readily available in the struct. We do need to consider that a packfile could be part of the alternates of a repository, but considering that we only have one repository struct and also that we currently anyways use 'the_repository', we should be OK with this change. We also modify `alloc_packed_git` to ensure that the repository is added to newly created `packed_git` structs. This requires modifying the function and all its callee to pass the repository object down the levels. Helped-by: Taylor Blau Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- packfile.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'packfile.h') diff --git a/packfile.h b/packfile.h index 08f88a7ff5..aee69d1a0b 100644 --- a/packfile.h +++ b/packfile.h @@ -46,7 +46,8 @@ const char *pack_basename(struct packed_git *p); * and does not add the resulting packed_git struct to the internal list of * packs. You probably want add_packed_git() instead. */ -struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); +struct packed_git *parse_pack_index(struct repository *r, unsigned char *sha1, + const char *idx_path); typedef void each_file_in_pack_dir_fn(const char *full_path, size_t full_path_len, const char *file_name, void *data); @@ -113,7 +114,8 @@ void close_pack(struct packed_git *); void close_object_store(struct raw_object_store *o); void unuse_pack(struct pack_window **); void clear_delta_base_cache(void); -struct packed_git *add_packed_git(const char *path, size_t path_len, int local); +struct packed_git *add_packed_git(struct repository *r, const char *path, + size_t path_len, int local); /* * Unlink the .pack and associated extension files. -- cgit v1.3 From 873b00597bbf20c1bcda089a687641167b148fa2 Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Tue, 3 Dec 2024 15:43:58 +0100 Subject: packfile: pass down repository to `odb_pack_name` The function `odb_pack_name` currently relies on the global variable `the_repository`. To eliminate global variable usage in `packfile.c`, we should progressively shift the dependency on the_repository to higher layers. Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- builtin/fast-import.c | 8 ++++---- builtin/index-pack.c | 4 ++-- builtin/pack-redundant.c | 2 +- http.c | 2 +- packfile.c | 9 ++++----- packfile.h | 3 ++- 6 files changed, 14 insertions(+), 14 deletions(-) (limited to 'packfile.h') diff --git a/builtin/fast-import.c b/builtin/fast-import.c index da7e2d613b..3ccc4c5722 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -806,7 +806,7 @@ static char *keep_pack(const char *curr_index_name) struct strbuf name = STRBUF_INIT; int keep_fd; - odb_pack_name(&name, pack_data->hash, "keep"); + odb_pack_name(pack_data->repo, &name, pack_data->hash, "keep"); keep_fd = odb_pack_keep(name.buf); if (keep_fd < 0) die_errno("cannot create keep file"); @@ -814,11 +814,11 @@ static char *keep_pack(const char *curr_index_name) if (close(keep_fd)) die_errno("failed to write keep file"); - odb_pack_name(&name, pack_data->hash, "pack"); + odb_pack_name(pack_data->repo, &name, pack_data->hash, "pack"); if (finalize_object_file(pack_data->pack_name, name.buf)) die("cannot store pack file"); - odb_pack_name(&name, pack_data->hash, "idx"); + odb_pack_name(pack_data->repo, &name, pack_data->hash, "idx"); if (finalize_object_file(curr_index_name, name.buf)) die("cannot store index file"); free((void *)curr_index_name); @@ -832,7 +832,7 @@ static void unkeep_all_packs(void) for (k = 0; k < pack_id; k++) { struct packed_git *p = all_packs[k]; - odb_pack_name(&name, p->hash, "keep"); + odb_pack_name(p->repo, &name, p->hash, "keep"); unlink_or_warn(name.buf); } strbuf_release(&name); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index be2f99625e..eaefb41761 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1479,7 +1479,7 @@ static void write_special_file(const char *suffix, const char *msg, if (pack_name) filename = derive_filename(pack_name, "pack", suffix, &name_buf); else - filename = odb_pack_name(&name_buf, hash, suffix); + filename = odb_pack_name(the_repository, &name_buf, hash, suffix); fd = odb_pack_keep(filename); if (fd < 0) { @@ -1507,7 +1507,7 @@ static void rename_tmp_packfile(const char **final_name, { if (!*final_name || strcmp(*final_name, curr_name)) { if (!*final_name) - *final_name = odb_pack_name(name, hash, ext); + *final_name = odb_pack_name(the_repository, name, hash, ext); if (finalize_object_file(curr_name, *final_name)) die(_("unable to rename temporary '*.%s' file to '%s'"), ext, *final_name); diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index d2c1c4e5ec..bc61990a93 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -690,7 +690,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s pl = red = pack_list_difference(local_packs, min); while (pl) { printf("%s\n%s\n", - odb_pack_name(&idx_name, pl->pack->hash, "idx"), + odb_pack_name(pl->pack->repo, &idx_name, pl->pack->hash, "idx"), pl->pack->pack_name); pl = pl->next; } diff --git a/http.c b/http.c index 6744e18409..420f1566f0 100644 --- a/http.c +++ b/http.c @@ -2581,7 +2581,7 @@ struct http_pack_request *new_direct_http_pack_request( preq->url = url; - odb_pack_name(&preq->tmpfile, packed_git_hash, "pack"); + odb_pack_name(the_repository, &preq->tmpfile, packed_git_hash, "pack"); strbuf_addstr(&preq->tmpfile, ".temp"); preq->packfile = fopen(preq->tmpfile.buf, "a"); if (!preq->packfile) { diff --git a/packfile.c b/packfile.c index c96ebc4c69..1015dac6db 100644 --- a/packfile.c +++ b/packfile.c @@ -25,13 +25,12 @@ #include "pack-revindex.h" #include "promisor-remote.h" -char *odb_pack_name(struct strbuf *buf, - const unsigned char *hash, - const char *ext) +char *odb_pack_name(struct repository *r, struct strbuf *buf, + const unsigned char *hash, const char *ext) { strbuf_reset(buf); - strbuf_addf(buf, "%s/pack/pack-%s.%s", repo_get_object_directory(the_repository), - hash_to_hex(hash), ext); + strbuf_addf(buf, "%s/pack/pack-%s.%s", repo_get_object_directory(r), + hash_to_hex_algop(hash, r->hash_algo), ext); return buf->buf; } diff --git a/packfile.h b/packfile.h index aee69d1a0b..51187f2393 100644 --- a/packfile.h +++ b/packfile.h @@ -29,7 +29,8 @@ struct pack_entry { * * Example: odb_pack_name(out, sha1, "idx") => ".git/objects/pack/pack-1234..idx" */ -char *odb_pack_name(struct strbuf *buf, const unsigned char *sha1, const char *ext); +char *odb_pack_name(struct repository *r, struct strbuf *buf, + const unsigned char *hash, const char *ext); /* * Return the basename of the packfile, omitting any containing directory -- cgit v1.3 From cc656f4eb2b7b10bc530c96844909c869bdd1fdf Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Tue, 3 Dec 2024 15:43:59 +0100 Subject: packfile: pass down repository to `has_object[_kept]_pack` The functions `has_object[_kept]_pack` currently rely on the global variable `the_repository`. To eliminate global variable usage in `packfile.c`, we should progressively shift the dependency on the_repository to higher layers. Let's remove its usage from these functions and any related ones. Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- builtin/count-objects.c | 2 +- builtin/fsck.c | 2 +- builtin/pack-objects.c | 4 ++-- diff.c | 3 ++- list-objects.c | 3 ++- pack-bitmap.c | 2 +- packfile.c | 9 +++++---- packfile.h | 5 +++-- prune-packed.c | 2 +- reachable.c | 2 +- revision.c | 4 ++-- 11 files changed, 21 insertions(+), 17 deletions(-) (limited to 'packfile.h') diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 04d80887e0..1e89148ed7 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -67,7 +67,7 @@ static int count_loose(const struct object_id *oid, const char *path, else { loose_size += on_disk_bytes(st); loose++; - if (verbose && has_object_pack(oid)) + if (verbose && has_object_pack(the_repository, oid)) packed_loose++; } return 0; diff --git a/builtin/fsck.c b/builtin/fsck.c index 7f4e2f0414..bb56eb98ac 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -272,7 +272,7 @@ static void check_reachable_object(struct object *obj) if (!(obj->flags & HAS_OBJ)) { if (is_promisor_object(&obj->oid)) return; - if (has_object_pack(&obj->oid)) + if (has_object_pack(the_repository, &obj->oid)) return; /* it is in pack - forget about it */ printf_ln(_("missing %s %s"), printable_type(&obj->oid, obj->type), diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 0800714267..0f32e92a3a 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1529,7 +1529,7 @@ static int want_found_object(const struct object_id *oid, int exclude, return 0; if (ignore_packed_keep_in_core && p->pack_keep_in_core) return 0; - if (has_object_kept_pack(oid, flags)) + if (has_object_kept_pack(p->repo, oid, flags)) return 0; } @@ -3627,7 +3627,7 @@ static void show_cruft_commit(struct commit *commit, void *data) static int cruft_include_check_obj(struct object *obj, void *data UNUSED) { - return !has_object_kept_pack(&obj->oid, IN_CORE_KEEP_PACKS); + return !has_object_kept_pack(to_pack.repo, &obj->oid, IN_CORE_KEEP_PACKS); } static int cruft_include_check(struct commit *commit, void *data) diff --git a/diff.c b/diff.c index dceac20d18..266ddf18e7 100644 --- a/diff.c +++ b/diff.c @@ -4041,7 +4041,8 @@ static int reuse_worktree_file(struct index_state *istate, * objects however would tend to be slower as they need * to be individually opened and inflated. */ - if (!FAST_WORKING_DIRECTORY && !want_file && has_object_pack(oid)) + if (!FAST_WORKING_DIRECTORY && !want_file && + has_object_pack(istate->repo, oid)) return 0; /* diff --git a/list-objects.c b/list-objects.c index 985d008799..31236a8dc9 100644 --- a/list-objects.c +++ b/list-objects.c @@ -41,7 +41,8 @@ static void show_object(struct traversal_context *ctx, { if (!ctx->show_object) return; - if (ctx->revs->unpacked && has_object_pack(&object->oid)) + if (ctx->revs->unpacked && has_object_pack(ctx->revs->repo, + &object->oid)) return; ctx->show_object(object, name, ctx->show_data); diff --git a/pack-bitmap.c b/pack-bitmap.c index 4fa9dfc771..d34ba9909a 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -1889,7 +1889,7 @@ static void filter_packed_objects_from_bitmap(struct bitmap_index *bitmap_git, bitmap_unset(result, i); for (i = 0; i < eindex->count; ++i) { - if (has_object_pack(&eindex->objects[i]->oid)) + if (has_object_pack(the_repository, &eindex->objects[i]->oid)) bitmap_unset(result, objects_nr + i); } } diff --git a/packfile.c b/packfile.c index 1015dac6db..e7dd270217 100644 --- a/packfile.c +++ b/packfile.c @@ -2143,16 +2143,17 @@ int find_kept_pack_entry(struct repository *r, return 0; } -int has_object_pack(const struct object_id *oid) +int has_object_pack(struct repository *r, const struct object_id *oid) { struct pack_entry e; - return find_pack_entry(the_repository, oid, &e); + return find_pack_entry(r, oid, &e); } -int has_object_kept_pack(const struct object_id *oid, unsigned flags) +int has_object_kept_pack(struct repository *r, const struct object_id *oid, + unsigned flags) { struct pack_entry e; - return find_kept_pack_entry(the_repository, oid, flags, &e); + return find_kept_pack_entry(r, oid, flags, &e); } int for_each_object_in_pack(struct packed_git *p, diff --git a/packfile.h b/packfile.h index 51187f2393..b09fb2c530 100644 --- a/packfile.h +++ b/packfile.h @@ -193,8 +193,9 @@ const struct packed_git *has_packed_and_bad(struct repository *, const struct ob int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e); int find_kept_pack_entry(struct repository *r, const struct object_id *oid, unsigned flags, struct pack_entry *e); -int has_object_pack(const struct object_id *oid); -int has_object_kept_pack(const struct object_id *oid, unsigned flags); +int has_object_pack(struct repository *r, const struct object_id *oid); +int has_object_kept_pack(struct repository *r, const struct object_id *oid, + unsigned flags); /* * Return 1 if an object in a promisor packfile is or refers to the given diff --git a/prune-packed.c b/prune-packed.c index 2bb99c29df..d1c65ab10e 100644 --- a/prune-packed.c +++ b/prune-packed.c @@ -24,7 +24,7 @@ static int prune_object(const struct object_id *oid, const char *path, { int *opts = data; - if (!has_object_pack(oid)) + if (!has_object_pack(the_repository, oid)) return 0; if (*opts & PRUNE_PACKED_DRY_RUN) diff --git a/reachable.c b/reachable.c index 3e9b3dd0a4..09d2c50079 100644 --- a/reachable.c +++ b/reachable.c @@ -239,7 +239,7 @@ static int want_recent_object(struct recent_data *data, const struct object_id *oid) { if (data->ignore_in_core_kept_packs && - has_object_kept_pack(oid, IN_CORE_KEEP_PACKS)) + has_object_kept_pack(data->revs->repo, oid, IN_CORE_KEEP_PACKS)) return 0; return 1; } diff --git a/revision.c b/revision.c index f5f5b84f2b..d1d152a67b 100644 --- a/revision.c +++ b/revision.c @@ -4103,10 +4103,10 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi { if (commit->object.flags & SHOWN) return commit_ignore; - if (revs->unpacked && has_object_pack(&commit->object.oid)) + if (revs->unpacked && has_object_pack(revs->repo, &commit->object.oid)) return commit_ignore; if (revs->no_kept_objects) { - if (has_object_kept_pack(&commit->object.oid, + if (has_object_kept_pack(revs->repo, &commit->object.oid, revs->keep_pack_cache_flags)) return commit_ignore; } -- cgit v1.3 From c87910b96b1223d4a1dfe65c04e03863fadef6bc Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Tue, 3 Dec 2024 15:44:00 +0100 Subject: packfile: pass down repository to `for_each_packed_object` The function `for_each_packed_object` currently relies on the global variable `the_repository`. To eliminate global variable usage in `packfile.c`, we should progressively shift the dependency on the_repository to higher layers. Let's remove its usage from this function and closely related function `is_promisor_object`. Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- builtin/cat-file.c | 7 ++++--- builtin/fsck.c | 18 +++++++++++------- builtin/pack-objects.c | 7 +++++-- builtin/repack.c | 2 +- builtin/rev-list.c | 2 +- commit-graph.c | 2 +- fsck.c | 2 +- list-objects.c | 4 ++-- object-store-ll.h | 4 ++-- packfile.c | 14 +++++++------- packfile.h | 2 +- promisor-remote.c | 2 +- reachable.c | 2 +- revision.c | 9 +++++---- tag.c | 2 +- 15 files changed, 44 insertions(+), 35 deletions(-) (limited to 'packfile.h') diff --git a/builtin/cat-file.c b/builtin/cat-file.c index bfdfb51c7c..d67b101c20 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -827,15 +827,16 @@ static int batch_objects(struct batch_options *opt) cb.seen = &seen; for_each_loose_object(batch_unordered_loose, &cb, 0); - for_each_packed_object(batch_unordered_packed, &cb, - FOR_EACH_OBJECT_PACK_ORDER); + for_each_packed_object(the_repository, batch_unordered_packed, + &cb, FOR_EACH_OBJECT_PACK_ORDER); oidset_clear(&seen); } else { struct oid_array sa = OID_ARRAY_INIT; for_each_loose_object(collect_loose_object, &sa, 0); - for_each_packed_object(collect_packed_object, &sa, 0); + for_each_packed_object(the_repository, collect_packed_object, + &sa, 0); oid_array_for_each_unique(&sa, batch_object_cb, &cb); diff --git a/builtin/fsck.c b/builtin/fsck.c index bb56eb98ac..0196c54eb6 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -150,7 +150,7 @@ static int mark_object(struct object *obj, enum object_type type, return 0; obj->flags |= REACHABLE; - if (is_promisor_object(&obj->oid)) + if (is_promisor_object(the_repository, &obj->oid)) /* * Further recursion does not need to be performed on this * object since it is a promisor object (so it does not need to @@ -270,7 +270,7 @@ static void check_reachable_object(struct object *obj) * do a full fsck */ if (!(obj->flags & HAS_OBJ)) { - if (is_promisor_object(&obj->oid)) + if (is_promisor_object(the_repository, &obj->oid)) return; if (has_object_pack(the_repository, &obj->oid)) return; /* it is in pack - forget about it */ @@ -391,7 +391,10 @@ static void check_connectivity(void) * traversal. */ for_each_loose_object(mark_loose_unreachable_referents, NULL, 0); - for_each_packed_object(mark_packed_unreachable_referents, NULL, 0); + for_each_packed_object(the_repository, + mark_packed_unreachable_referents, + NULL, + 0); } /* Look up all the requirements, warn about missing objects.. */ @@ -488,7 +491,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid, refname, timestamp); obj->flags |= USED; mark_object_reachable(obj); - } else if (!is_promisor_object(oid)) { + } else if (!is_promisor_object(the_repository, oid)) { error(_("%s: invalid reflog entry %s"), refname, oid_to_hex(oid)); errors_found |= ERROR_REACHABLE; @@ -531,7 +534,7 @@ static int fsck_handle_ref(const char *refname, const char *referent UNUSED, con obj = parse_object(the_repository, oid); if (!obj) { - if (is_promisor_object(oid)) { + if (is_promisor_object(the_repository, oid)) { /* * Increment default_refs anyway, because this is a * valid ref. @@ -966,7 +969,8 @@ int cmd_fsck(int argc, if (connectivity_only) { for_each_loose_object(mark_loose_for_connectivity, NULL, 0); - for_each_packed_object(mark_packed_for_connectivity, NULL, 0); + for_each_packed_object(the_repository, + mark_packed_for_connectivity, NULL, 0); } else { prepare_alt_odb(the_repository); for (odb = the_repository->objects->odb; odb; odb = odb->next) @@ -1011,7 +1015,7 @@ int cmd_fsck(int argc, &oid); if (!obj || !(obj->flags & HAS_OBJ)) { - if (is_promisor_object(&oid)) + if (is_promisor_object(the_repository, &oid)) continue; error(_("%s: object missing"), oid_to_hex(&oid)); errors_found |= ERROR_OBJECT; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 0f32e92a3a..db20f0cf51 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3858,7 +3858,8 @@ static void show_object__ma_allow_promisor(struct object *obj, const char *name, * Quietly ignore EXPECTED missing objects. This avoids problems with * staging them now and getting an odd error later. */ - if (!has_object(the_repository, &obj->oid, 0) && is_promisor_object(&obj->oid)) + if (!has_object(the_repository, &obj->oid, 0) && + is_promisor_object(to_pack.repo, &obj->oid)) return; show_object(obj, name, data); @@ -3927,7 +3928,9 @@ static int add_object_in_unpacked_pack(const struct object_id *oid, static void add_objects_in_unpacked_packs(void) { - if (for_each_packed_object(add_object_in_unpacked_pack, NULL, + if (for_each_packed_object(to_pack.repo, + add_object_in_unpacked_pack, + NULL, FOR_EACH_OBJECT_PACK_ORDER | FOR_EACH_OBJECT_LOCAL_ONLY | FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS | diff --git a/builtin/repack.c b/builtin/repack.c index d6bb37e84a..96a4fa234b 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -404,7 +404,7 @@ static void repack_promisor_objects(const struct pack_objects_args *args, * {type -> existing pack order} ordering when computing deltas instead * of a {type -> size} ordering, which may produce better deltas. */ - for_each_packed_object(write_oid, &cmd, + for_each_packed_object(the_repository, write_oid, &cmd, FOR_EACH_OBJECT_PROMISOR_ONLY); if (cmd.in == -1) { diff --git a/builtin/rev-list.c b/builtin/rev-list.c index f62bcbf2b1..43c42621e3 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -121,7 +121,7 @@ static inline void finish_object__ma(struct object *obj) return; case MA_ALLOW_PROMISOR: - if (is_promisor_object(&obj->oid)) + if (is_promisor_object(the_repository, &obj->oid)) return; die("unexpected missing %s object '%s'", type_name(obj->type), oid_to_hex(&obj->oid)); diff --git a/commit-graph.c b/commit-graph.c index 83dd69bfeb..e2e2083951 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1960,7 +1960,7 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx) ctx->progress = start_delayed_progress( _("Finding commits for commit graph among packed objects"), ctx->approx_nr_objects); - for_each_packed_object(add_packed_commits, ctx, + for_each_packed_object(ctx->r, add_packed_commits, ctx, FOR_EACH_OBJECT_PACK_ORDER); if (ctx->progress_done < ctx->approx_nr_objects) display_progress(ctx->progress, ctx->approx_nr_objects); diff --git a/fsck.c b/fsck.c index 3756f52459..87ce999a49 100644 --- a/fsck.c +++ b/fsck.c @@ -1295,7 +1295,7 @@ static int fsck_blobs(struct oidset *blobs_found, struct oidset *blobs_done, buf = repo_read_object_file(the_repository, oid, &type, &size); if (!buf) { - if (is_promisor_object(oid)) + if (is_promisor_object(the_repository, oid)) continue; ret |= report(options, oid, OBJ_BLOB, msg_missing, diff --git a/list-objects.c b/list-objects.c index 31236a8dc9..d11a389b3a 100644 --- a/list-objects.c +++ b/list-objects.c @@ -75,7 +75,7 @@ static void process_blob(struct traversal_context *ctx, */ if (ctx->revs->exclude_promisor_objects && !repo_has_object_file(the_repository, &obj->oid) && - is_promisor_object(&obj->oid)) + is_promisor_object(ctx->revs->repo, &obj->oid)) return; pathlen = path->len; @@ -180,7 +180,7 @@ static void process_tree(struct traversal_context *ctx, * an incomplete list of missing objects. */ if (revs->exclude_promisor_objects && - is_promisor_object(&obj->oid)) + is_promisor_object(revs->repo, &obj->oid)) return; if (!revs->do_not_die_on_missing_objects) diff --git a/object-store-ll.h b/object-store-ll.h index d46cd0e654..cd3bd5bd99 100644 --- a/object-store-ll.h +++ b/object-store-ll.h @@ -550,7 +550,7 @@ typedef int each_packed_object_fn(const struct object_id *oid, int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn, void *data, enum for_each_object_flags flags); -int for_each_packed_object(each_packed_object_fn, void *, - enum for_each_object_flags flags); +int for_each_packed_object(struct repository *repo, each_packed_object_fn cb, + void *data, enum for_each_object_flags flags); #endif /* OBJECT_STORE_LL_H */ diff --git a/packfile.c b/packfile.c index e7dd270217..5e8019b1fe 100644 --- a/packfile.c +++ b/packfile.c @@ -2200,15 +2200,15 @@ int for_each_object_in_pack(struct packed_git *p, return r; } -int for_each_packed_object(each_packed_object_fn cb, void *data, - enum for_each_object_flags flags) +int for_each_packed_object(struct repository *repo, each_packed_object_fn cb, + void *data, enum for_each_object_flags flags) { struct packed_git *p; int r = 0; int pack_errors = 0; - prepare_packed_git(the_repository); - for (p = get_all_packs(the_repository); p; p = p->next) { + prepare_packed_git(repo); + for (p = get_all_packs(repo); p; p = p->next) { if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local) continue; if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) && @@ -2286,14 +2286,14 @@ static int add_promisor_object(const struct object_id *oid, return 0; } -int is_promisor_object(const struct object_id *oid) +int is_promisor_object(struct repository *r, const struct object_id *oid) { static struct oidset promisor_objects; static int promisor_objects_prepared; if (!promisor_objects_prepared) { - if (repo_has_promisor_remote(the_repository)) { - for_each_packed_object(add_promisor_object, + if (repo_has_promisor_remote(r)) { + for_each_packed_object(r, add_promisor_object, &promisor_objects, FOR_EACH_OBJECT_PROMISOR_ONLY | FOR_EACH_OBJECT_PACK_ORDER); diff --git a/packfile.h b/packfile.h index b09fb2c530..addb95b0c4 100644 --- a/packfile.h +++ b/packfile.h @@ -201,7 +201,7 @@ int has_object_kept_pack(struct repository *r, const struct object_id *oid, * Return 1 if an object in a promisor packfile is or refers to the given * object, 0 otherwise. */ -int is_promisor_object(const struct object_id *oid); +int is_promisor_object(struct repository *r, const struct object_id *oid); /* * Expose a function for fuzz testing. diff --git a/promisor-remote.c b/promisor-remote.c index 9345ae3db2..c714f4f007 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -283,7 +283,7 @@ void promisor_remote_get_direct(struct repository *repo, } for (i = 0; i < remaining_nr; i++) { - if (is_promisor_object(&remaining_oids[i])) + if (is_promisor_object(repo, &remaining_oids[i])) die(_("could not fetch %s from promisor remote"), oid_to_hex(&remaining_oids[i])); } diff --git a/reachable.c b/reachable.c index 09d2c50079..ecf7ccf504 100644 --- a/reachable.c +++ b/reachable.c @@ -324,7 +324,7 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, if (ignore_in_core_kept_packs) flags |= FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS; - r = for_each_packed_object(add_recent_packed, &data, flags); + r = for_each_packed_object(revs->repo, add_recent_packed, &data, flags); done: oidset_clear(&data.extra_recent_oids); diff --git a/revision.c b/revision.c index d1d152a67b..45dc6d2819 100644 --- a/revision.c +++ b/revision.c @@ -390,7 +390,8 @@ static struct object *get_reference(struct rev_info *revs, const char *name, if (!object) { if (revs->ignore_missing) return NULL; - if (revs->exclude_promisor_objects && is_promisor_object(oid)) + if (revs->exclude_promisor_objects && + is_promisor_object(revs->repo, oid)) return NULL; if (revs->do_not_die_on_missing_objects) { oidset_insert(&revs->missing_commits, oid); @@ -432,7 +433,7 @@ static struct commit *handle_commit(struct rev_info *revs, if (revs->ignore_missing_links || (flags & UNINTERESTING)) return NULL; if (revs->exclude_promisor_objects && - is_promisor_object(&tag->tagged->oid)) + is_promisor_object(revs->repo, &tag->tagged->oid)) return NULL; if (revs->do_not_die_on_missing_objects && oid) { oidset_insert(&revs->missing_commits, oid); @@ -1211,7 +1212,7 @@ static int process_parents(struct rev_info *revs, struct commit *commit, revs->do_not_die_on_missing_objects; if (repo_parse_commit_gently(revs->repo, p, gently) < 0) { if (revs->exclude_promisor_objects && - is_promisor_object(&p->object.oid)) { + is_promisor_object(revs->repo, &p->object.oid)) { if (revs->first_parent_only) break; continue; @@ -3915,7 +3916,7 @@ int prepare_revision_walk(struct rev_info *revs) revs->treesame.name = "treesame"; if (revs->exclude_promisor_objects) { - for_each_packed_object(mark_uninteresting, revs, + for_each_packed_object(revs->repo, mark_uninteresting, revs, FOR_EACH_OBJECT_PROMISOR_ONLY); } diff --git a/tag.c b/tag.c index d24170e340..beef9571b5 100644 --- a/tag.c +++ b/tag.c @@ -84,7 +84,7 @@ struct object *deref_tag(struct repository *r, struct object *o, const char *war o = NULL; } if (!o && warn) { - if (last_oid && is_promisor_object(last_oid)) + if (last_oid && is_promisor_object(r, last_oid)) return NULL; if (!warnlen) warnlen = strlen(warn); -- cgit v1.3 From d284713bae71877577cf1a07501c8528f8c44bb2 Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Tue, 3 Dec 2024 15:44:02 +0100 Subject: config: make `packed_git_(limit|window_size)` non-global variables The variables `packed_git_window_size` and `packed_git_limit` are global config variables used in the `packfile.c` file. Since it is only used in this file, let's change it from being a global config variable to a local variable for the subsystem. With this, we rid `packfile.c` from all global variable usage and this means we can also remove the `USE_THE_REPOSITORY_VARIABLE` guard from the file. Helped-by: Taylor Blau Signed-off-by: Karthik Nayak Signed-off-by: Junio C Hamano --- builtin/fast-import.c | 4 ++-- config.c | 17 ----------------- environment.c | 2 -- packfile.c | 23 +++++++++++++++-------- packfile.h | 2 +- repo-settings.c | 13 +++++++++++++ repo-settings.h | 4 ++++ 7 files changed, 35 insertions(+), 30 deletions(-) (limited to 'packfile.h') diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 3ccc4c5722..0ece070260 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -3539,7 +3539,7 @@ static void parse_argv(void) int cmd_fast_import(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { unsigned int i; @@ -3660,7 +3660,7 @@ int cmd_fast_import(int argc, fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)((tree_entry_allocd + fi_mem_pool.pool_alloc) /1024)); fprintf(stderr, " objects: %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024); fprintf(stderr, "---------------------------------------------------------------------\n"); - pack_report(); + pack_report(repo); fprintf(stderr, "---------------------------------------------------------------------\n"); fprintf(stderr, "\n"); } diff --git a/config.c b/config.c index 728ef98e42..2c295f7430 100644 --- a/config.c +++ b/config.c @@ -1493,28 +1493,11 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.packedgitwindowsize")) { - int pgsz_x2 = getpagesize() * 2; - packed_git_window_size = git_config_ulong(var, value, ctx->kvi); - - /* This value must be multiple of (pagesize * 2) */ - packed_git_window_size /= pgsz_x2; - if (packed_git_window_size < 1) - packed_git_window_size = 1; - packed_git_window_size *= pgsz_x2; - return 0; - } - if (!strcmp(var, "core.bigfilethreshold")) { big_file_threshold = git_config_ulong(var, value, ctx->kvi); return 0; } - if (!strcmp(var, "core.packedgitlimit")) { - packed_git_limit = git_config_ulong(var, value, ctx->kvi); - return 0; - } - if (!strcmp(var, "core.autocrlf")) { if (value && !strcasecmp(value, "input")) { auto_crlf = AUTO_CRLF_INPUT; diff --git a/environment.c b/environment.c index 8e5022c282..8389a27270 100644 --- a/environment.c +++ b/environment.c @@ -49,8 +49,6 @@ int fsync_object_files = -1; int use_fsync = -1; enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT; enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT; -size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE; -size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT; unsigned long big_file_threshold = 512 * 1024 * 1024; char *editor_program; char *askpass_program; diff --git a/packfile.c b/packfile.c index 64248ca664..2e0e28c7de 100644 --- a/packfile.c +++ b/packfile.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "environment.h" @@ -46,15 +45,15 @@ static size_t pack_mapped; #define SZ_FMT PRIuMAX static inline uintmax_t sz_fmt(size_t s) { return s; } -void pack_report(void) +void pack_report(struct repository *repo) { fprintf(stderr, "pack_report: getpagesize() = %10" SZ_FMT "\n" "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n" "pack_report: core.packedGitLimit = %10" SZ_FMT "\n", sz_fmt(getpagesize()), - sz_fmt(packed_git_window_size), - sz_fmt(packed_git_limit)); + sz_fmt(repo->settings.packed_git_window_size), + sz_fmt(repo->settings.packed_git_limit)); fprintf(stderr, "pack_report: pack_used_ctr = %10u\n" "pack_report: pack_mmap_calls = %10u\n" @@ -650,8 +649,15 @@ unsigned char *use_pack(struct packed_git *p, break; } if (!win) { - size_t window_align = packed_git_window_size / 2; + size_t window_align; off_t len; + struct repo_settings *settings; + + /* lazy load the settings in case it hasn't been setup */ + prepare_repo_settings(p->repo); + settings = &p->repo->settings; + + window_align = settings->packed_git_window_size / 2; if (p->pack_fd == -1 && open_packed_git(p)) die("packfile %s cannot be accessed", p->pack_name); @@ -659,11 +665,12 @@ unsigned char *use_pack(struct packed_git *p, CALLOC_ARRAY(win, 1); win->offset = (offset / window_align) * window_align; len = p->pack_size - win->offset; - if (len > packed_git_window_size) - len = packed_git_window_size; + if (len > settings->packed_git_window_size) + len = settings->packed_git_window_size; win->len = (size_t)len; pack_mapped += win->len; - while (packed_git_limit < pack_mapped + + while (settings->packed_git_limit < pack_mapped && unuse_one_window(p)) ; /* nothing */ win->base = xmmap_gently(NULL, win->len, diff --git a/packfile.h b/packfile.h index addb95b0c4..58104fa009 100644 --- a/packfile.h +++ b/packfile.h @@ -89,7 +89,7 @@ unsigned long repo_approximate_object_count(struct repository *r); struct packed_git *find_oid_pack(const struct object_id *oid, struct packed_git *packs); -void pack_report(void); +void pack_report(struct repository *repo); /* * mmap the index file for the specified packfile (if it is not diff --git a/repo-settings.c b/repo-settings.c index acc27eb8fe..9d16d5399e 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -128,6 +128,19 @@ void prepare_repo_settings(struct repository *r) if (!repo_config_get_ulong(r, "core.deltabasecachelimit", &ulongval)) r->settings.delta_base_cache_limit = ulongval; + + if (!repo_config_get_ulong(r, "core.packedgitwindowsize", &ulongval)) { + int pgsz_x2 = getpagesize() * 2; + + /* This value must be multiple of (pagesize * 2) */ + ulongval /= pgsz_x2; + if (ulongval < 1) + ulongval = 1; + r->settings.packed_git_window_size = ulongval * pgsz_x2; + } + + if (!repo_config_get_ulong(r, "core.packedgitlimit", &ulongval)) + r->settings.packed_git_limit = ulongval; } enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo) diff --git a/repo-settings.h b/repo-settings.h index 10a6f7ed64..93ea0c3274 100644 --- a/repo-settings.h +++ b/repo-settings.h @@ -59,6 +59,8 @@ struct repo_settings { int warn_ambiguous_refs; /* lazily loaded via accessor */ size_t delta_base_cache_limit; + size_t packed_git_window_size; + size_t packed_git_limit; }; #define REPO_SETTINGS_INIT { \ .index_version = -1, \ @@ -66,6 +68,8 @@ struct repo_settings { .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ .warn_ambiguous_refs = -1, \ .delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT, \ + .packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE, \ + .packed_git_limit = DEFAULT_PACKED_GIT_LIMIT, \ } void prepare_repo_settings(struct repository *r); -- cgit v1.3 From 798e0f451661f81f4568dce4033cf1c9076f224f Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 19 Jan 2025 08:23:37 -0500 Subject: packfile: factor out --pack_header argument parsing Both index-pack and unpack-objects accept a --pack_header argument. This is an undocumented internal argument used by receive-pack and fetch to pass along information about the header of the pack, which they've already read from the incoming stream. In preparation for a bugfix, let's factor the duplicated code into a common helper. The callers are still responsible for identifying the option. While this could likewise be factored out, it is more flexible this way (e.g., if they ever started using parse-options and wanted to handle both the stuck and unstuck forms). Likewise, the callers are responsible for reporting errors, though they both just call die(). I've tweaked unpack-objects to match index-pack in marking the error for translation. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/index-pack.c | 14 +++----------- builtin/unpack-objects.c | 16 ++++------------ packfile.c | 17 +++++++++++++++++ packfile.h | 6 ++++++ 4 files changed, 30 insertions(+), 23 deletions(-) (limited to 'packfile.h') diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 763b01372a..bab42dfc2a 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1801,18 +1801,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) nr_threads = 1; } } else if (starts_with(arg, "--pack_header=")) { - struct pack_header *hdr; - char *c; - - hdr = (struct pack_header *)input_buffer; - hdr->hdr_signature = htonl(PACK_SIGNATURE); - hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); - if (*c != ',') - die(_("bad %s"), arg); - hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); - if (*c) + if (parse_pack_header_option(arg + 14, + input_buffer, + &input_len) < 0) die(_("bad %s"), arg); - input_len = sizeof(*hdr); } else if (!strcmp(arg, "-v")) { verbose = 1; } else if (!strcmp(arg, "--progress-title")) { diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 08fa2a7a74..3161447274 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -15,6 +15,7 @@ #include "progress.h" #include "decorate.h" #include "fsck.h" +#include "packfile.h" static int dry_run, quiet, recover, has_errors, strict; static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]"; @@ -639,18 +640,9 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED) continue; } if (starts_with(arg, "--pack_header=")) { - struct pack_header *hdr; - char *c; - - hdr = (struct pack_header *)buffer; - hdr->hdr_signature = htonl(PACK_SIGNATURE); - hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); - if (*c != ',') - die("bad %s", arg); - hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); - if (*c) - die("bad %s", arg); - len = sizeof(*hdr); + if (parse_pack_header_option(arg + 14, + buffer, &len) < 0) + die(_("bad %s"), arg); continue; } if (skip_prefix(arg, "--max-input-size=", &arg)) { diff --git a/packfile.c b/packfile.c index 813584646f..e2bdadc7cb 100644 --- a/packfile.c +++ b/packfile.c @@ -2294,3 +2294,20 @@ int is_promisor_object(const struct object_id *oid) } return oidset_contains(&promisor_objects, oid); } + +int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len) +{ + struct pack_header *hdr; + char *c; + + hdr = (struct pack_header *)out; + hdr->hdr_signature = htonl(PACK_SIGNATURE); + hdr->hdr_version = htonl(strtoul(in, &c, 10)); + if (*c != ',') + return -1; + hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); + if (*c) + return -1; + *len = sizeof(*hdr); + return 0; +} diff --git a/packfile.h b/packfile.h index eb18ec15db..41f38b4832 100644 --- a/packfile.h +++ b/packfile.h @@ -210,4 +210,10 @@ int is_promisor_object(const struct object_id *oid); int load_idx(const char *path, const unsigned int hashsz, void *idx_map, size_t idx_size, struct packed_git *p); +/* + * Parse a --pack_header option as accepted by index-pack and unpack-objects, + * turning it into the matching bytes we'd find in a pack. + */ +int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len); + #endif -- cgit v1.3