{"thread":{"id":"66062","subject":"[PATCH v1 0/3] environment: migrate more global variables, pt.2","startedAt":"2026-07-25T11:54:38Z","lastAt":"2026-07-28T01:46:46Z","messageCount":9,"participants":["Tian Yuchen","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"548954","messageId":"20260725115428.2214202-1-cat@malon.dev","threadId":"66062","inReplyTo":null,"subject":"[PATCH v1 0/3] environment: migrate more global variables, pt.2","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-25T11:54:25Z","receivedAt":"2026-07-25T11:54:38Z","isPatch":true,"body":"Hi all,\n\nThis series moves:\n\n - (1/3) minimum_abbrev and default_abbrev \n - (2/3) pack_size_limit_cfg\n - (3/3) assume_unchanged\n\ninto repo_config_values to continue the libification effort. \n\nNote: in commit 1/3, we need (repo != the_repository) checks in the\ngetters, because some subsystems where the readers of _abbrev\nconfigurations live forbid the use of 'the_repository' and only accept\n'repo' [1]. We have to explicitly intercept those intances that are\nnot 'the_repository'.\n\nThanks! yuchen\n\n [1] [PATCH v3 5/6] merge-ort: prevent the_repository from coming back\n https://lore.kernel.org/git/42a25768784492a4e8187bad0b070ccb27e980f7.1771718393.git.gitgitgadget@gmail.com/\n\nTian Yuchen (3):\n  environment: migrate minimum_abbrev and default_abbrev\n  environment: migrate pack_size_limit_cfg into repo_config_values\n  environment: migrate assume_unchanged into repo_config_values\n\n builtin/pack-objects.c |  2 +-\n builtin/update-index.c |  3 ++-\n environment.c          | 39 ++++++++++++++++++++++++++++++---------\n environment.h          | 11 ++++++++---\n merge-ort.c            |  7 ++++---\n object-file.c          |  5 +++--\n object-name.h          |  4 ++--\n read-cache.c           |  9 ++++++---\n replay.c               |  2 +-\n sequencer.c            |  5 +++--\n 10 files changed, 60 insertions(+), 27 deletions(-)\n\n-- \n2.43.0\n\n"},{"id":"548955","messageId":"20260725115428.2214202-2-cat@malon.dev","threadId":"66062","inReplyTo":"20260725115428.2214202-1-cat@malon.dev","subject":"[PATCH v1 1/3] environment: migrate minimum_abbrev and default_abbrev","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-25T11:54:26Z","receivedAt":"2026-07-25T11:54:40Z","isPatch":true,"body":"Move the global 'minimum_abbrev' and 'default_abbrev' configurations\ninto the repository-specific 'repo_config_values'\nstruct.\n\nTo ensure code readability, the getter functions\n'repo_minimum_abbrev()' and 'repo_default_abbrev()' have been introduced.\nThe existing MINIMUM_ABBREV and DEFAULT_ABBREV macros are redefined to\nthe corresponding getters.\n\nAdditionally, some subsystems forbid the direct use of 'the_repository'\nand must pass their own local 'repo'. Let the getters explicitly intercept\nthese instances.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>\nMentored-by: Olamide Caleb Bello <belkid98@gmail.com>\nSigned-off-by: Tian Yuchen <cat@malon.dev>\n---\n environment.c | 31 ++++++++++++++++++++++++++-----\n environment.h |  6 +++++-\n merge-ort.c   |  7 ++++---\n object-name.h |  4 ++--\n replay.c      |  2 +-\n sequencer.c   |  5 +++--\n 6 files changed, 41 insertions(+), 14 deletions(-)\n\ndiff --git a/environment.c b/environment.c\nindex c663113e8a..2b44778b50 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -43,7 +43,6 @@ static int zlib_compression_seen;\n \n int trust_executable_bit = 1;\n int has_symlinks = 1;\n-int minimum_abbrev = 4, default_abbrev = -1;\n int assume_unchanged;\n char *git_commit_encoding;\n char *git_log_output_encoding;\n@@ -148,6 +147,26 @@ int repo_ignore_case(struct repository *repo)\n \t\t0;\n }\n \n+int repo_minimum_abbrev(struct repository *repo)\n+{\n+\tif (repo != the_repository)\n+\t\trepo = the_repository;\n+\n+\treturn repo->initialized\n+\t\t? repo_config_values(repo)->minimum_abbrev\n+\t\t: 4;\n+}\n+\n+int repo_default_abbrev(struct repository *repo)\n+{\n+\tif (repo != the_repository)\n+\t\trepo = the_repository;\n+\n+\treturn repo->initialized\n+\t\t? repo_config_values(repo)->default_abbrev\n+\t\t: -1;\n+}\n+\n int have_git_dir(void)\n {\n \treturn startup_info->have_repository\n@@ -364,14 +383,14 @@ 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, \"auto\"))\n-\t\t\tdefault_abbrev = -1;\n+\t\t\tcfg->default_abbrev = -1;\n \t\telse if (!git_parse_maybe_bool_text(value))\n-\t\t\tdefault_abbrev = GIT_MAX_HEXSZ;\n+\t\t\tcfg->default_abbrev = GIT_MAX_HEXSZ;\n \t\telse {\n \t\t\tint abbrev = git_config_int(var, value, ctx->kvi);\n-\t\t\tif (abbrev < minimum_abbrev)\n+\t\t\tif (abbrev < cfg->minimum_abbrev)\n \t\t\t\treturn error(_(\"abbrev length out of range: %d\"), abbrev);\n-\t\t\tdefault_abbrev = abbrev;\n+\t\t\tcfg->default_abbrev = abbrev;\n \t\t}\n \t\treturn 0;\n \t}\n@@ -738,6 +757,8 @@ 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->minimum_abbrev = 4;\n+\tcfg->default_abbrev = -1;\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;\ndiff --git a/environment.h b/environment.h\nindex acfb670be1..c5905d8b01 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -95,6 +95,8 @@ struct repo_config_values {\n \tint check_stat;\n \tint zlib_compression_level;\n \tint pack_compression_level;\n+\tint minimum_abbrev;\n+\tint default_abbrev;\n \tint precomposed_unicode;\n \tint core_sparse_checkout_cone;\n \tint warn_on_object_refname_ambiguity;\n@@ -151,6 +153,9 @@ int repo_protect_ntfs(struct repository *repo);\n  */\n int repo_ignore_case(struct repository *repo);\n \n+int repo_minimum_abbrev(struct repository *repo);\n+int repo_default_abbrev(struct repository *repo);\n+\n void repo_config_values_init(struct repo_config_values *cfg);\n \n int is_bare_repository(struct repository *repo);\n@@ -180,7 +185,6 @@ int have_git_dir(void);\n /* Environment bits from configuration mechanism */\n extern int trust_executable_bit;\n extern int has_symlinks;\n-extern int minimum_abbrev, default_abbrev;\n extern int assume_unchanged;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\ndiff --git a/merge-ort.c b/merge-ort.c\nindex c410a5d353..b94ebcc2de 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -777,7 +777,7 @@ static void format_commit(struct strbuf *sb,\n {\n \tstruct merge_remote_desc *desc;\n \tstruct pretty_print_context ctx = {0};\n-\tctx.abbrev = DEFAULT_ABBREV;\n+\tctx.abbrev = repo_default_abbrev(repo);\n \n \tstrbuf_addchars(sb, ' ', indent);\n \tdesc = merge_remote_util(commit);\n@@ -2035,7 +2035,8 @@ static int merge_submodule(struct merge_options *opt,\n \t\tutil->flag = sub_flag;\n \t\tutil->abbrev = NULL;\n \t\tif (!sub_not_initialized) {\n-\t\t\tabbrev = repo_find_unique_abbrev(&subrepo, b, DEFAULT_ABBREV);\n+\t\t\tabbrev = repo_find_unique_abbrev(&subrepo, b,\n+\t\t\t\t\t\t\trepo_default_abbrev(opt->repo));\n \t\t\tutil->abbrev = xstrdup(abbrev);\n \t\t}\n \t\tstring_list_append(csub, path)->util = util;\n@@ -5348,7 +5349,7 @@ static void merge_ort_internal(struct merge_options *opt,\n \t} else {\n \t\tstrbuf_add_unique_abbrev(&merge_base_abbrev,\n \t\t\t\t\t &merged_merge_bases->object.oid,\n-\t\t\t\t\t DEFAULT_ABBREV);\n+\t\t\t\t\t repo_default_abbrev(opt->repo));\n \t\tancestor_name = merge_base_abbrev.buf;\n \t}\n \ndiff --git a/object-name.h b/object-name.h\nindex 167a9154ea..a6d7206ed8 100644\n--- a/object-name.h\n+++ b/object-name.h\n@@ -133,8 +133,8 @@ struct object *repo_peel_to_type(struct repository *r,\n \t\t\t\t struct object *o, enum object_type);\n \n /* Convert to/from hex/sha1 representation */\n-#define MINIMUM_ABBREV minimum_abbrev\n-#define DEFAULT_ABBREV default_abbrev\n+#define MINIMUM_ABBREV repo_minimum_abbrev(the_repository)\n+#define DEFAULT_ABBREV repo_default_abbrev(the_repository)\n \n /* used when the code does not know or care what the default abbrev is */\n #define FALLBACK_DEFAULT_ABBREV 7\ndiff --git a/replay.c b/replay.c\nindex 463c900d6c..cd41c7f507 100644\n--- a/replay.c\n+++ b/replay.c\n@@ -27,7 +27,7 @@ static const char *short_commit_name(struct repository *repo,\n \t\t\t\t     struct commit *commit)\n {\n \treturn repo_find_unique_abbrev(repo, &commit->object.oid,\n-\t\t\t\t       DEFAULT_ABBREV);\n+\t\t\t\t       repo_default_abbrev(repo));\n }\n \n static struct commit *peel_committish(struct repository *repo,\ndiff --git a/sequencer.c b/sequencer.c\nindex 1355a99a09..2426c5e422 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -5813,7 +5813,7 @@ static const char *label_oid(struct object_id *oid, const char *label,\n \t\tlabel = p = state->buf.buf;\n \n \t\trepo_find_unique_abbrev_r(the_repository, p, oid,\n-\t\t\t\t\t  default_abbrev);\n+\t\t\t\t\t  repo_default_abbrev(the_repository));\n \n \t\t/*\n \t\t * We may need to extend the abbreviated hash so that there is\n@@ -5875,7 +5875,8 @@ static const char *label_oid(struct object_id *oid, const char *label,\n \t\t\t\tstrbuf_addch(buf, '-');\n \t\tif (!buf->len) {\n \t\t\tstrbuf_addstr(buf, \"rev-\");\n-\t\t\tstrbuf_add_unique_abbrev(buf, oid, default_abbrev);\n+\t\t\tstrbuf_add_unique_abbrev(buf, oid,\n+\t\t\t\t\t\t repo_default_abbrev(the_repository));\n \t\t}\n \t\tlabel = buf->buf;\n \n-- \n2.43.0\n\n"},{"id":"548956","messageId":"20260725115428.2214202-3-cat@malon.dev","threadId":"66062","inReplyTo":"20260725115428.2214202-1-cat@malon.dev","subject":"[PATCH v1 2/3] environment: migrate pack_size_limit_cfg into repo_config_values","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-25T11:54:27Z","receivedAt":"2026-07-25T11:54:43Z","isPatch":true,"body":"Move the global 'pack_size_limit_cfg' configuration into the\nrepository-specific 'repo_config_values' struct.\n\nWe do not introduce a getter for it because the readers are\nlimited and no hardcoded fallback values are needed.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>\nMentored-by: Olamide Caleb Bello <belkid98@gmail.com>\nSigned-off-by: Tian Yuchen <cat@malon.dev>\n---\n builtin/pack-objects.c | 2 +-\n environment.c          | 4 ++--\n environment.h          | 3 ++-\n object-file.c          | 5 +++--\n 4 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 3673b14b89..4ebcaccb09 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -5328,7 +5328,7 @@ int cmd_pack_objects(int argc,\n \tif (!HAVE_THREADS && delta_search_threads != 1)\n \t\twarning(_(\"no threads support, ignoring --threads\"));\n \tif (!pack_to_stdout && !pack_size_limit)\n-\t\tpack_size_limit = pack_size_limit_cfg;\n+\t\tpack_size_limit = cfg->pack_size_limit_cfg;\n \tif (pack_to_stdout && pack_size_limit)\n \t\tdie(_(\"--max-pack-size cannot be used to build a pack for transfer\"));\n \tif (pack_size_limit && pack_size_limit < 1024*1024) {\ndiff --git a/environment.c b/environment.c\nindex 2b44778b50..ff731a9611 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -66,7 +66,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-unsigned long pack_size_limit_cfg;\n \n #ifndef PROTECT_HFS_DEFAULT\n #define PROTECT_HFS_DEFAULT 0\n@@ -723,7 +722,7 @@ int git_default_config(const char *var, const char *value,\n \t}\n \n \tif (!strcmp(var, \"pack.packsizelimit\")) {\n-\t\tpack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi);\n+\t\tcfg->pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi);\n \t\treturn 0;\n \t}\n \n@@ -763,4 +762,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\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+\tcfg->pack_size_limit_cfg = 0;\n }\ndiff --git a/environment.h b/environment.h\nindex c5905d8b01..c1d5bba2f0 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -103,6 +103,8 @@ struct repo_config_values {\n \tint protect_hfs;\n \tint protect_ntfs;\n \tint ignore_case;\n+\tunsigned long pack_size_limit_cfg;\n+\n \n \t/* section \"sparse\" config values */\n \tint sparse_expect_files_outside_of_patterns;\n@@ -188,7 +190,6 @@ extern int has_symlinks;\n extern int assume_unchanged;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n-extern unsigned long pack_size_limit_cfg;\n \n enum rebase_setup_type {\n \tAUTOREBASE_NEVER = 0,\ndiff --git a/object-file.c b/object-file.c\nindex 7ff2b730ac..be68eead63 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -1273,6 +1273,7 @@ static int odb_transaction_files_write_object_stream(struct odb_transaction *bas\n \t\t\t\t\t\t     size_t size,\n \t\t\t\t\t\t     struct object_id *result_oid)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tstruct odb_transaction_files *transaction = container_of(base,\n \t\t\t\t\t\t\t\t struct odb_transaction_files,\n \t\t\t\t\t\t\t\t base);\n@@ -1298,8 +1299,8 @@ static int odb_transaction_files_write_object_stream(struct odb_transaction *bas\n \t * the difference between the inflated and on-disk size is limited\n \t * to zlib compression and is sufficient for this check.\n \t */\n-\tif (state->nr_written && pack_size_limit_cfg &&\n-\t    pack_size_limit_cfg < state->offset + size)\n+\tif (state->nr_written && cfg->pack_size_limit_cfg &&\n+\t    cfg->pack_size_limit_cfg < state->offset + size)\n \t\tflush_packfile_transaction(transaction);\n \n \tCALLOC_ARRAY(idx, 1);\n-- \n2.43.0\n\n"},{"id":"548957","messageId":"20260725115428.2214202-4-cat@malon.dev","threadId":"66062","inReplyTo":"20260725115428.2214202-1-cat@malon.dev","subject":"[PATCH v1 3/3] environment: migrate assume_unchanged into repo_config_values","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-25T11:54:28Z","receivedAt":"2026-07-25T11:54:48Z","isPatch":true,"body":"Move the global 'assume_unchanged' configuration into the\nrepository-specific 'repo_config_values' struct.\n\nWe do not introduce a getter for it because the readers are\nlimited and no hardcoded fallback values are needed.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>\nMentored-by: Olamide Caleb Bello <belkid98@gmail.com>\nSigned-off-by: Tian Yuchen <cat@malon.dev>\n---\n builtin/update-index.c | 3 ++-\n environment.c          | 4 ++--\n environment.h          | 2 +-\n read-cache.c           | 9 ++++++---\n 4 files changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 4c4b39a157..3ef7e9bb90 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -419,6 +419,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n {\n \tint len, option;\n \tstruct cache_entry *ce;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (!verify_path(path, mode))\n \t\treturn error(\"Invalid path '%s'\", path);\n@@ -431,7 +432,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n \tce->ce_flags = create_ce_flags(stage);\n \tce->ce_namelen = len;\n \tce->ce_mode = create_ce_mode(mode);\n-\tif (assume_unchanged)\n+\tif (cfg->assume_unchanged)\n \t\tce->ce_flags |= CE_VALID;\n \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\ndiff --git a/environment.c b/environment.c\nindex ff731a9611..8fdb736023 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -43,7 +43,6 @@ static int zlib_compression_seen;\n \n int trust_executable_bit = 1;\n int has_symlinks = 1;\n-int assume_unchanged;\n char *git_commit_encoding;\n char *git_log_output_encoding;\n char *apply_default_whitespace;\n@@ -374,7 +373,7 @@ int git_default_core_config(const char *var, const char *value,\n \t}\n \n \tif (!strcmp(var, \"core.ignorestat\")) {\n-\t\tassume_unchanged = git_config_bool(var, value);\n+\t\tcfg->assume_unchanged = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n \n@@ -758,6 +757,7 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->pack_compression_level = Z_DEFAULT_COMPRESSION;\n \tcfg->minimum_abbrev = 4;\n \tcfg->default_abbrev = -1;\n+\tcfg->assume_unchanged = 0;\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;\ndiff --git a/environment.h b/environment.h\nindex c1d5bba2f0..a7e2bcbe30 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 minimum_abbrev;\n \tint default_abbrev;\n+\tint assume_unchanged;\n \tint precomposed_unicode;\n \tint core_sparse_checkout_cone;\n \tint warn_on_object_refname_ambiguity;\n@@ -187,7 +188,6 @@ int have_git_dir(void);\n /* Environment bits from configuration mechanism */\n extern int trust_executable_bit;\n extern int has_symlinks;\n-extern int assume_unchanged;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n \ndiff --git a/read-cache.c b/read-cache.c\nindex 38b55323dd..643b13f1fb 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -192,9 +192,11 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n\n  */\n void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, struct stat *st)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n \tfill_stat_data(&ce->ce_stat_data, st);\n \n-\tif (assume_unchanged)\n+\tif (cfg->assume_unchanged)\n \t\tce->ce_flags |= CE_VALID;\n \n \tif (S_ISREG(st->st_mode)) {\n@@ -1346,6 +1348,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,\n {\n \tstruct stat st;\n \tstruct cache_entry *updated;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tint changed;\n \tint refresh = options & CE_MATCH_REFRESH;\n \tint ignore_valid = options & CE_MATCH_IGNORE_VALID;\n@@ -1405,7 +1408,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,\n \t\t * is not marked VALID, this is the place to mark it\n \t\t * valid again, under \"assume unchanged\" mode.\n \t\t */\n-\t\tif (ignore_valid && assume_unchanged &&\n+\t\tif (ignore_valid && cfg->assume_unchanged &&\n \t\t    !(ce->ce_flags & CE_VALID))\n \t\t\t; /* mark this one VALID again */\n \t\telse {\n@@ -1440,7 +1443,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,\n \t * (i.e. things to be edited) will reacquire CE_VALID bit\n \t * automatically, which is not really what we want.\n \t */\n-\tif (!ignore_valid && assume_unchanged &&\n+\tif (!ignore_valid && cfg->assume_unchanged &&\n \t    !(ce->ce_flags & CE_VALID))\n \t\tupdated->ce_flags &= ~CE_VALID;\n \n-- \n2.43.0\n\n"},{"id":"548973","messageId":"xmqq5x23ypcf.fsf@gitster.g","threadId":"66062","inReplyTo":"20260725115428.2214202-1-cat@malon.dev","subject":"Re: [PATCH v1 0/3] environment: migrate more global variables, pt.2","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-25T17:02:40Z","receivedAt":"2026-07-25T17:02:43Z","isPatch":true,"body":"Tian Yuchen <cat@malon.dev> writes:\n\n> Hi all,\n>\n> This series moves:\n>\n>  - (1/3) minimum_abbrev and default_abbrev \n>  - (2/3) pack_size_limit_cfg\n>  - (3/3) assume_unchanged\n>\n> into repo_config_values to continue the libification effort. \n>\n> Note: in commit 1/3, we need (repo != the_repository) checks in the\n> getters, because some subsystems where the readers of _abbrev\n> configurations live forbid the use of 'the_repository' and only accept\n> 'repo' [1]. We have to explicitly intercept those intances that are\n> not 'the_repository'.\n\nSorry but I am not sure I follow.  If a repository that is not\nthe_repository is not yet allowed, shouldn't the caller be flagged\nfor passing a random repository that is not the_repository as not\nconforming to the API (yet) with:\n\n        if (repo != the_repository)\n                BUG(...);\n\nrather than papering over the issue with an unconditional\n\n        repo = the_repository;\n\noverride?\n\nIf the API that deals with this 'abbrev' setting needs to call\nanother API that only superficially takes any 'repo' parameter\nwithout supporting anything other than the_repository, isn't that a\nsign that the other API needs to be extended to work with any 'repo'\nbefore the 'abbrev' part of the system can use it, simply because the\nformer is not ready?  Futzing with the 'abbrev' part of the system in\nsuch a state piles on more unfinished work that will need to be fixed\nlater without achieving anything, except for the superficial \"now\nthis part too can take a 'repo' parameter, even though it does not\nsupport anything but the_repository\", no?\n\nPuzzled...\n"},{"id":"548979","messageId":"ab900bd2-0524-4122-8bb7-e3f57b0a86fc@malon.dev","threadId":"66062","inReplyTo":"xmqq5x23ypcf.fsf@gitster.g","subject":"Re: [PATCH v1 0/3] environment: migrate more global variables, pt.2","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-26T06:29:08Z","receivedAt":"2026-07-26T06:29:21Z","isPatch":true,"body":"On 7/26/26 01:02, Junio C Hamano wrote:\n> Tian Yuchen <cat@malon.dev> writes:\n> \n>> Hi all,\n>>\n>> This series moves:\n>>\n>>   - (1/3) minimum_abbrev and default_abbrev\n>>   - (2/3) pack_size_limit_cfg\n>>   - (3/3) assume_unchanged\n>>\n>> into repo_config_values to continue the libification effort.\n>>\n>> Note: in commit 1/3, we need (repo != the_repository) checks in the\n>> getters, because some subsystems where the readers of _abbrev\n>> configurations live forbid the use of 'the_repository' and only accept\n>> 'repo' [1]. We have to explicitly intercept those intances that are\n>> not 'the_repository'.\n> \n> Sorry but I am not sure I follow.  If a repository that is not\n> the_repository is not yet allowed, shouldn't the caller be flagged\n> for passing a random repository that is not the_repository as not\n> conforming to the API (yet) with:\n> \n>          if (repo != the_repository)\n>                  BUG(...);\n> \n> rather than papering over the issue with an unconditional\n> \n>          repo = the_repository;\n> \n> override?\n> \n> If the API that deals with this 'abbrev' setting needs to call\n> another API that only superficially takes any 'repo' parameter\n> without supporting anything other than the_repository, isn't that a\n> sign that the other API needs to be extended to work with any 'repo'\n> before the 'abbrev' part of the system can use it, simply because the\n> former is not ready?  Futzing with the 'abbrev' part of the system in\n> such a state piles on more unfinished work that will need to be fixed\n> later without achieving anything, except for the superficial \"now\n> this part too can take a 'repo' parameter, even though it does not\n> support anything but the_repository\", no?\n> \n> Puzzled...\n\nI was also wondering if doing this was appropriate... Since that's the \ncase, let's not migrate the _abbrev variable for now. I'll expand this \nseries, migrate some other variables and resend it when ready.\n\nRegards, yuchen\n"},{"id":"549108","messageId":"20260728014630.3284974-1-cat@malon.dev","threadId":"66062","inReplyTo":"20260725115428.2214202-1-cat@malon.dev","subject":"[PATCH v2 0/2] environment: migrate more global variables into","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-28T01:46:28Z","receivedAt":"2026-07-28T01:46:39Z","isPatch":true,"body":"Hi all,\n\nThis series moves:\n\n - (1/2) pack_size_limit_cfg\n - (2/2) assume_unchanged\n\ninto repo_config_values to continue the libification effort. \n\nChange since v1:\n\n - drop the migration of minimum_abbrev and default_abbrev.\n\nRelated:\n\n - [PATCH v12 00/10] migrate more variables into repo_config_values\n https://lore.kernel.org/git/20260714032525.1611141-1-cat@malon.dev/#t\n\nThanks! yuchen\n\nTian Yuchen (2):\n  environment: migrate pack_size_limit_cfg into repo_config_values\n  environment: migrate assume_unchanged into repo_config_values\n\n builtin/pack-objects.c | 2 +-\n builtin/update-index.c | 3 ++-\n environment.c          | 8 ++++----\n environment.h          | 5 +++--\n object-file.c          | 5 +++--\n read-cache.c           | 9 ++++++---\n 6 files changed, 19 insertions(+), 13 deletions(-)\n\n-- \n2.43.0\n\n"},{"id":"549109","messageId":"20260728014630.3284974-2-cat@malon.dev","threadId":"66062","inReplyTo":"20260728014630.3284974-1-cat@malon.dev","subject":"[PATCH v2 1/2] environment: migrate pack_size_limit_cfg into repo_config_values","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-28T01:46:29Z","receivedAt":"2026-07-28T01:46:42Z","isPatch":true,"body":"Move the global 'pack_size_limit_cfg' configuration into the\nrepository-specific 'repo_config_values' struct.\n\nWe do not introduce a getter for it because the readers are\nlimited and no hardcoded fallback values are needed.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>\nMentored-by: Olamide Caleb Bello <belkid98@gmail.com>\nSigned-off-by: Tian Yuchen <cat@malon.dev>\n---\n builtin/pack-objects.c | 2 +-\n environment.c          | 4 ++--\n environment.h          | 3 ++-\n object-file.c          | 5 +++--\n 4 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 3673b14b89..4ebcaccb09 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -5328,7 +5328,7 @@ int cmd_pack_objects(int argc,\n \tif (!HAVE_THREADS && delta_search_threads != 1)\n \t\twarning(_(\"no threads support, ignoring --threads\"));\n \tif (!pack_to_stdout && !pack_size_limit)\n-\t\tpack_size_limit = pack_size_limit_cfg;\n+\t\tpack_size_limit = cfg->pack_size_limit_cfg;\n \tif (pack_to_stdout && pack_size_limit)\n \t\tdie(_(\"--max-pack-size cannot be used to build a pack for transfer\"));\n \tif (pack_size_limit && pack_size_limit < 1024*1024) {\ndiff --git a/environment.c b/environment.c\nindex c663113e8a..53623518c7 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -67,7 +67,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-unsigned long pack_size_limit_cfg;\n \n #ifndef PROTECT_HFS_DEFAULT\n #define PROTECT_HFS_DEFAULT 0\n@@ -704,7 +703,7 @@ int git_default_config(const char *var, const char *value,\n \t}\n \n \tif (!strcmp(var, \"pack.packsizelimit\")) {\n-\t\tpack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi);\n+\t\tcfg->pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi);\n \t\treturn 0;\n \t}\n \n@@ -742,4 +741,5 @@ void repo_config_values_init(struct repo_config_values *cfg)\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+\tcfg->pack_size_limit_cfg = 0;\n }\ndiff --git a/environment.h b/environment.h\nindex acfb670be1..2e0f8beac0 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -101,6 +101,8 @@ struct repo_config_values {\n \tint protect_hfs;\n \tint protect_ntfs;\n \tint ignore_case;\n+\tunsigned long pack_size_limit_cfg;\n+\n \n \t/* section \"sparse\" config values */\n \tint sparse_expect_files_outside_of_patterns;\n@@ -184,7 +186,6 @@ extern int minimum_abbrev, default_abbrev;\n extern int assume_unchanged;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n-extern unsigned long pack_size_limit_cfg;\n \n enum rebase_setup_type {\n \tAUTOREBASE_NEVER = 0,\ndiff --git a/object-file.c b/object-file.c\nindex 7ff2b730ac..be68eead63 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -1273,6 +1273,7 @@ static int odb_transaction_files_write_object_stream(struct odb_transaction *bas\n \t\t\t\t\t\t     size_t size,\n \t\t\t\t\t\t     struct object_id *result_oid)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tstruct odb_transaction_files *transaction = container_of(base,\n \t\t\t\t\t\t\t\t struct odb_transaction_files,\n \t\t\t\t\t\t\t\t base);\n@@ -1298,8 +1299,8 @@ static int odb_transaction_files_write_object_stream(struct odb_transaction *bas\n \t * the difference between the inflated and on-disk size is limited\n \t * to zlib compression and is sufficient for this check.\n \t */\n-\tif (state->nr_written && pack_size_limit_cfg &&\n-\t    pack_size_limit_cfg < state->offset + size)\n+\tif (state->nr_written && cfg->pack_size_limit_cfg &&\n+\t    cfg->pack_size_limit_cfg < state->offset + size)\n \t\tflush_packfile_transaction(transaction);\n \n \tCALLOC_ARRAY(idx, 1);\n-- \n2.43.0\n\n"},{"id":"549110","messageId":"20260728014630.3284974-3-cat@malon.dev","threadId":"66062","inReplyTo":"20260728014630.3284974-1-cat@malon.dev","subject":"[PATCH v2 2/2] environment: migrate assume_unchanged into repo_config_values","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-07-28T01:46:30Z","receivedAt":"2026-07-28T01:46:46Z","isPatch":true,"body":"Move the global 'assume_unchanged' configuration into the\nrepository-specific 'repo_config_values' struct.\n\nWe do not introduce a getter for it because the readers are\nlimited and no hardcoded fallback values are needed.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>\nMentored-by: Olamide Caleb Bello <belkid98@gmail.com>\nSigned-off-by: Tian Yuchen <cat@malon.dev>\n---\n builtin/update-index.c | 3 ++-\n environment.c          | 4 ++--\n environment.h          | 2 +-\n read-cache.c           | 9 ++++++---\n 4 files changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 4c4b39a157..3ef7e9bb90 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -419,6 +419,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n {\n \tint len, option;\n \tstruct cache_entry *ce;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n \tif (!verify_path(path, mode))\n \t\treturn error(\"Invalid path '%s'\", path);\n@@ -431,7 +432,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n \tce->ce_flags = create_ce_flags(stage);\n \tce->ce_namelen = len;\n \tce->ce_mode = create_ce_mode(mode);\n-\tif (assume_unchanged)\n+\tif (cfg->assume_unchanged)\n \t\tce->ce_flags |= CE_VALID;\n \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\ndiff --git a/environment.c b/environment.c\nindex 53623518c7..12659c1d9c 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -44,7 +44,6 @@ static int zlib_compression_seen;\n int trust_executable_bit = 1;\n int has_symlinks = 1;\n int minimum_abbrev = 4, default_abbrev = -1;\n-int assume_unchanged;\n char *git_commit_encoding;\n char *git_log_output_encoding;\n char *apply_default_whitespace;\n@@ -355,7 +354,7 @@ int git_default_core_config(const char *var, const char *value,\n \t}\n \n \tif (!strcmp(var, \"core.ignorestat\")) {\n-\t\tassume_unchanged = git_config_bool(var, value);\n+\t\tcfg->assume_unchanged = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n \n@@ -737,6 +736,7 @@ 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->assume_unchanged = 0;\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;\ndiff --git a/environment.h b/environment.h\nindex 2e0f8beac0..3a391338e3 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 assume_unchanged;\n \tint precomposed_unicode;\n \tint core_sparse_checkout_cone;\n \tint warn_on_object_refname_ambiguity;\n@@ -183,7 +184,6 @@ int have_git_dir(void);\n extern int trust_executable_bit;\n extern int has_symlinks;\n extern int minimum_abbrev, default_abbrev;\n-extern int assume_unchanged;\n extern char *apply_default_whitespace;\n extern char *apply_default_ignorewhitespace;\n \ndiff --git a/read-cache.c b/read-cache.c\nindex 38b55323dd..643b13f1fb 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -192,9 +192,11 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n\n  */\n void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, struct stat *st)\n {\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\n \tfill_stat_data(&ce->ce_stat_data, st);\n \n-\tif (assume_unchanged)\n+\tif (cfg->assume_unchanged)\n \t\tce->ce_flags |= CE_VALID;\n \n \tif (S_ISREG(st->st_mode)) {\n@@ -1346,6 +1348,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,\n {\n \tstruct stat st;\n \tstruct cache_entry *updated;\n+\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \tint changed;\n \tint refresh = options & CE_MATCH_REFRESH;\n \tint ignore_valid = options & CE_MATCH_IGNORE_VALID;\n@@ -1405,7 +1408,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,\n \t\t * is not marked VALID, this is the place to mark it\n \t\t * valid again, under \"assume unchanged\" mode.\n \t\t */\n-\t\tif (ignore_valid && assume_unchanged &&\n+\t\tif (ignore_valid && cfg->assume_unchanged &&\n \t\t    !(ce->ce_flags & CE_VALID))\n \t\t\t; /* mark this one VALID again */\n \t\telse {\n@@ -1440,7 +1443,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,\n \t * (i.e. things to be edited) will reacquire CE_VALID bit\n \t * automatically, which is not really what we want.\n \t */\n-\tif (!ignore_valid && assume_unchanged &&\n+\tif (!ignore_valid && cfg->assume_unchanged &&\n \t    !(ce->ce_flags & CE_VALID))\n \t\tupdated->ce_flags &= ~CE_VALID;\n \n-- \n2.43.0\n\n"}]}