Re: [GSoC Proposal] Refactoring in order to reduce Git's global state
- From
Christian Couder <christian.couder@gmail.com>
- Date
- Mar 21, 2026, 13:36 UTC
- Message-ID
- <CAP8UFD1H8ZsxfGSnnvX9xkKLSSpDjA3e3KNZ7eHN3ruq-sC7fw@mail.gmail.com>
- In-Reply-To
- <CAEaT9_9jAoXkxKn+2+q654aKybC1=bk6p7xiVHmcy+YDDe7GXw@mail.gmail.com>
Hi,
On Tue, Mar 17, 2026 at 6:54 PM Francesco Paparatto <francescopaparatto@gmail.com> wrote:
[...]
Show 6 quoted lines
> So far, I have made the following contributions: > > * [GSoC PATCH v2] t3310: replace test -f/-d with > test_path_is_file/test_path_is_dir > Link: https://lore.kernel.org/git/20260228005939.9012-1-francescopaparatto@gmail.com/ > Status: Graduated to 'master'.
For commits which graduated to master, please give the commit ID of either the commits you authored or the merge commit that merged your commit(s) into master.
> * [PATCH v4] t3310: avoid hiding failures from rev-parse in > command substitutions > Link: https://lore.kernel.org/git/20260307103631.89829-1-francescopaparatto@gmail.com/ > Status: Will merge to 'master'.
[...]
Show 71 quoted lines
> Context and Prior Work > ----------------------- > Not all config variables can be treated in the same way. There is > a fundamental distinction between eagerly and lazily parsed > variables, and conflating the two causes regressions. > > Variables set in git_default_core_config() are eagerly parsed. They > are read at startup, and if a value is invalid, Git calls die() > immediately with a clear error before doing any real work. The user > gets early feedback and can fix their config. > > Variables in struct repo_settings are lazily parsed. They are > populated on first access via prepare_repo_settings(). If an eagerly > parsed variable is naively moved into this struct, invalid config > that used to crash at startup now crashes mid-operation — the user > may have already started work that is now lost. > > During GSoC 2025, Ayush Chandekar moved several global configuration > variables into repository-scoped structures [3]. Through this work > and subsequent review discussions, the eager/lazy problem became > visible [4]. > > Ayush's work also surfaced the getter/setter debate. When he > introduced getter and setter functions for repo_settings fields, > reviewers pointed out they added no value without calling > prepare_repo_settings() internally. From this discussion, Junio > suggested two approaches for repo_settings variables that must > not be mixed [5]: > > - Common variables: populated in prepare_repo_settings(), accessed > directly via repo->settings.foo. No getter, no setter. > - Rare variables: prepare_repo_settings() does not touch the field. > A lazy getter checks a sentinel value (e.g. -1), reads from > config on first access, and caches the result. > > The appropriate pattern for each variable will require reasoning > and discussion on the mailing list. > > Phillip Wood suggested a third approach: passing a > repository pointer through git_default_config() via the void *cb > callback data parameter, so handlers can populate per-repo structs > without touching globals [6]. > > Building on these lessons, Olamide Bello during the Outreachy > program introduced struct repo_config_values [2], a structure > linked to struct repository that stores eagerly parsed configuration > values while preserving their startup-time error detection. An > accessor function repo_config_values() enforces safety by preventing > access from uninitialized repositories and guarding against access > from secondary repository instances that do not yet have their > config populated. > > So we now have two structs living inside struct repository: > repo_settings for lazily parsed variables, and repo_config_values > for eagerly parsed variables. > > Approach > -------- > I will follow the pattern established in Olamide Bello's approved > patch series [2], which provides the concrete workflow for each > variable: > > 1. Add a new field to struct repo_config_values in environment.h. > 2. Initialize the field in repo_config_values_init(). > 3. Update the config callback: get cfg via > repo_config_values(the_repository), write to cfg->field instead > of the global. > 4. Update all call sites: replace the global with cfg->field. > 5. Remove the global from environment.c and the extern from > environment.h. > 6. Run tests and check fuzz targets.
By the way there is also this series from Olamide Bello:
https://lore.kernel.org/git/cover.1773127785.git.belkid98@gmail.com/
Show 9 quoted lines
> Timeline > -------- > Project size: 175 hours. > > Community Bonding (May 1 - May 25): > - Discuss project direction and design approaches with mentors. > - Study Bello Caleb's and Ayush Chandekar's patches in depth. > Review remaining repo_config_values work and identify > unfinished tasks.
It would be nice if your proposal started to look at the remaining repo_config_values work already.
Thanks for your interest in Git and this project.
Best, Christian.