{"thread":{"id":"65197","subject":"[PATCH v1 0/8] repo_config_values: migrate more globals","startedAt":"2026-03-10T12:07:32Z","lastAt":"2026-03-12T13:19:04Z","messageCount":14,"participants":["Olamide Caleb Bello","Christian Couder","Tian Yuchen","Bello Olamide"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"538392","messageId":"cover.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":null,"subject":"[PATCH v1 0/8] repo_config_values: migrate more globals","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:21Z","receivedAt":"2026-03-10T12:07:32Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"Base series\n===========\nThis series builds on top of the merged series:\n  [PATCH v7 0/3] Move repo-specific globals into repo_config_values\n\navailable at:\n  https://lore.kernel.org/git/<cover.1771258573.git.belkid98@gmail.com>\n\nIt should be applied on top of that series.\n\nOverview\n========\nThis series continues the effort to migrate repository-specific global\nvariables into struct repo_config_values, further reducing global\nstate and improving repository isolation.\n\nThe previous series introduced the infrastructure for storing\nrepository-dependent configuration in repo_config_values. This series\nextends that work by moving additional environment-related globals into\nthat struct and updating their call sites accordingly.\n\nThis helps avoid cross-repository interference when multiple\nrepositories are used within the same process, and continues preparing\nGit for improved library usage and better encapsulation of repository\nstate.\n\nOlamide Caleb Bello (8):\n  environment: move \"trust_ctime\" into `struct repo_config_values`\n  environment: move \"check_stat\" into `struct repo_config_values`\n  environment: move `zlib_compression_level` into repo_config_values\n  environment: move \"pack_compression_level\" into `struct\n    repo_config_values`\n  environment: move \"precomposed_unicode\" into `struct\n    repo_config_values`\n  env: move \"core_sparse_checkout_cone\" into `struct repo_config_values`\n  env: put \"sparse_expect_files_outside_of_patterns\" in\n    `repo_config_values`\n  env: move \"warn_on_object_refname_ambiguity\" into `repo_config_values`\n\n builtin/cat-file.c        |  7 ++++---\n builtin/fast-import.c     |  8 +++++---\n builtin/index-pack.c      |  3 ++-\n builtin/mv.c              |  2 +-\n builtin/pack-objects.c    | 15 ++++++++++-----\n builtin/sparse-checkout.c | 37 +++++++++++++++++++++---------------\n compat/precompose_utf8.c  | 20 +++++++++++++-------\n diff.c                    |  3 ++-\n dir.c                     |  3 ++-\n entry.c                   |  3 ++-\n environment.c             | 40 +++++++++++++++++++++------------------\n environment.h             | 19 ++++++++++---------\n http-push.c               |  3 ++-\n object-file.c             |  6 ++++--\n object-name.c             |  3 ++-\n revision.c                |  7 ++++---\n sparse-index.c            |  4 ++--\n statinfo.c                | 12 +++++++-----\n submodule.c               |  7 ++++---\n upload-pack.c             |  3 ++-\n 20 files changed, 122 insertions(+), 83 deletions(-)\n\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538393","messageId":"1188d351e62718f906cb5f49a9ac344b3d88dd3f.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 1/8] environment: move \"trust_ctime\" into `struct repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:22Z","receivedAt":"2026-03-10T12:07:36Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `core.trustctime` configuration is currently stored in the global\nvariable `trust_ctime`, which makes it shared across repository\ninstances in a single process.\n\nStore it instead in `repo_config_values`, so the value is tied to the\nrepository from which it was read. This preserves existing behavior\nwhile avoiding cross-repository state leakage and continues the effort\nto reduce reliance on global configuration state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n environment.c | 4 ++--\n environment.h | 2 +-\n statinfo.c    | 6 ++++--\n 3 files changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/environment.c b/environment.c\nindex fc3ed8bb1c..0a9067729e 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -42,7 +42,6 @@ static int pack_compression_seen;\n static int zlib_compression_seen;\n \n int trust_executable_bit = 1;\n-int trust_ctime = 1;\n int check_stat = 1;\n int has_symlinks = 1;\n int minimum_abbrev = 4, default_abbrev = -1;\n@@ -309,7 +308,7 @@ int git_default_core_config(const char *var, const char *value,\n \t\treturn 0;\n \t}\n \tif (!strcmp(var, \"core.trustctime\")) {\n-\t\ttrust_ctime = git_config_bool(var, value);\n+\t\tcfg->trust_ctime = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n \tif (!strcmp(var, \"core.checkstat\")) {\n@@ -721,4 +720,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->attributes_file = NULL;\n \tcfg->apply_sparse_checkout = 0;\n \tcfg->branch_track = BRANCH_TRACK_REMOTE;\n+\tcfg->trust_ctime = 1;\n }\ndiff --git a/environment.h b/environment.h\nindex 123a71cdc8..64d537686e 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -91,6 +91,7 @@ struct repo_config_values {\n \t/* section \"core\" config values */\n \tchar *attributes_file;\n \tint apply_sparse_checkout;\n+\tint trust_ctime;\n \n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n@@ -161,7 +162,6 @@ extern char *git_work_tree_cfg;\n \n /* Environment bits from configuration mechanism */\n extern int trust_executable_bit;\n-extern int trust_ctime;\n extern int check_stat;\n extern int has_symlinks;\n extern int minimum_abbrev, default_abbrev;\ndiff --git a/statinfo.c b/statinfo.c\nindex 30a164b0e6..4fc12053f4 100644\n--- a/statinfo.c\n+++ b/statinfo.c\n@@ -3,6 +3,7 @@\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"statinfo.h\"\n+#include \"repository.h\"\n \n /*\n  * Munge st_size into an unsigned int.\n@@ -63,17 +64,18 @@ void fake_lstat_data(const struct stat_data *sd, struct stat *st)\n int match_stat_data(const struct stat_data *sd, struct stat *st)\n {\n \tint changed = 0;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (sd->sd_mtime.sec != (unsigned int)st->st_mtime)\n \t\tchanged |= MTIME_CHANGED;\n-\tif (trust_ctime && check_stat &&\n+\tif (cfg->trust_ctime && check_stat &&\n \t    sd->sd_ctime.sec != (unsigned int)st->st_ctime)\n \t\tchanged |= CTIME_CHANGED;\n \n #ifdef USE_NSEC\n \tif (check_stat && sd->sd_mtime.nsec != ST_MTIME_NSEC(*st))\n \t\tchanged |= MTIME_CHANGED;\n-\tif (trust_ctime && check_stat &&\n+\tif (cfg->trust_ctime && check_stat &&\n \t    sd->sd_ctime.nsec != ST_CTIME_NSEC(*st))\n \t\tchanged |= CTIME_CHANGED;\n #endif\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538394","messageId":"1cd8f88a3de4b81a37bdb86672b7d394d7232117.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 2/8] environment: move \"check_stat\" into `struct repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:23Z","receivedAt":"2026-03-10T12:07:40Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `core.checkstat` configuration is currently stored in the global\nvariable `check_stat`, which makes it shared across repository\ninstances within a single process.\n\nStore it instead in `repo_config_values` so the value is associated\nwith the repository from which it was read. This preserves existing\nbehavior while avoiding cross-repository state leakage and continues\nthe effort to reduce reliance on global configuration state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n entry.c       |  3 ++-\n environment.c |  6 +++---\n environment.h |  2 +-\n statinfo.c    | 10 +++++-----\n 4 files changed, 11 insertions(+), 10 deletions(-)\n\ndiff --git a/entry.c b/entry.c\nindex 7817aee362..c55e867d8a 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -443,7 +443,8 @@ static int check_path(const char *path, int len, struct stat *st, int skiplen)\n static void mark_colliding_entries(const struct checkout *state,\n \t\t\t\t   struct cache_entry *ce, struct stat *st)\n {\n-\tint trust_ino = check_stat;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\tint trust_ino = cfg->check_stat;\n \n #if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__)\n \ttrust_ino = 0;\ndiff --git a/environment.c b/environment.c\nindex 0a9067729e..8542ac3141 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -42,7 +42,6 @@ static int pack_compression_seen;\n static int zlib_compression_seen;\n \n int trust_executable_bit = 1;\n-int check_stat = 1;\n int has_symlinks = 1;\n int minimum_abbrev = 4, default_abbrev = -1;\n int ignore_case;\n@@ -315,9 +314,9 @@ int git_default_core_config(const char *var, const char *value,\n \t\tif (!value)\n \t\t\treturn config_error_nonbool(var);\n \t\tif (!strcasecmp(value, \"default\"))\n-\t\t\tcheck_stat = 1;\n+\t\t\tcfg->check_stat = 1;\n \t\telse if (!strcasecmp(value, \"minimal\"))\n-\t\t\tcheck_stat = 0;\n+\t\t\tcfg->check_stat = 0;\n \t\telse\n \t\t\treturn error(_(\"invalid value for '%s': '%s'\"),\n \t\t\t\t     var, value);\n@@ -721,4 +720,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->apply_sparse_checkout = 0;\n \tcfg->branch_track = BRANCH_TRACK_REMOTE;\n \tcfg->trust_ctime = 1;\n+\tcfg->check_stat = 1;\n }\ndiff --git a/environment.h b/environment.h\nindex 64d537686e..1d3e2e4f23 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -92,6 +92,7 @@ struct repo_config_values {\n \tchar *attributes_file;\n \tint apply_sparse_checkout;\n \tint trust_ctime;\n+\tint check_stat;\n \n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n@@ -162,7 +163,6 @@ extern char *git_work_tree_cfg;\n \n /* Environment bits from configuration mechanism */\n extern int trust_executable_bit;\n-extern int check_stat;\n extern int has_symlinks;\n extern int minimum_abbrev, default_abbrev;\n extern int ignore_case;\ndiff --git a/statinfo.c b/statinfo.c\nindex 4fc12053f4..5e00af127d 100644\n--- a/statinfo.c\n+++ b/statinfo.c\n@@ -68,19 +68,19 @@ int match_stat_data(const struct stat_data *sd, struct stat *st)\n \n \tif (sd->sd_mtime.sec != (unsigned int)st->st_mtime)\n \t\tchanged |= MTIME_CHANGED;\n-\tif (cfg->trust_ctime && check_stat &&\n+\tif (cfg->trust_ctime && cfg->check_stat &&\n \t    sd->sd_ctime.sec != (unsigned int)st->st_ctime)\n \t\tchanged |= CTIME_CHANGED;\n \n #ifdef USE_NSEC\n-\tif (check_stat && sd->sd_mtime.nsec != ST_MTIME_NSEC(*st))\n+\tif (cfg->check_stat && sd->sd_mtime.nsec != ST_MTIME_NSEC(*st))\n \t\tchanged |= MTIME_CHANGED;\n-\tif (cfg->trust_ctime && check_stat &&\n+\tif (cfg->trust_ctime && cfg->check_stat &&\n \t    sd->sd_ctime.nsec != ST_CTIME_NSEC(*st))\n \t\tchanged |= CTIME_CHANGED;\n #endif\n \n-\tif (check_stat) {\n+\tif (cfg->check_stat) {\n \t\tif (sd->sd_uid != (unsigned int) st->st_uid ||\n \t\t\tsd->sd_gid != (unsigned int) st->st_gid)\n \t\t\tchanged |= OWNER_CHANGED;\n@@ -94,7 +94,7 @@ int match_stat_data(const struct stat_data *sd, struct stat *st)\n \t * clients will have different views of what \"device\"\n \t * the filesystem is on\n \t */\n-\tif (check_stat && sd->sd_dev != (unsigned int) st->st_dev)\n+\tif (cfg->check_stat && sd->sd_dev != (unsigned int) st->st_dev)\n \t\t\tchanged |= INODE_CHANGED;\n #endif\n \n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538395","messageId":"aebbcef3d1202001c5094d10587a86fda63cdfa2.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 3/8] environment: move `zlib_compression_level` into repo_config_values","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:24Z","receivedAt":"2026-03-10T12:07:45Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `zlib_compression_level` configuration is currently stored in the\nglobal variable `zlib_compression_level`, which makes it shared across\nrepository instances within a single process.\n\nStore it instead in `repo_config_values` so the value is associated\nwith the repository from which it was read. This preserves existing\nbehavior while avoiding cross-repository state leakage and continues\nthe effort to reduce reliance on global configuration state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n builtin/index-pack.c | 3 ++-\n diff.c               | 3 ++-\n environment.c        | 6 +++---\n environment.h        | 2 +-\n http-push.c          | 3 ++-\n object-file.c        | 3 ++-\n 6 files changed, 12 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex b67fb0256c..dd82eed76f 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1416,8 +1416,9 @@ static int write_compressed(struct hashfile *f, void *in, unsigned int size)\n \tgit_zstream stream;\n \tint status;\n \tunsigned char outbuf[4096];\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tgit_deflate_init(&stream, zlib_compression_level);\n+\tgit_deflate_init(&stream, cfg->zlib_compression_level);\n \tstream.next_in = in;\n \tstream.avail_in = size;\n \ndiff --git a/diff.c b/diff.c\nindex 501648a5c4..4bc0297873 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -3365,8 +3365,9 @@ static unsigned char *deflate_it(char *data,\n \tint bound;\n \tunsigned char *deflated;\n \tgit_zstream stream;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tgit_deflate_init(&stream, zlib_compression_level);\n+\tgit_deflate_init(&stream, cfg->zlib_compression_level);\n \tbound = git_deflate_bound(&stream, size);\n \tdeflated = xmalloc(bound);\n \tstream.next_out = deflated;\ndiff --git a/environment.c b/environment.c\nindex 8542ac3141..5b0e88b65c 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -52,7 +52,6 @@ char *git_commit_encoding;\n char *git_log_output_encoding;\n char *apply_default_whitespace;\n char *apply_default_ignorewhitespace;\n-int zlib_compression_level = Z_BEST_SPEED;\n int pack_compression_level = Z_DEFAULT_COMPRESSION;\n int fsync_object_files = -1;\n int use_fsync = -1;\n@@ -377,7 +376,7 @@ int git_default_core_config(const char *var, const char *value,\n \t\t\tlevel = Z_DEFAULT_COMPRESSION;\n \t\telse if (level < 0 || level > Z_BEST_COMPRESSION)\n \t\t\tdie(_(\"bad zlib compression level %d\"), level);\n-\t\tzlib_compression_level = level;\n+\t\tcfg->zlib_compression_level = level;\n \t\tzlib_compression_seen = 1;\n \t\treturn 0;\n \t}\n@@ -389,7 +388,7 @@ int git_default_core_config(const char *var, const char *value,\n \t\telse if (level < 0 || level > Z_BEST_COMPRESSION)\n \t\t\tdie(_(\"bad zlib compression level %d\"), level);\n \t\tif (!zlib_compression_seen)\n-\t\t\tzlib_compression_level = level;\n+\t\t\tcfg->zlib_compression_level = level;\n \t\tif (!pack_compression_seen)\n \t\t\tpack_compression_level = level;\n \t\treturn 0;\n@@ -721,4 +720,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->branch_track = BRANCH_TRACK_REMOTE;\n \tcfg->trust_ctime = 1;\n \tcfg->check_stat = 1;\n+\tcfg->zlib_compression_level = Z_BEST_SPEED;\n }\ndiff --git a/environment.h b/environment.h\nindex 1d3e2e4f23..93201620af 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -93,6 +93,7 @@ struct repo_config_values {\n \tint apply_sparse_checkout;\n \tint trust_ctime;\n \tint check_stat;\n+\tint zlib_compression_level;\n \n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n@@ -170,7 +171,6 @@ extern int assume_unchanged;\n extern int warn_on_object_refname_ambiguity;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n-extern int zlib_compression_level;\n extern int pack_compression_level;\n extern unsigned long pack_size_limit_cfg;\n \ndiff --git a/http-push.c b/http-push.c\nindex 9ae6062198..c6bf9ff387 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -369,13 +369,14 @@ static void start_put(struct transfer_request *request)\n \tint hdrlen;\n \tssize_t size;\n \tgit_zstream stream;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tunpacked = odb_read_object(the_repository->objects, &request->obj->oid,\n \t\t\t\t   &type, &len);\n \thdrlen = format_object_header(hdr, sizeof(hdr), type, len);\n \n \t/* Set it up */\n-\tgit_deflate_init(&stream, zlib_compression_level);\n+\tgit_deflate_init(&stream, cfg->zlib_compression_level);\n \tsize = git_deflate_bound(&stream, len + hdrlen);\n \tstrbuf_grow(&request->buffer.buf, size);\n \trequest->buffer.posn = 0;\ndiff --git a/object-file.c b/object-file.c\nindex 3094140055..8b719a915c 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -891,6 +891,7 @@ static int start_loose_object_common(struct odb_source *source,\n \tconst struct git_hash_algo *algo = source->odb->repo->hash_algo;\n \tconst struct git_hash_algo *compat = source->odb->repo->compat_hash_algo;\n \tint fd;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tfd = create_tmpfile(source->odb->repo, tmp_file, filename);\n \tif (fd < 0) {\n@@ -906,7 +907,7 @@ static int start_loose_object_common(struct odb_source *source,\n \t}\n \n \t/*  Setup zlib stream for compression */\n-\tgit_deflate_init(stream, zlib_compression_level);\n+\tgit_deflate_init(stream, cfg->zlib_compression_level);\n \tstream->next_out = buf;\n \tstream->avail_out = buflen;\n \talgo->init_fn(c);\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538396","messageId":"98bc36bb3ed8f5028442499f1b0d9731049e0b26.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 4/8] environment: move \"pack_compression_level\" into `struct repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:25Z","receivedAt":"2026-03-10T12:07:49Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `pack_compression_level` configuration is currently stored in the\nglobal variable `pack_compression_level`, which makes it shared across\nrepository instances within a single process.\n\nStore it instead in `repo_config_values` so the value is associated\nwith the repository from which it was read. This preserves existing\nbehavior while avoiding cross-repository state leakage and is another\nstep toward eliminating repository-dependent global state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n builtin/fast-import.c  | 8 +++++---\n builtin/pack-objects.c | 8 ++++++--\n environment.c          | 8 +++++---\n environment.h          | 2 +-\n object-file.c          | 3 ++-\n 5 files changed, 19 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex b8a7757cfd..6475cdae85 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -963,6 +963,7 @@ static int store_object(\n \tunsigned long hdrlen, deltalen;\n \tstruct git_hash_ctx c;\n \tgit_zstream s;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \thdrlen = format_object_header((char *)hdr, sizeof(hdr), type,\n \t\t\t\t      dat->len);\n@@ -1001,7 +1002,7 @@ static int store_object(\n \t} else\n \t\tdelta = NULL;\n \n-\tgit_deflate_init(&s, pack_compression_level);\n+\tgit_deflate_init(&s, cfg->pack_compression_level);\n \tif (delta) {\n \t\ts.next_in = delta;\n \t\ts.avail_in = deltalen;\n@@ -1028,7 +1029,7 @@ static int store_object(\n \t\tif (delta) {\n \t\t\tFREE_AND_NULL(delta);\n \n-\t\t\tgit_deflate_init(&s, pack_compression_level);\n+\t\t\tgit_deflate_init(&s, cfg->pack_compression_level);\n \t\t\ts.next_in = (void *)dat->buf;\n \t\t\ts.avail_in = dat->len;\n \t\t\ts.avail_out = git_deflate_bound(&s, s.avail_in);\n@@ -1111,6 +1112,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)\n \tstruct git_hash_ctx c;\n \tgit_zstream s;\n \tstruct hashfile_checkpoint checkpoint;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tint status = Z_OK;\n \n \t/* Determine if we should auto-checkpoint. */\n@@ -1130,7 +1132,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)\n \n \tcrc32_begin(pack_file);\n \n-\tgit_deflate_init(&s, pack_compression_level);\n+\tgit_deflate_init(&s, cfg->pack_compression_level);\n \n \thdrlen = encode_in_pack_object_header(out_buf, out_sz, OBJ_BLOB, len);\n \ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex c1ee4d5ed7..f5164486ea 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -383,8 +383,9 @@ static unsigned long do_compress(void **pptr, unsigned long size)\n \tgit_zstream stream;\n \tvoid *in, *out;\n \tunsigned long maxsize;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tgit_deflate_init(&stream, pack_compression_level);\n+\tgit_deflate_init(&stream, cfg->pack_compression_level);\n \tmaxsize = git_deflate_bound(&stream, size);\n \n \tin = *pptr;\n@@ -410,8 +411,9 @@ static unsigned long write_large_blob_data(struct odb_read_stream *st, struct ha\n \tunsigned char ibuf[1024 * 16];\n \tunsigned char obuf[1024 * 16];\n \tunsigned long olen = 0;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tgit_deflate_init(&stream, pack_compression_level);\n+\tgit_deflate_init(&stream, cfg->pack_compression_level);\n \n \tfor (;;) {\n \t\tssize_t readlen;\n@@ -4868,6 +4870,8 @@ int cmd_pack_objects(int argc,\n \tstruct string_list keep_pack_list = STRING_LIST_INIT_NODUP;\n \tstruct list_objects_filter_options filter_options =\n \t\tLIST_OBJECTS_FILTER_INIT;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\tint pack_compression_level = cfg->pack_compression_level;\n \n \tstruct option pack_objects_options[] = {\n \t\tOPT_CALLBACK_F('q', \"quiet\", &progress, NULL,\ndiff --git a/environment.c b/environment.c\nindex 5b0e88b65c..d0d3a4b7d2 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -52,7 +52,6 @@ char *git_commit_encoding;\n char *git_log_output_encoding;\n char *apply_default_whitespace;\n char *apply_default_ignorewhitespace;\n-int pack_compression_level = Z_DEFAULT_COMPRESSION;\n int fsync_object_files = -1;\n int use_fsync = -1;\n enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;\n@@ -390,7 +389,7 @@ int git_default_core_config(const char *var, const char *value,\n \t\tif (!zlib_compression_seen)\n \t\t\tcfg->zlib_compression_level = level;\n \t\tif (!pack_compression_seen)\n-\t\t\tpack_compression_level = level;\n+\t\t\tcfg->pack_compression_level = level;\n \t\treturn 0;\n \t}\n \n@@ -662,6 +661,8 @@ static int git_default_attr_config(const char *var, const char *value)\n int git_default_config(const char *var, const char *value,\n \t\t       const struct config_context *ctx, void *cb)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n \tif (starts_with(var, \"core.\"))\n \t\treturn git_default_core_config(var, value, ctx, cb);\n \n@@ -701,7 +702,7 @@ int git_default_config(const char *var, const char *value,\n \t\t\tlevel = Z_DEFAULT_COMPRESSION;\n \t\telse if (level < 0 || level > Z_BEST_COMPRESSION)\n \t\t\tdie(_(\"bad pack compression level %d\"), level);\n-\t\tpack_compression_level = level;\n+\t\tcfg->pack_compression_level = level;\n \t\tpack_compression_seen = 1;\n \t\treturn 0;\n \t}\n@@ -721,4 +722,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->trust_ctime = 1;\n \tcfg->check_stat = 1;\n \tcfg->zlib_compression_level = Z_BEST_SPEED;\n+\tcfg->pack_compression_level = Z_DEFAULT_COMPRESSION;\n }\ndiff --git a/environment.h b/environment.h\nindex 93201620af..514576b67a 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -94,6 +94,7 @@ struct repo_config_values {\n \tint trust_ctime;\n \tint check_stat;\n \tint zlib_compression_level;\n+\tint pack_compression_level;\n \n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n@@ -171,7 +172,6 @@ extern int assume_unchanged;\n extern int warn_on_object_refname_ambiguity;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n-extern int pack_compression_level;\n extern unsigned long pack_size_limit_cfg;\n \n extern int precomposed_unicode;\ndiff --git a/object-file.c b/object-file.c\nindex 8b719a915c..87179fc667 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -1420,8 +1420,9 @@ static int stream_blob_to_pack(struct transaction_packfile *state,\n \tint status = Z_OK;\n \tint write_object = (flags & INDEX_WRITE_OBJECT);\n \toff_t offset = 0;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tgit_deflate_init(&s, pack_compression_level);\n+\tgit_deflate_init(&s, cfg->pack_compression_level);\n \n \thdrlen = encode_in_pack_object_header(obuf, sizeof(obuf), OBJ_BLOB, size);\n \ts.next_out = obuf + hdrlen;\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538397","messageId":"48af23a0d6ea26659d0c51ffe3d1835c12627a02.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 5/8] environment: move \"precomposed_unicode\" into `struct repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:26Z","receivedAt":"2026-03-10T12:07:53Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `core.precomposeunicode` configuration is currently stored in the\nglobal variable `precomposed_unicode`, which makes it shared across\nrepository instances within a single process.\n\nStore it instead in `repo_config_values` so the value is associated\nwith the repository from which it was read. This preserves existing\nbehavior while avoiding cross-repository state leakage and is another\nstep toward eliminating repository-dependent global state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n compat/precompose_utf8.c | 20 +++++++++++++-------\n environment.c            |  4 ++--\n environment.h            |  2 +-\n upload-pack.c            |  3 ++-\n 4 files changed, 18 insertions(+), 11 deletions(-)\n\ndiff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c\nindex 43b3be0114..0e94dbd862 100644\n--- a/compat/precompose_utf8.c\n+++ b/compat/precompose_utf8.c\n@@ -48,16 +48,18 @@ void probe_utf8_pathname_composition(void)\n \tstatic const char *auml_nfc = \"\\xc3\\xa4\";\n \tstatic const char *auml_nfd = \"\\x61\\xcc\\x88\";\n \tint output_fd;\n-\tif (precomposed_unicode != -1)\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n+\tif (cfg->precomposed_unicode != -1)\n \t\treturn; /* We found it defined in the global config, respect it */\n \trepo_git_path_replace(the_repository, &path, \"%s\", auml_nfc);\n \toutput_fd = open(path.buf, O_CREAT|O_EXCL|O_RDWR, 0600);\n \tif (output_fd >= 0) {\n \t\tclose(output_fd);\n \t\trepo_git_path_replace(the_repository, &path, \"%s\", auml_nfd);\n-\t\tprecomposed_unicode = access(path.buf, R_OK) ? 0 : 1;\n+\t\tcfg->precomposed_unicode = access(path.buf, R_OK) ? 0 : 1;\n \t\trepo_config_set(the_repository, \"core.precomposeunicode\",\n-\t\t\t\tprecomposed_unicode ? \"true\" : \"false\");\n+\t\t\t\tcfg->precomposed_unicode ? \"true\" : \"false\");\n \t\trepo_git_path_replace(the_repository, &path, \"%s\", auml_nfc);\n \t\tif (unlink(path.buf))\n \t\t\tdie_errno(_(\"failed to unlink '%s'\"), path.buf);\n@@ -69,14 +71,16 @@ const char *precompose_string_if_needed(const char *in)\n {\n \tsize_t inlen;\n \tsize_t outlen;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n \tif (!in)\n \t\treturn NULL;\n \tif (has_non_ascii(in, (size_t)-1, &inlen)) {\n \t\ticonv_t ic_prec;\n \t\tchar *out;\n-\t\tif (precomposed_unicode < 0)\n-\t\t\trepo_config_get_bool(the_repository, \"core.precomposeunicode\", &precomposed_unicode);\n-\t\tif (precomposed_unicode != 1)\n+\t\tif (cfg->precomposed_unicode < 0)\n+\t\t\trepo_config_get_bool(the_repository, \"core.precomposeunicode\", &cfg->precomposed_unicode);\n+\t\tif (cfg->precomposed_unicode != 1)\n \t\t\treturn in;\n \t\tic_prec = iconv_open(repo_encoding, path_encoding);\n \t\tif (ic_prec == (iconv_t) -1)\n@@ -130,7 +134,9 @@ PREC_DIR *precompose_utf8_opendir(const char *dirname)\n \n struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tstruct dirent *res;\n+\n \tres = readdir(prec_dir->dirp);\n \tif (res) {\n \t\tsize_t namelenz = strlen(res->d_name) + 1; /* \\0 */\n@@ -149,7 +155,7 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir)\n \t\tprec_dir->dirent_nfc->d_ino  = res->d_ino;\n \t\tprec_dir->dirent_nfc->d_type = res->d_type;\n \n-\t\tif ((precomposed_unicode == 1) && has_non_ascii(res->d_name, (size_t)-1, NULL)) {\n+\t\tif ((cfg->precomposed_unicode == 1) && has_non_ascii(res->d_name, (size_t)-1, NULL)) {\n \t\t\tif (prec_dir->ic_precompose == (iconv_t)-1) {\n \t\t\t\tdie(\"iconv_open(%s,%s) failed, but needed:\\n\"\n \t\t\t\t\t\t\"    precomposed unicode is not supported.\\n\"\ndiff --git a/environment.c b/environment.c\nindex d0d3a4b7d2..739b647ebe 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -72,7 +72,6 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;\n int grafts_keep_true_parents;\n int core_sparse_checkout_cone;\n int sparse_expect_files_outside_of_patterns;\n-int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */\n unsigned long pack_size_limit_cfg;\n \n #ifndef PROTECT_HFS_DEFAULT\n@@ -532,7 +531,7 @@ int git_default_core_config(const char *var, const char *value,\n \t}\n \n \tif (!strcmp(var, \"core.precomposeunicode\")) {\n-\t\tprecomposed_unicode = git_config_bool(var, value);\n+\t\tcfg->precomposed_unicode = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n \n@@ -723,4 +722,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->check_stat = 1;\n \tcfg->zlib_compression_level = Z_BEST_SPEED;\n \tcfg->pack_compression_level = Z_DEFAULT_COMPRESSION;\n+\tcfg->precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */\n }\ndiff --git a/environment.h b/environment.h\nindex 514576b67a..508cb1afbc 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -95,6 +95,7 @@ struct repo_config_values {\n \tint check_stat;\n \tint zlib_compression_level;\n \tint pack_compression_level;\n+\tint precomposed_unicode;\n \n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n@@ -174,7 +175,6 @@ extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n extern unsigned long pack_size_limit_cfg;\n \n-extern int precomposed_unicode;\n extern int protect_hfs;\n extern int protect_ntfs;\n \ndiff --git a/upload-pack.c b/upload-pack.c\nindex 88dac1b65c..afa3ef7655 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -1288,6 +1288,7 @@ static int upload_pack_config(const char *var, const char *value,\n \t\t\t      void *cb_data)\n {\n \tstruct upload_pack_data *data = cb_data;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (!strcmp(\"uploadpack.allowtipsha1inwant\", var)) {\n \t\tif (git_config_bool(var, value))\n@@ -1318,7 +1319,7 @@ static int upload_pack_config(const char *var, const char *value,\n \t\tif (value)\n \t\t\tdata->allow_packfile_uris = 1;\n \t} else if (!strcmp(\"core.precomposeunicode\", var)) {\n-\t\tprecomposed_unicode = git_config_bool(var, value);\n+\t\tcfg->precomposed_unicode = git_config_bool(var, value);\n \t} else if (!strcmp(\"transfer.advertisesid\", var)) {\n \t\tdata->advertise_sid = git_config_bool(var, value);\n \t}\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538398","messageId":"b376cc9408f9e35adc7d45bf8d3c30a1ae945445.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 6/8] env: move \"core_sparse_checkout_cone\" into `struct repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:27Z","receivedAt":"2026-03-10T12:07:58Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `core_sparse_checkout_cone` variable was previously a global integer,\nuninitialized by default. Storing repository-dependent configuration in\nglobals can lead to cross-repository state leakage.\n\nMove it into `repo_config_values` and initialize it to 0 by default.\nThis ensures predictable behavior for repositories that do not set\nthis configuration while preserving existing semantics.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n builtin/mv.c              |  2 +-\n builtin/sparse-checkout.c | 37 ++++++++++++++++++++++---------------\n dir.c                     |  3 ++-\n environment.c             |  4 ++--\n environment.h             |  2 +-\n sparse-index.c            |  2 +-\n 6 files changed, 29 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 2215d34e31..ef3a326c90 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -574,7 +574,7 @@ int cmd_mv(int argc,\n \n \t\tif (ignore_sparse &&\n \t\t    cfg->apply_sparse_checkout &&\n-\t\t    core_sparse_checkout_cone) {\n+\t\t    cfg->core_sparse_checkout_cone) {\n \t\t\t/*\n \t\t\t * NEEDSWORK: we are *not* paying attention to\n \t\t\t * \"out-to-out\" move (<source> is out-of-cone and\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex f4aa405da9..92d017b81f 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -73,7 +73,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n \n \tmemset(&pl, 0, sizeof(pl));\n \n-\tpl.use_cone_patterns = core_sparse_checkout_cone;\n+\tpl.use_cone_patterns = cfg->core_sparse_checkout_cone;\n \n \tsparse_filename = get_sparse_checkout_filename();\n \tres = add_patterns_from_file_to_list(sparse_filename, \"\", 0, &pl, NULL, 0);\n@@ -334,6 +334,7 @@ static int write_patterns_and_update(struct repository *repo,\n \tFILE *fp;\n \tstruct lock_file lk = LOCK_INIT;\n \tint result;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tsparse_filename = get_sparse_checkout_filename();\n \n@@ -353,7 +354,7 @@ static int write_patterns_and_update(struct repository *repo,\n \tif (!fp)\n \t\tdie_errno(_(\"unable to fdopen %s\"), get_lock_file_path(&lk));\n \n-\tif (core_sparse_checkout_cone)\n+\tif (cfg->core_sparse_checkout_cone)\n \t\twrite_cone_to_file(fp, pl);\n \telse\n \t\twrite_patterns_to_file(fp, pl);\n@@ -402,15 +403,15 @@ static enum sparse_checkout_mode update_cone_mode(int *cone_mode) {\n \n \t/* If not specified, use previous definition of cone mode */\n \tif (*cone_mode == -1 && cfg->apply_sparse_checkout)\n-\t\t*cone_mode = core_sparse_checkout_cone;\n+\t\t*cone_mode = cfg->core_sparse_checkout_cone;\n \n \t/* Set cone/non-cone mode appropriately */\n \tcfg->apply_sparse_checkout = 1;\n \tif (*cone_mode == 1 || *cone_mode == -1) {\n-\t\tcore_sparse_checkout_cone = 1;\n+\t\tcfg->core_sparse_checkout_cone = 1;\n \t\treturn MODE_CONE_PATTERNS;\n \t}\n-\tcore_sparse_checkout_cone = 0;\n+\tcfg->core_sparse_checkout_cone = 0;\n \treturn MODE_ALL_PATTERNS;\n }\n \n@@ -577,7 +578,9 @@ static void add_patterns_from_input(struct pattern_list *pl,\n \t\t\t\t    FILE *file)\n {\n \tint i;\n-\tif (core_sparse_checkout_cone) {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n+\tif (cfg->core_sparse_checkout_cone) {\n \t\tstruct strbuf line = STRBUF_INIT;\n \n \t\thashmap_init(&pl->recursive_hashmap, pl_hashmap_cmp, NULL, 0);\n@@ -636,13 +639,14 @@ static void add_patterns_cone_mode(int argc, const char **argv,\n \tstruct pattern_entry *pe;\n \tstruct hashmap_iter iter;\n \tstruct pattern_list existing;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tchar *sparse_filename = get_sparse_checkout_filename();\n \n \tadd_patterns_from_input(pl, argc, argv,\n \t\t\t\tuse_stdin ? stdin : NULL);\n \n \tmemset(&existing, 0, sizeof(existing));\n-\texisting.use_cone_patterns = core_sparse_checkout_cone;\n+\texisting.use_cone_patterns = cfg->core_sparse_checkout_cone;\n \n \tif (add_patterns_from_file_to_list(sparse_filename, \"\", 0,\n \t\t\t\t\t   &existing, NULL, 0))\n@@ -690,7 +694,7 @@ static int modify_pattern_list(struct repository *repo,\n \n \tswitch (m) {\n \tcase ADD:\n-\t\tif (core_sparse_checkout_cone)\n+\t\tif (cfg->core_sparse_checkout_cone)\n \t\t\tadd_patterns_cone_mode(args->nr, args->v, pl, use_stdin);\n \t\telse\n \t\t\tadd_patterns_literal(args->nr, args->v, pl, use_stdin);\n@@ -723,11 +727,12 @@ static void sanitize_paths(struct repository *repo,\n \t\t\t   const char *prefix, int skip_checks)\n {\n \tint i;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (!args->nr)\n \t\treturn;\n \n-\tif (prefix && *prefix && core_sparse_checkout_cone) {\n+\tif (prefix && *prefix && cfg->core_sparse_checkout_cone) {\n \t\t/*\n \t\t * The args are not pathspecs, so unfortunately we\n \t\t * cannot imitate how cmd_add() uses parse_pathspec().\n@@ -744,10 +749,10 @@ static void sanitize_paths(struct repository *repo,\n \tif (skip_checks)\n \t\treturn;\n \n-\tif (prefix && *prefix && !core_sparse_checkout_cone)\n+\tif (prefix && *prefix && !cfg->core_sparse_checkout_cone)\n \t\tdie(_(\"please run from the toplevel directory in non-cone mode\"));\n \n-\tif (core_sparse_checkout_cone) {\n+\tif (cfg->core_sparse_checkout_cone) {\n \t\tfor (i = 0; i < args->nr; i++) {\n \t\t\tif (args->v[i][0] == '/')\n \t\t\t\tdie(_(\"specify directories rather than patterns (no leading slash)\"));\n@@ -769,7 +774,7 @@ static void sanitize_paths(struct repository *repo,\n \t\tif (S_ISSPARSEDIR(ce->ce_mode))\n \t\t\tcontinue;\n \n-\t\tif (core_sparse_checkout_cone)\n+\t\tif (cfg->core_sparse_checkout_cone)\n \t\t\tdie(_(\"'%s' is not a directory; to treat it as a directory anyway, rerun with --skip-checks\"), args->v[i]);\n \t\telse\n \t\t\twarning(_(\"pass a leading slash before paths such as '%s' if you want a single file (see NON-CONE PROBLEMS in the git-sparse-checkout manual).\"), args->v[i]);\n@@ -836,6 +841,7 @@ static struct sparse_checkout_set_opts {\n static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n \t\t\t       struct repository *repo)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tint default_patterns_nr = 2;\n \tconst char *default_patterns[] = {\"/*\", \"!/*/\", NULL};\n \n@@ -873,7 +879,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n \t * non-cone mode, if nothing is specified, manually select just the\n \t * top-level directory (much as 'init' would do).\n \t */\n-\tif (!core_sparse_checkout_cone && !set_opts.use_stdin && argc == 0) {\n+\tif (!cfg->core_sparse_checkout_cone && !set_opts.use_stdin && argc == 0) {\n \t\tfor (int i = 0; i < default_patterns_nr; i++)\n \t\t\tstrvec_push(&patterns, default_patterns[i]);\n \t} else {\n@@ -977,7 +983,7 @@ static int sparse_checkout_clean(int argc, const char **argv,\n \tsetup_work_tree();\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to clean directories\"));\n-\tif (!core_sparse_checkout_cone)\n+\tif (!cfg->core_sparse_checkout_cone)\n \t\tdie(_(\"must be in a cone-mode sparse-checkout to clean directories\"));\n \n \targc = parse_options(argc, argv, prefix,\n@@ -1141,6 +1147,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *\n \tFILE *fp;\n \tint ret;\n \tstruct pattern_list pl = {0};\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tchar *sparse_filename;\n \tcheck_rules_opts.cone_mode = -1;\n \n@@ -1152,7 +1159,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *\n \t\tcheck_rules_opts.cone_mode = 1;\n \n \tupdate_cone_mode(&check_rules_opts.cone_mode);\n-\tpl.use_cone_patterns = core_sparse_checkout_cone;\n+\tpl.use_cone_patterns = cfg->core_sparse_checkout_cone;\n \tif (check_rules_opts.rules_file) {\n \t\tfp = xfopen(check_rules_opts.rules_file, \"r\");\n \t\tadd_patterns_from_input(&pl, argc, argv, fp);\ndiff --git a/dir.c b/dir.c\nindex 026d8516a9..2744b3e5ca 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -3508,8 +3508,9 @@ int get_sparse_checkout_patterns(struct pattern_list *pl)\n {\n \tint res;\n \tchar *sparse_filename = get_sparse_checkout_filename();\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tpl->use_cone_patterns = core_sparse_checkout_cone;\n+\tpl->use_cone_patterns = cfg->core_sparse_checkout_cone;\n \tres = add_patterns_from_file_to_list(sparse_filename, \"\", 0, pl, NULL, 0);\n \n \tfree(sparse_filename);\ndiff --git a/environment.c b/environment.c\nindex 739b647ebe..b0e873e9f5 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -70,7 +70,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;\n #endif\n enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;\n int grafts_keep_true_parents;\n-int core_sparse_checkout_cone;\n int sparse_expect_files_outside_of_patterns;\n unsigned long pack_size_limit_cfg;\n \n@@ -526,7 +525,7 @@ int git_default_core_config(const char *var, const char *value,\n \t}\n \n \tif (!strcmp(var, \"core.sparsecheckoutcone\")) {\n-\t\tcore_sparse_checkout_cone = git_config_bool(var, value);\n+\t\tcfg->core_sparse_checkout_cone = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n \n@@ -723,4 +722,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->zlib_compression_level = Z_BEST_SPEED;\n \tcfg->pack_compression_level = Z_DEFAULT_COMPRESSION;\n \tcfg->precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */\n+\tcfg->core_sparse_checkout_cone = 0;\n }\ndiff --git a/environment.h b/environment.h\nindex 508cb1afbc..befad9a388 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -96,6 +96,7 @@ struct repo_config_values {\n \tint zlib_compression_level;\n \tint pack_compression_level;\n \tint precomposed_unicode;\n+\tint core_sparse_checkout_cone;\n \n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n@@ -178,7 +179,6 @@ extern unsigned long pack_size_limit_cfg;\n extern int protect_hfs;\n extern int protect_ntfs;\n \n-extern int core_sparse_checkout_cone;\n extern int sparse_expect_files_outside_of_patterns;\n \n enum rebase_setup_type {\ndiff --git a/sparse-index.c b/sparse-index.c\nindex 13629c075d..53cb8d64fc 100644\n--- a/sparse-index.c\n+++ b/sparse-index.c\n@@ -154,7 +154,7 @@ int is_sparse_index_allowed(struct index_state *istate, int flags)\n {\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tif (!cfg->apply_sparse_checkout || !core_sparse_checkout_cone)\n+\tif (!cfg->apply_sparse_checkout || !cfg->core_sparse_checkout_cone)\n \t\treturn 0;\n \n \tif (!(flags & SPARSE_INDEX_MEMORY_ONLY)) {\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538399","messageId":"5e30c28b48f1ebc8bc4b830b55f2885521fa376d.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 7/8] env: put \"sparse_expect_files_outside_of_patterns\" in `repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:28Z","receivedAt":"2026-03-10T12:08:02Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `sparse_expect_files_outside_of_patterns` variable was previously\na global variable, which makes it shared across repository\ninstances within a single process.\n\nMove it into `repo_config_values`, this makes the  value  tied to the\nrepository from which it was read. This preserves existing behavior\nwhile avoiding cross-repository state leakage and is another step\ntoward eliminating repository-dependent global state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n environment.c  | 6 ++++--\n environment.h  | 5 +++--\n sparse-index.c | 2 +-\n 3 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/environment.c b/environment.c\nindex b0e873e9f5..57587ede56 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -70,7 +70,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;\n #endif\n enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;\n int grafts_keep_true_parents;\n-int sparse_expect_files_outside_of_patterns;\n unsigned long pack_size_limit_cfg;\n \n #ifndef PROTECT_HFS_DEFAULT\n@@ -550,8 +549,10 @@ int git_default_core_config(const char *var, const char *value,\n \n static int git_default_sparse_config(const char *var, const char *value)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n \tif (!strcmp(var, \"sparse.expectfilesoutsideofpatterns\")) {\n-\t\tsparse_expect_files_outside_of_patterns = git_config_bool(var, value);\n+\t\tcfg->sparse_expect_files_outside_of_patterns = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n \n@@ -723,4 +724,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->pack_compression_level = Z_DEFAULT_COMPRESSION;\n \tcfg->precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */\n \tcfg->core_sparse_checkout_cone = 0;\n+\tcfg->sparse_expect_files_outside_of_patterns = 0;\n }\ndiff --git a/environment.h b/environment.h\nindex befad9a388..609cdaa07f 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -98,6 +98,9 @@ struct repo_config_values {\n \tint precomposed_unicode;\n \tint core_sparse_checkout_cone;\n \n+\t/* section \"sparse\" config values */\n+\tint sparse_expect_files_outside_of_patterns;\n+\n \t/* section \"branch\" config values */\n \tenum branch_track branch_track;\n };\n@@ -179,8 +182,6 @@ extern unsigned long pack_size_limit_cfg;\n extern int protect_hfs;\n extern int protect_ntfs;\n \n-extern int sparse_expect_files_outside_of_patterns;\n-\n enum rebase_setup_type {\n \tAUTOREBASE_NEVER = 0,\n \tAUTOREBASE_LOCAL,\ndiff --git a/sparse-index.c b/sparse-index.c\nindex 53cb8d64fc..1ed769b78d 100644\n--- a/sparse-index.c\n+++ b/sparse-index.c\n@@ -675,7 +675,7 @@ void clear_skip_worktree_from_present_files(struct index_state *istate)\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (!cfg->apply_sparse_checkout ||\n-\t    sparse_expect_files_outside_of_patterns)\n+\t    cfg->sparse_expect_files_outside_of_patterns)\n \t\treturn;\n \n \tif (clear_skip_worktree_from_present_files_sparse(istate)) {\n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538400","messageId":"0d37266a75333305047b76cae95595987f45b903.1773127785.git.belkid98@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"[PATCH v1 8/8] env: move \"warn_on_object_refname_ambiguity\" into `repo_config_values`","fromName":"Olamide Caleb Bello","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-10T12:06:29Z","receivedAt":"2026-03-10T12:08:06Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"The `warn_on_object_refname_ambiguity` variable was previously a global\ninteger, which makes it shared across repository instances in a single\nprocess.\n\nMove it into `repo_config_values` so the value is associated with the\nrepository from which it was read. This preserves existing behavior\nwhile avoiding cross-repository state leakage and is another step\ntoward eliminating repository-dependent global state.\n\nUpdate all references to use repo_config_values().\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>\nSigned-off-by: Olamide Caleb Bello <belkid98@gmail.com>\n---\n builtin/cat-file.c     | 7 ++++---\n builtin/pack-objects.c | 7 ++++---\n environment.c          | 2 +-\n environment.h          | 2 +-\n object-name.c          | 3 ++-\n revision.c             | 7 ++++---\n submodule.c            | 7 ++++---\n 7 files changed, 20 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex da059d0e26..32f60f2f64 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -897,6 +897,7 @@ static int batch_objects(struct batch_options *opt)\n \tstruct strbuf input = STRBUF_INIT;\n \tstruct strbuf output = STRBUF_INIT;\n \tstruct expand_data data = EXPAND_DATA_INIT;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tint save_warning;\n \tint retval = 0;\n \n@@ -969,8 +970,8 @@ static int batch_objects(struct batch_options *opt)\n \t * warn) ends up dwarfing the actual cost of the object lookups\n \t * themselves. We can work around it by just turning off the warning.\n \t */\n-\tsave_warning = warn_on_object_refname_ambiguity;\n-\twarn_on_object_refname_ambiguity = 0;\n+\tsave_warning = cfg->warn_on_object_refname_ambiguity;\n+\tcfg->warn_on_object_refname_ambiguity = 0;\n \n \tif (opt->batch_mode == BATCH_MODE_QUEUE_AND_DISPATCH) {\n \t\tbatch_objects_command(opt, &output, &data);\n@@ -998,7 +999,7 @@ static int batch_objects(struct batch_options *opt)\n  cleanup:\n \tstrbuf_release(&input);\n \tstrbuf_release(&output);\n-\twarn_on_object_refname_ambiguity = save_warning;\n+\tcfg->warn_on_object_refname_ambiguity = save_warning;\n \treturn retval;\n }\n \ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex f5164486ea..964c46d682 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -4653,6 +4653,7 @@ static void get_object_list(struct rev_info *revs, struct strvec *argv)\n \tstruct setup_revision_opt s_r_opt = {\n \t\t.allow_exclude_promisor_objects = 1,\n \t};\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tchar line[1000];\n \tint flags = 0;\n \tint save_warning;\n@@ -4663,8 +4664,8 @@ static void get_object_list(struct rev_info *revs, struct strvec *argv)\n \t/* make sure shallows are read */\n \tis_repository_shallow(the_repository);\n \n-\tsave_warning = warn_on_object_refname_ambiguity;\n-\twarn_on_object_refname_ambiguity = 0;\n+\tsave_warning = cfg->warn_on_object_refname_ambiguity;\n+\tcfg->warn_on_object_refname_ambiguity = 0;\n \n \twhile (fgets(line, sizeof(line), stdin) != NULL) {\n \t\tint len = strlen(line);\n@@ -4692,7 +4693,7 @@ static void get_object_list(struct rev_info *revs, struct strvec *argv)\n \t\t\tdie(_(\"bad revision '%s'\"), line);\n \t}\n \n-\twarn_on_object_refname_ambiguity = save_warning;\n+\tcfg->warn_on_object_refname_ambiguity = save_warning;\n \n \tif (use_bitmap_index && !get_object_list_from_bitmap(revs))\n \t\treturn;\ndiff --git a/environment.c b/environment.c\nindex 57587ede56..ba2c60103f 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -47,7 +47,6 @@ int minimum_abbrev = 4, default_abbrev = -1;\n int ignore_case;\n int assume_unchanged;\n int is_bare_repository_cfg = -1; /* unspecified */\n-int warn_on_object_refname_ambiguity = 1;\n char *git_commit_encoding;\n char *git_log_output_encoding;\n char *apply_default_whitespace;\n@@ -725,4 +724,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */\n \tcfg->core_sparse_checkout_cone = 0;\n \tcfg->sparse_expect_files_outside_of_patterns = 0;\n+\tcfg->warn_on_object_refname_ambiguity = 1;\n }\ndiff --git a/environment.h b/environment.h\nindex 609cdaa07f..1ff0a7ba8b 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -97,6 +97,7 @@ struct repo_config_values {\n \tint pack_compression_level;\n \tint precomposed_unicode;\n \tint core_sparse_checkout_cone;\n+\tint warn_on_object_refname_ambiguity;\n \n \t/* section \"sparse\" config values */\n \tint sparse_expect_files_outside_of_patterns;\n@@ -174,7 +175,6 @@ extern int has_symlinks;\n extern int minimum_abbrev, default_abbrev;\n extern int ignore_case;\n extern int assume_unchanged;\n-extern int warn_on_object_refname_ambiguity;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n extern unsigned long pack_size_limit_cfg;\ndiff --git a/object-name.c b/object-name.c\nindex 7b14c3bf9b..ddd863d293 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -969,11 +969,12 @@ static int get_oid_basic(struct repository *r, const char *str, int len,\n \tint refs_found = 0;\n \tint at, reflog_len, nth_prior = 0;\n \tint fatal = !(flags & GET_OID_QUIETLY);\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) {\n \t\tif (!(flags & GET_OID_SKIP_AMBIGUITY_CHECK) &&\n \t\t    repo_settings_get_warn_ambiguous_refs(r) &&\n-\t\t    warn_on_object_refname_ambiguity) {\n+\t\t    cfg->warn_on_object_refname_ambiguity) {\n \t\t\trefs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0);\n \t\t\tif (refs_found > 0) {\n \t\t\t\twarning(warn_msg, len, str);\ndiff --git a/revision.c b/revision.c\nindex 402eb1b029..cff821132b 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2904,9 +2904,10 @@ static void read_revisions_from_stdin(struct rev_info *revs,\n \tint seen_end_of_options = 0;\n \tint save_warning;\n \tint flags = 0;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsave_warning = warn_on_object_refname_ambiguity;\n-\twarn_on_object_refname_ambiguity = 0;\n+\tsave_warning = cfg->warn_on_object_refname_ambiguity;\n+\tcfg->warn_on_object_refname_ambiguity = 0;\n \n \tstrbuf_init(&sb, 1000);\n \twhile (strbuf_getline(&sb, stdin) != EOF) {\n@@ -2940,7 +2941,7 @@ static void read_revisions_from_stdin(struct rev_info *revs,\n \t\tread_pathspec_from_stdin(&sb, prune);\n \n \tstrbuf_release(&sb);\n-\twarn_on_object_refname_ambiguity = save_warning;\n+\tcfg->warn_on_object_refname_ambiguity = save_warning;\n }\n \n static void NORETURN diagnose_missing_default(const char *def)\ndiff --git a/submodule.c b/submodule.c\nindex 508938e4da..486b41011c 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -898,12 +898,13 @@ static void collect_changed_submodules(struct repository *r,\n \tstruct setup_revision_opt s_r_opt = {\n \t\t.assume_dashdash = 1,\n \t};\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsave_warning = warn_on_object_refname_ambiguity;\n-\twarn_on_object_refname_ambiguity = 0;\n+\tsave_warning = cfg->warn_on_object_refname_ambiguity;\n+\tcfg->warn_on_object_refname_ambiguity = 0;\n \trepo_init_revisions(r, &rev, NULL);\n \tsetup_revisions_from_strvec(argv, &rev, &s_r_opt);\n-\twarn_on_object_refname_ambiguity = save_warning;\n+\tcfg->warn_on_object_refname_ambiguity = save_warning;\n \tif (prepare_revision_walk(&rev))\n \t\tdie(_(\"revision walk setup failed\"));\n \n-- \n2.53.0.155.g9f36b15afa\n\n"},{"id":"538410","messageId":"CAP8UFD1t4Xs=xYW4uzqi7Ybc7Wz0nGMTkucCt5UxVnKTO1KE8w@mail.gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"Re: [PATCH v1 0/8] repo_config_values: migrate more globals","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2026-03-10T12:31:27Z","receivedAt":"2026-03-10T12:31:40Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Mar 10, 2026 at 1:07 PM Olamide Caleb Bello <belkid98@gmail.com> wrote:\n>\n> Base series\n> ===========\n> This series builds on top of the merged series:\n>   [PATCH v7 0/3] Move repo-specific globals into repo_config_values\n>\n> available at:\n>   https://lore.kernel.org/git/<cover.1771258573.git.belkid98@gmail.com>\n>\n> It should be applied on top of that series.\n\nThe above was interesting when the \"Move repo-specific globals into\nrepo_config_values\" series wasn't merged to master. But now that it\nhas been merged, you can remove it.\n\nThanks.\n"},{"id":"538716","messageId":"9f9a2e8e-6db7-4105-ba2b-7e42bff2ad1a@gmail.com","threadId":"65197","inReplyTo":"cover.1773127785.git.belkid98@gmail.com","subject":"Re: [PATCH v1 0/8] repo_config_values: migrate more globals","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-03-12T05:03:11Z","receivedAt":"2026-03-12T05:03:17Z","isPatch":true,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi Olamide,\n\nOn 3/10/26 20:06, Olamide Caleb Bello wrote:\n>   \tint status = Z_OK;\n>   \tint write_object = (flags & INDEX_WRITE_OBJECT);\n>   \toff_t offset = 0;\n> +\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n>   \n> -\tgit_deflate_init(&s, pack_compression_level);\n> +\tgit_deflate_init(&s, cfg->pack_compression_level);\n>   \n>   \thdrlen = encode_in_pack_object_header(obuf, sizeof(obuf), OBJ_BLOB, size);\n>   \ts.next_out = obuf + hdrlen;\n\nI didn't look closely at the other parts, but I have a small question \nabout this section.\n\npack_compression_level before this patch is a global variable:\n\n\tint pack_compression_level = Z_DEFAULT_COMPRESSION;\n\nand struct option  in cmd_pack_objects contains its pointer:\n\nstruct option pack_objects_options[] = {\n\t...\n\tOPT_INTEGER(0, \"compression\", &pack_compression_level, ...),\n\t...\n};\n\nThe reason why functions such as do_compress, write_large_blob_data can \nwork properly is beacuse they all read the same global variable, right?\n\n\nHowever, in this patch,\n\n> +\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n> +\tint pack_compression_level = cfg->pack_compression_level;\n\nHere, a local variable with the same name was created via value \nassignment (I also find the naming a bit odd).\n\n> @@ -383,8 +383,9 @@ static unsigned long do_compress(void **pptr, unsigned long size)\n>  \tgit_zstream stream;\n>  \tvoid *in, *out;\n>  \tunsigned long maxsize;\n> +\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n>  \n> -\tgit_deflate_init(&stream, pack_compression_level);\n> +\tgit_deflate_init(&stream, cfg->pack_compression_level);\n>  \tmaxsize = git_deflate_bound(&stream, size);\n\nBut then in the do_compress() function, the variable being read is still \nthat pointer, cfg->pack_compression_level. The expected input wasn't \n*written back* to this pointer, right? If I understand correctly, after \nparsing CLI, the output is written to the local variable rather than the \ncfg. And that's why the naming is a bit confusing to me.\n\nstruct option pack_objects_options[] = {\n\t...\n\tOPT_INTEGER(0, \"compression\", &cfg->pack_compression_level, ...),\n\t...\n};\n\nI think change like this is needed. Of course, you'll need to \ndouble-check it. _(:3 」∠ )_\n\nRegards,\n\nYuchen\n"},{"id":"538741","messageId":"CAD=f0L_HkyRNYk07Laq77gr8+JLaHeVxTwFN5eqC9-rLjgNRvA@mail.gmail.com","threadId":"65197","inReplyTo":"9f9a2e8e-6db7-4105-ba2b-7e42bff2ad1a@gmail.com","subject":"Re: [PATCH v1 0/8] repo_config_values: migrate more globals","fromName":"Bello Olamide","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-12T12:46:23Z","receivedAt":"2026-03-12T12:46:36Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"Hi Yuchen,\n\nThanks for taking a close look.\n\nMy intention here was mainly to avoid repeating `cfg->pack_compression_level`\nmultiple times in the function, so I introduced a local\n`pack_compression_level` initialized from `cfg->pack_compression_level`.\n\nBut you are right to point out the interaction with the CLI option. The\n--compression option currently writes to the local variable via\nOPT_INTEGER, and the value is not propagated back to\n`cfg->pack_compression_level`.\n\nI took a second look at it and will change the option to write\ndirectly into `cfg->pack_compression_level instead` in upcoming versions.\n\nThanks for pointing this out.\n\nBest,\nOlamide\n\nOn Thu, 12 Mar 2026 at 06:03, Tian Yuchen <a3205153416@gmail.com> wrote:\n>\n> Hi Olamide,\n>\n> On 3/10/26 20:06, Olamide Caleb Bello wrote:\n> >       int status = Z_OK;\n> >       int write_object = (flags & INDEX_WRITE_OBJECT);\n> >       off_t offset = 0;\n> > +     struct repo_config_values *cfg = repo_config_values(the_repository);\n> >\n> > -     git_deflate_init(&s, pack_compression_level);\n> > +     git_deflate_init(&s, cfg->pack_compression_level);\n> >\n> >       hdrlen = encode_in_pack_object_header(obuf, sizeof(obuf), OBJ_BLOB, size);\n> >       s.next_out = obuf + hdrlen;\n>\n> I didn't look closely at the other parts, but I have a small question\n> about this section.\n>\n> pack_compression_level before this patch is a global variable:\n>\n>         int pack_compression_level = Z_DEFAULT_COMPRESSION;\n>\n> and struct option  in cmd_pack_objects contains its pointer:\n>\n> struct option pack_objects_options[] = {\n>         ...\n>         OPT_INTEGER(0, \"compression\", &pack_compression_level, ...),\n>         ...\n> };\n>\n> The reason why functions such as do_compress, write_large_blob_data can\n> work properly is beacuse they all read the same global variable, right?\n>\n>\n> However, in this patch,\n>\n> > +     struct repo_config_values *cfg = repo_config_values(the_repository);\n> > +     int pack_compression_level = cfg->pack_compression_level;\n>\n> Here, a local variable with the same name was created via value\n> assignment (I also find the naming a bit odd).\n>\n> > @@ -383,8 +383,9 @@ static unsigned long do_compress(void **pptr, unsigned long size)\n> >       git_zstream stream;\n> >       void *in, *out;\n> >       unsigned long maxsize;\n> > +     struct repo_config_values *cfg = repo_config_values(the_repository);\n> >\n> > -     git_deflate_init(&stream, pack_compression_level);\n> > +     git_deflate_init(&stream, cfg->pack_compression_level);\n> >       maxsize = git_deflate_bound(&stream, size);\n>\n> But then in the do_compress() function, the variable being read is still\n> that pointer, cfg->pack_compression_level. The expected input wasn't\n> *written back* to this pointer, right? If I understand correctly, after\n> parsing CLI, the output is written to the local variable rather than the\n> cfg. And that's why the naming is a bit confusing to me.\n>\n> struct option pack_objects_options[] = {\n>         ...\n>         OPT_INTEGER(0, \"compression\", &cfg->pack_compression_level, ...),\n>         ...\n> };\n>\n> I think change like this is needed. Of course, you'll need to\n> double-check it. _(:3 」∠ )_\n>\n> Regards,\n>\n> Yuchen\n"},{"id":"538743","messageId":"CAD=f0L8phuDNSvJJ8GdPxM_W-o01uUduN29XHDaKT7tu0bTGvQ@mail.gmail.com","threadId":"65197","inReplyTo":"CAP8UFD1t4Xs=xYW4uzqi7Ybc7Wz0nGMTkucCt5UxVnKTO1KE8w@mail.gmail.com","subject":"Re: [PATCH v1 0/8] repo_config_values: migrate more globals","fromName":"Bello Olamide","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-12T12:55:08Z","receivedAt":"2026-03-12T12:55:20Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"On Tue, 10 Mar 2026 at 13:31, Christian Couder\n<christian.couder@gmail.com> wrote:\n>\n> On Tue, Mar 10, 2026 at 1:07 PM Olamide Caleb Bello <belkid98@gmail.com> wrote:\n> >\n> > Base series\n> > ===========\n> > This series builds on top of the merged series:\n> >   [PATCH v7 0/3] Move repo-specific globals into repo_config_values\n> >\n> > available at:\n> >   https://lore.kernel.org/git/<cover.1771258573.git.belkid98@gmail.com>\n> >\n> > It should be applied on top of that series.\n>\n> The above was interesting when the \"Move repo-specific globals into\n> repo_config_values\" series wasn't merged to master. But now that it\n> has been merged, you can remove it.\n>\n> Thanks.\n\nThank you, Christian.\n\nI will remove it in subsequent versions\n"},{"id":"538744","messageId":"CAD=f0L9V14gdTgYzQ6aXqq9U8vmi-BozhmHAPVCaSR+2VYythw@mail.gmail.com","threadId":"65197","inReplyTo":"9f9a2e8e-6db7-4105-ba2b-7e42bff2ad1a@gmail.com","subject":"Re: [PATCH v1 0/8] repo_config_values: migrate more globals","fromName":"Bello Olamide","fromEmail":"belkid98@gmail.com","sentAt":"2026-03-12T13:18:51Z","receivedAt":"2026-03-12T13:19:04Z","isPatch":true,"sender":{"key":"belkid98@gmail.com","avatar":"https://avatars.githubusercontent.com/u/73387291?v=4"},"body":"On Thu, 12 Mar 2026 at 06:03, Tian Yuchen <a3205153416@gmail.com> wrote:\n>\n> Hi Olamide,\n>\n> On 3/10/26 20:06, Olamide Caleb Bello wrote:\n> >       int status = Z_OK;\n> >       int write_object = (flags & INDEX_WRITE_OBJECT);\n> >       off_t offset = 0;\n> > +     struct repo_config_values *cfg = repo_config_values(the_repository);\n> >\n> > -     git_deflate_init(&s, pack_compression_level);\n> > +     git_deflate_init(&s, cfg->pack_compression_level);\n> >\n> >       hdrlen = encode_in_pack_object_header(obuf, sizeof(obuf), OBJ_BLOB, size);\n> >       s.next_out = obuf + hdrlen;\n>\n> I didn't look closely at the other parts, but I have a small question\n> about this section.\n>\n> pack_compression_level before this patch is a global variable:\n>\n>         int pack_compression_level = Z_DEFAULT_COMPRESSION;\n>\n> and struct option  in cmd_pack_objects contains its pointer:\n>\n> struct option pack_objects_options[] = {\n>         ...\n>         OPT_INTEGER(0, \"compression\", &pack_compression_level, ...),\n>         ...\n> };\n>\n> The reason why functions such as do_compress, write_large_blob_data can\n> work properly is beacuse they all read the same global variable, right?\n>\n>\n> However, in this patch,\n>\n> > +     struct repo_config_values *cfg = repo_config_values(the_repository);\n> > +     int pack_compression_level = cfg->pack_compression_level;\n>\n> Here, a local variable with the same name was created via value\n> assignment (I also find the naming a bit odd).\n>\n> > @@ -383,8 +383,9 @@ static unsigned long do_compress(void **pptr, unsigned long size)\n> >       git_zstream stream;\n> >       void *in, *out;\n> >       unsigned long maxsize;\n> > +     struct repo_config_values *cfg = repo_config_values(the_repository);\n> >\n> > -     git_deflate_init(&stream, pack_compression_level);\n> > +     git_deflate_init(&stream, cfg->pack_compression_level);\n> >       maxsize = git_deflate_bound(&stream, size);\n>\n> But then in the do_compress() function, the variable being read is still\n> that pointer, cfg->pack_compression_level. The expected input wasn't\n> *written back* to this pointer, right? If I understand correctly, after\n> parsing CLI, the output is written to the local variable rather than the\n> cfg. And that's why the naming is a bit confusing to me.\n>\n> struct option pack_objects_options[] = {\n>         ...\n>         OPT_INTEGER(0, \"compression\", &cfg->pack_compression_level, ...),\n>         ...\n> };\n>\n> I think change like this is needed. Of course, you'll need to\n> double-check it. _(:3 」∠ )_\n>\n> Regards,\n>\n> Yuchen\n\nHi Yuchen,\n\nThanks for taking a close look.\n\nMy intention here was mainly to avoid repeating `cfg->pack_compression_level`\nmultiple times in the function, so I introduced a local\n`pack_compression_level` initialized from `cfg->pack_compression_level`.\n\nBut you are right to point out the interaction with the CLI option. The\n--compression option currently writes to the local variable via\nOPT_INTEGER, and the value is not propagated back to\n`cfg->pack_compression_level`.\n\nI took a second look at it and will change the option to write\ndirectly into `cfg->pack_compression_level instead` in upcoming versions.\n\nThanks for pointing this out.\n\nBest regards,\nOlamide Caleb Bello\n"}]}