environment: move "pack_compression_level" into `struct repo_config_values`

The `pack_compression_level` configuration is currently stored in the global variable `pack_compression_level`, which makes it shared across repository instances within a single process. Store it instead in `repo_config_values`, where eagerly‑parsed repository configuration lives. `pack_compression_level` is parsed eagerly because it influences packfile compression, a core operation where a lazy parse could cause inconsistent behavior and hamper libification. This preserves the existing eager‑parsing behavior while tying the value to the repository from which it was read, avoiding cross‑repository state leakage and continuing the effort to reduce reliance on global configuration state. Update all references to use `repo_config_values()`. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Olamide Caleb Bello committed Jun 2, 2026 at 18:09 UTC 8cd7402accec35c92d9ea8cc10b9d8e2536ef7b5
5 files changed +23 -15
builtin/fast-import.c
+5 -3
@@ -965,6 +965,7 @@ static int store_object(
965 unsigned long hdrlen, deltalen;
966 struct git_hash_ctx c;
967 git_zstream s;
968 + struct repo_config_values *cfg = repo_config_values(the_repository);
969
970 hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
971 dat->len);
@@ -1005,7 +1006,7 @@ static int store_object(
1006 } else
1007 delta = NULL;
1008
1008 - git_deflate_init(&s, pack_compression_level);
1009 + git_deflate_init(&s, cfg->pack_compression_level);
1010 if (delta) {
1011 s.next_in = delta;
1012 s.avail_in = deltalen;
@@ -1032,7 +1033,7 @@ static int store_object(
1033 if (delta) {
1034 FREE_AND_NULL(delta);
1035
1035 - git_deflate_init(&s, pack_compression_level);
1036 + git_deflate_init(&s, cfg->pack_compression_level);
1037 s.next_in = (void *)dat->buf;
1038 s.avail_in = dat->len;
1039 s.avail_out = git_deflate_bound(&s, s.avail_in);
@@ -1115,6 +1116,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
1116 struct git_hash_ctx c;
1117 git_zstream s;
1118 struct hashfile_checkpoint checkpoint;
1119 + struct repo_config_values *cfg = repo_config_values(the_repository);
1120 int status = Z_OK;
1121
1122 /* Determine if we should auto-checkpoint. */
@@ -1134,7 +1136,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
1136
1137 crc32_begin(pack_file);
1138
1137 - git_deflate_init(&s, pack_compression_level);
1139 + git_deflate_init(&s, cfg->pack_compression_level);
1140
1141 hdrlen = encode_in_pack_object_header(out_buf, out_sz, OBJ_BLOB, len);
1142
builtin/pack-objects.c
+10 -7
@@ -386,8 +386,9 @@ static unsigned long do_compress(void **pptr, unsigned long size)
386 git_zstream stream;
387 void *in, *out;
388 unsigned long maxsize;
389 + struct repo_config_values *cfg = repo_config_values(the_repository);
390
390 - git_deflate_init(&stream, pack_compression_level);
391 + git_deflate_init(&stream, cfg->pack_compression_level);
392 maxsize = git_deflate_bound(&stream, size);
393
394 in = *pptr;
@@ -413,8 +414,9 @@ static unsigned long write_large_blob_data(struct odb_read_stream *st, struct ha
414 unsigned char ibuf[1024 * 16];
415 unsigned char obuf[1024 * 16];
416 unsigned long olen = 0;
417 + struct repo_config_values *cfg = repo_config_values(the_repository);
418
417 - git_deflate_init(&stream, pack_compression_level);
419 + git_deflate_init(&stream, cfg->pack_compression_level);
420
421 for (;;) {
422 ssize_t readlen;
@@ -5003,6 +5005,7 @@ int cmd_pack_objects(int argc,
5005 struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
5006 struct list_objects_filter_options filter_options =
5007 LIST_OBJECTS_FILTER_INIT;
5008 + struct repo_config_values *cfg = repo_config_values(the_repository);
5009
5010 struct option pack_objects_options[] = {
5011 OPT_CALLBACK_F('q', "quiet", &progress, NULL,
@@ -5084,7 +5087,7 @@ int cmd_pack_objects(int argc,
5087 N_("ignore packs that have companion .keep file")),
5088 OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
5089 N_("ignore this pack")),
5087 - OPT_INTEGER(0, "compression", &pack_compression_level,
5090 + OPT_INTEGER(0, "compression", &cfg->pack_compression_level,
5091 N_("pack compression level")),
5092 OPT_BOOL(0, "keep-true-parents", &grafts_keep_true_parents,
5093 N_("do not hide commits by grafts")),
@@ -5243,10 +5246,10 @@ int cmd_pack_objects(int argc,
5246
5247 if (!reuse_object)
5248 reuse_delta = 0;
5246 - if (pack_compression_level == -1)
5247 - pack_compression_level = Z_DEFAULT_COMPRESSION;
5248 - else if (pack_compression_level < 0 || pack_compression_level > Z_BEST_COMPRESSION)
5249 - die(_("bad pack compression level %d"), pack_compression_level);
5249 + if (cfg->pack_compression_level == -1)
5250 + cfg->pack_compression_level = Z_DEFAULT_COMPRESSION;
5251 + else if (cfg->pack_compression_level < 0 || cfg->pack_compression_level > Z_BEST_COMPRESSION)
5252 + die(_("bad pack compression level %d"), cfg->pack_compression_level);
5253
5254 if (!delta_search_threads) /* --threads=0 means autodetect */
5255 delta_search_threads = online_cpus();
environment.c
+5 -3
@@ -52,7 +52,6 @@ char *git_commit_encoding;
52 char *git_log_output_encoding;
53 char *apply_default_whitespace;
54 char *apply_default_ignorewhitespace;
55 -int pack_compression_level = Z_DEFAULT_COMPRESSION;
55 int fsync_object_files = -1;
56 int use_fsync = -1;
57 enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;
@@ -390,7 +389,7 @@ int git_default_core_config(const char *var, const char *value,
389 if (!zlib_compression_seen)
390 cfg->zlib_compression_level = level;
391 if (!pack_compression_seen)
393 - pack_compression_level = level;
392 + cfg->pack_compression_level = level;
393 return 0;
394 }
395
@@ -662,6 +661,8 @@ static int git_default_attr_config(const char *var, const char *value)
661 int git_default_config(const char *var, const char *value,
662 const struct config_context *ctx, void *cb)
663 {
664 + struct repo_config_values *cfg = repo_config_values(the_repository);
665 +
666 if (starts_with(var, "core."))
667 return git_default_core_config(var, value, ctx, cb);
668
@@ -701,7 +702,7 @@ int git_default_config(const char *var, const char *value,
702 level = Z_DEFAULT_COMPRESSION;
703 else if (level < 0 || level > Z_BEST_COMPRESSION)
704 die(_("bad pack compression level %d"), level);
704 - pack_compression_level = level;
705 + cfg->pack_compression_level = level;
706 pack_compression_seen = 1;
707 return 0;
708 }
@@ -721,4 +722,5 @@ void repo_config_values_init(struct repo_config_values *cfg)
722 cfg->trust_ctime = 1;
723 cfg->check_stat = 1;
724 cfg->zlib_compression_level = Z_BEST_SPEED;
725 + cfg->pack_compression_level = Z_DEFAULT_COMPRESSION;
726 }
environment.h
+1 -1
@@ -94,6 +94,7 @@ struct repo_config_values {
94 int trust_ctime;
95 int check_stat;
96 int zlib_compression_level;
97 + int pack_compression_level;
98
99 /* section "branch" config values */
100 enum branch_track branch_track;
@@ -171,7 +172,6 @@ extern int assume_unchanged;
172 extern int warn_on_object_refname_ambiguity;
173 extern char *apply_default_whitespace;
174 extern char *apply_default_ignorewhitespace;
174 -extern int pack_compression_level;
175 extern unsigned long pack_size_limit_cfg;
176
177 extern int precomposed_unicode;
object-file.c
+2 -1
@@ -1437,8 +1437,9 @@ static int stream_blob_to_pack(struct transaction_packfile *state,
1437 int status = Z_OK;
1438 int write_object = (flags & INDEX_WRITE_OBJECT);
1439 off_t offset = 0;
1440 + struct repo_config_values *cfg = repo_config_values(the_repository);
1441
1441 - git_deflate_init(&s, pack_compression_level);
1442 + git_deflate_init(&s, cfg->pack_compression_level);
1443
1444 hdrlen = encode_in_pack_object_header(obuf, sizeof(obuf), OBJ_BLOB, size);
1445 s.next_out = obuf + hdrlen;