threads / discuss / 66705

[Outreachy][Proposal]: Reduce Git's global state to enable Git's libification

Subject: [Outreachy][Proposal]: Reduce Git's global state to enable Git's libification

## tl;dr

5 messages between Oct 29, 2026 and Nov 5, 2026.

replies: 4people: 3as markdown or json

Okhuomon Ajayi· Oct 29, 2026, 14:18 UTC · lore
Hello,

This is my proposal for the project "Reduce Git's global state to enable Git's libification" for the December 2026 Outreachy internship.

I'd appreciate any feedback.

Personal Information ====================

Full Name: Okhuomon Rosemary Ajayi
Email: okhuomonajayi54@gmail.com
GitHub: https://github.com/six-shot
Blog: https://medium.com/@okhuomonajayi54
Location: Lagos, Nigeria (WAT, UTC+1)

About Me ========

I am Okhuomon Rosemary Ajayi, often known as "sixshot", a self-taught software developer from Lagos, Nigeria. I am obsessed with robots and intelligent mechanical systems. C was the first programming language I picked up, before I moved into frontend and mobile development. Working on Git during this contribution period has brought me back to C, and I have enjoyed working at that lower level again.

Before Git, I contributed to other open source projects. In Servo I fixed clippy warnings in the script crate and improved some documentation [12]. In the OCaml ecosystem I added Deflate support and horizontal differencing to ocaml-tiff, and worked on raven and YOCaml [13]. In LibreOffice I worked in the C++ core, fixing a bug where Infobar keys reached the document and cleaning up unit conversion code [14]. In Mozilla Firefox I fixed layout bugs in vertical tabs and split view [15].

As a woman in tech, I know how much it helps to see someone like yourself doing the work. That is why I volunteered to train girls at Edunity for Girls, helping them get started in tech.

Honestly, I would like to be part of the Git community and keep on contributing to open source. This project lets me do that in C, the language I started with, and my patches on the_repository so far have shown me how much there is to learn here.

Past Experience with Git ========================

I have been using Git since I started coding, for my own projects and when collaborating with other developers.

This is not my first time on the Git mailing list. I applied to Outreachy in October 2025 and sent about ten patches in about a week (patch-ids, commit.c comments, builtin/patch-id.c, gpg-interface) [10]. None of them were merged. I was sending too fast, my subject lines had doubled prefixes like "[PATCH] [PATCH v2]", and my commit messages did not follow the project style, as Junio and Christian pointed out [11].

This year I slowed down. I read SubmittingPatches properly, wrote my commit messages in the present tense, and sent one change at a time. The hardest part was still sending new versions: keeping each version in sync with the review, the right thread and the notes on what changed since the last version. This time my microproject was merged to master, and six more topics are in 'seen', some of them marked "Will merge to 'next'?" in What's cooking.

Contributions to the Git Community ==================================

Microproject
------------
+ delta-islands: use Q_() for island count
  Thread: https://lore.kernel.org/git/20261013203042.58610-1-okhuomonajayi54@gmail.com/
  Branch: oa/delta-islands-i18n-use-q
  Status: merged to 'master'
  Commit: 60e16b0387 (merge commit 7ac84b7267), listed in the
  Git 2.98.0 release notes
  Description: The island count in a progress message was built with
  a plain _() so translators could not handle plural forms. Use Q_()
  instead. v2 moved a reviewer note below the --- line after
  Junio's review.
Patches related to the project (the_repository)
------------------------------------------------
+ merge: stop using the_repository
  Thread: https://lore.kernel.org/git/20261015142532.48175-1-okhuomonajayi54@gmail.com/
  Branch: oa/merge-without-the-repository
  Status: in 'seen'
  Description: Pass the repository already available at the entry
  points down to the helpers, removing the_repository and
  the_hash_algo from merge.c.
+ merge-blobs: stop using the_repository
  Thread: https://lore.kernel.org/git/20261017105244.90295-1-okhuomonajayi54@gmail.com/
  Branch: oa/merge-blobs-stop-using-the-repository
  Status: in 'seen'
  Description: Use the repository reachable from the index_state
  instead of the global.
  Usman suggested renaming "r" to "repo"; Junio preferred the short
  "r" used elsewhere for "struct repository *", so I kept it [9].
+ diffcore-break: remove USE_THE_REPOSITORY_VARIABLE
  Thread: https://lore.kernel.org/git/20261014114904.85300-1-okhuomonajayi54@gmail.com/
  Status: in 'seen', marked "Will merge to 'next'?"
  Description: An earlier commit removed the last use of
  the_repository in diffcore-break.c, so the file no longer needs
  USE_THE_REPOSITORY_VARIABLE. Drop the define.
+ checkout: make unique_tracking_name() use the given repository
  (2 patches)
  Thread (v3): https://lore.kernel.org/git/20261023211533.73433-1-okhuomonajayi54@gmail.com/
  Status: v3 in 'seen'
  Description: Pass the repository to unique_tracking_name() and
  carry it in struct tracking_name_data, so checkout.c no longer
  needs USE_THE_REPOSITORY_VARIABLE. Usman asked for a clearer
  commit message in v1. In v2 Junio pointed out that the function
  still walked the remotes with for_each_remote(), which only works
  on the_repository, so v3 adds repo_for_each_remote() first.
+ diffcore-rename: stop using the_repository
  Thread: https://lore.kernel.org/git/20261024221341.92086-1-okhuomonajayi54@gmail.com/
  Status: in 'seen', marked "Will merge to 'next'?"
  Description: diffcore_rename_extended() already has the
  repository through its options. Use its hash algorithm when
  checking for empty blobs, pass it to start_delayed_progress(),
  and drop USE_THE_REPOSITORY_VARIABLE. Patrick reviewed it and
  said it looks correct.
+ notes-cache: read the cache ref from the given repository
  Thread: https://lore.kernel.org/git/20261026102603.32377-1-okhuomonajayi54@gmail.com/
  Status: reviewed by Junio, waiting to be queued
  Description: notes_cache_match_validity() already receives the
  repository but read the ref from the_repository. Pass it to
  get_main_ref_store() so the check reads the same repository.
+ combine-diff: use the repository from diff options
  Thread: https://lore.kernel.org/git/20261026111303.92117-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: show_combined_header() and show_patch_diff()
  already have opt->repo; use it for the hash algorithm,
  abbreviation and gitlinks. The file still needs the macro for
  DEFAULT_ABBREV, which depends on the default_abbrev global.
+ negotiator/default: stop using the_repository
  Thread: https://lore.kernel.org/git/20261027153429.14131-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: Give default_negotiator_init() a repository,
  store it on the negotiation state and use it to parse commits,
  clear marks and walk refs. Drop USE_THE_REPOSITORY_VARIABLE.
+ bundle-uri: stop using the_repository
  Thread (v2): https://lore.kernel.org/git/20261029131325.79176-1-okhuomonajayi54@gmail.com/
  Status: v1 in 'seen' and marked ready for 'next'; v2 sent to
  replace it, and Patrick confirmed the v2 diff
  Description: unbundle_from_file() unbundles objects into the
  given repository but read and wrote refs in the_repository, and
  fetch_bundle_uri() used the_repository for tracing. v1 used the
  given repository for both and was reviewed by Karthik. Patrick
  then pointed out that only two more uses were left in the file,
  in find_temp_filename() and copy_uri_to_file(), so v2 passes the
  repository to them too and drops USE_THE_REPOSITORY_VARIABLE
  from bundle-uri.c.
+ range-diff: use diffopt->repo instead of the_repository
  Thread (v2): https://lore.kernel.org/git/20261029084720.93221-1-okhuomonajayi54@gmail.com/
  Status: v2 sent, waiting for review
  Description: output_pair_header() and patch_diff() receive a
  diffopt that names the repository, but still used the_repository
  and the_hash_algo. Use diffopt->repo, and give get_filespec() a
  hash algorithm parameter. v2 rewords the commit message after
  Pablo's review.
+ environment: move commit_encoding into repo_config_values
  Thread: https://lore.kernel.org/git/20261021155608.58509-1-okhuomonajayi54@gmail.com/
  Status: v1 reviewed by Junio; v2 in progress
  Description: v1 moved the global into struct repo_config_values.
  Junio pointed out that only commit.c uses it and suggested passing
  a "const char *" encoding down to the functions instead of the
  whole repository. v2 will do that.
Other patches
-------------
+ credential-store: add lockTimeout config option (#leftoverbits)
  Thread (v2): https://lore.kernel.org/git/20261016212216.58000-1-okhuomonajayi54@gmail.com/
  Status: v2 sent after Junio's review, waiting
  Description: Junio noted in the rerere thread that
  credentialStore.lockTimeoutMS is the only timeout setting with
  the unit in its name, and suggested a synonym without "MS". Add
  credentialStore.lockTimeout; the old name keeps working.
Reviews and help to other applicants
------------------------------------
+ list-objects-filter-options: pass repository to partial clone
  helpers (Dorine Tipo)
  My reply: https://lore.kernel.org/git/CAFpMFfCu6JrUC8i453qBP=AktqcG_9sGX=1-1ekEDCYm_+pkUw@mail.gmail.com/
  Description: Dorine asked whether USE_THE_REPOSITORY_VARIABLE
  could be dropped. I applied the patch, removed the define and
  checked that the file still builds, so it can go in the same
  patch.
+ Microproject idea: modernize a file-existence check in
  t/t0081-find-pack.sh (Immaculate Mecha)
  My reply: https://lore.kernel.org/git/CAFpMFfA17dnuLSRt97BrM0u3cHAifJybr_Zc2ahr_zq2nspgsw@mail.gmail.com/
  Description: Pointed out that Shashank S had already changed that
  exact line, and suggested searching lore and "What's cooking"
  before choosing a microproject.
Learning resource
-----------------
+ "Learn C by reading Git" -- a zero-to-hero guide
  Link: https://six-shot.github.io/six-shot-git-c-zero-to-hero/
  Description: C was the first language I learned, but I had not
  used it in a while. I built this guide during this Outreachy
  contribution period so I could understand C well by learning it
  with Git itself. It teaches C from zero using real code from
  git.git (repository.h, merge-blobs.c, git.c, ...), with
  exercises. It covers the patterns this project depends on:
  structs and pointers, passing "struct repository *" down a call
  chain, and why global variables like the_repository are a
  problem. I hope it also helps other people who want to start
  contributing to Git.

Project Overview ================

Git keeps the state of the repository it is working on in a single global object, the_repository, which is a "struct repository". A lot of internal code uses this global directly instead of taking a repository as a parameter. On top of that, many configuration and environment values are stored as global variables in environment.c rather than in the repository they belong to.

This design assumes that a process only ever works with one repository. That is not true for things like submodules, and it is one of the main things blocking the long-term goal of libifying Git, where a program could open several repositories at the same time. With shared globals, two repositories in one process would read and overwrite the same values, which can lead to wrong behaviour that is hard to debug. It also makes the code harder to read and test, because a function's dependencies are hidden instead of being visible in its parameters.

This project reduces that global state step by step:
- removing the_repository from library code by passing the
  repository explicitly through the call chain, so files no longer
  need USE_THE_REPOSITORY_VARIABLE;
- moving repository-specific settings from environment.c into the
  repository, mostly struct repo_config_values and struct
  repo_settings;
- and, where a value is only used in one place, passing just that
  value down instead of the whole repository.

A lot of progress has already been made: many settings that used to be globals now live in struct repo_config_values, and many files no longer need the_repository. But there is still plenty left. Over a hundred library files outside builtin/ still define USE_THE_REPOSITORY_VARIABLE, and environment.h still has globals such as git_commit_encoding, git_log_output_encoding and comment_line_str. That remaining library code is where I want to focus.

Review of Previous Work and Strategies ======================================

From reading past series on the list and from my own patches, I see three strategies, and the right one depends on the variable:

1. Thread the repository through the call chain, bottom-up.
   Patrick Steinhardt introduced USE_THE_REPOSITORY_VARIABLE so files
   that still depend on the global are marked [1]. Work then goes from
   the lowest layers up, removing the macro file by file (objects [2],
   path [3], packfile by Karthik [4]). My patches to merge.c,
   merge-blobs.c, diffcore-break.c, diffcore-rename.c, checkout.c,
   notes-cache.c, combine-diff.c, negotiator/default.c,
   bundle-uri.c and range-diff.c follow this pattern.
2. Move repository-scoped config into the repository.
   core.hooksPath and core.sharedRepository moved into repo-settings
   with accessors [3]. Later, Olamide Caleb Bello's Outreachy series
   added struct repo_config_values, with repo_config_values(repo) as
   the accessor, and moved core.attributesFile, core.sparseCheckout
   and branch.autoSetupMerge into it [5]. Others, such as Tian Yuchen,
   have moved more values there since.
3. Pass only the value the function needs.
   the_hash_algo was replaced by an explicit
   "const struct git_hash_algo *" in csum-file.c [2]. Junio asked for
   the same thing on my commit_encoding patch: since only commit.c
   uses the variable, pass the encoding string instead of adding it
   to repository config [6].
Roadblocks seen in earlier work
-------------------------------
- Not every global belongs in struct repository. When Ayush
  Chandekar tried to move core.attributesfile into repo_settings,
  Junio questioned whether attribute data belongs to a repository at
  all, since attributes come from the index and the working tree,
  and compared it to how index_state is passed around instead of the
  repository [7]. The config value was later stored in struct
  repo_config_values instead [5].
- State used during early startup cannot simply be moved; the setup
  code has to change first. Patrick did this for
  is_bare_repository_cfg and git_work_tree_cfg in his "setup: drop
  global state" series [8]. have_git_dir() is still left, and
  environment.h says it "should not have to exist at all".
- builtin/ commands: the "repo" argument of cmd_foo() can be NULL
  (e.g. "git foo -h" outside a repository), so blindly replacing
  the_repository there causes crashes. Library code is the safer
  target.
- Naming: Junio prefers a short "r" for "struct repository *"
  parameters [9].
Can there be clear criteria? Only partly. My working checklist:
  a. Who reads and writes it? (git grep every use)
  b. Is it per-repository, per-index, per-subsystem or process-wide?
  c. Is it needed before a repository is set up?
  d. Does only one file use it? Then pass the value (strategy 3).
  e. Search the list for earlier attempts and objections first.
Anything still unclear goes to the list as a question before code.
Example: git_log_output_encoding
--------------------------------
This is the encoding Git uses when it shows commit messages. It is
the twin of git_commit_encoding, which my commit_encoding patch
works on, but it is harder:
- It is set in two places: from i18n.logOutputEncoding in
  environment.c, and from "git log --encoding=..." in revision.c.
  Other revision options like --reverse are stored in struct
  rev_info, but --encoding writes the global. The parsing was moved
  into revision.c in 2006 (7cbcf4d557) so that rev-list and
  diff-tree could use it too, and at that time the rest of the
  code read the encoding from a global anyway.
- It is read through get_log_output_encoding() 15 times in 12
  files. Many of these callers (log-tree.c, bundle.c, submodule.c,
  sequencer.c) copy it into
  "struct pretty_print_context.output_encoding", so that struct
  already carries the value. That points to strategy 3: fill the
  context once from the caller and let the pretty-printing code use
  ctx->output_encoding instead of calling the global getter.
- Some callers do not print a log: remote-curl.c uses it to
  re-encode an error message from the server, and sequencer.c uses
  it when building the todo list. So the value is really "the
  user's display encoding", not something that belongs to one
  repository. That is a reason NOT to put it in
  repo_config_values, which is also what Junio said about
  commit_encoding [6].

My plan for it: first do commit_encoding (single caller), then propose on the list storing the --encoding value in struct rev_info and passing it through pretty_print_context, and ask whether that design is acceptable before writing the series.

Internship Plan and Timeline ============================

The internship runs from 7 December 2026 to 8 March 2027.
Before the internship (now -- 6 Dec 2026)
- Finish open patches: commit_encoding v2, combine-diff,
  negotiator/default, range-diff, notes-cache and credential-store.
- Keep reviewing other applicants' patches in the global-state area.
- Build a list of remaining globals and USE_THE_REPOSITORY_VARIABLE
  files outside builtin/, ordered by how low in the call graph they
  sit.
Weeks 1-2 (7 Dec -- 20 Dec)
- Agree the list and order with mentors.
- First small series: one library file off
  USE_THE_REPOSITORY_VARIABLE.
- First blog post.
Weeks 3-6 (21 Dec -- 17 Jan)
- environment.c globals that only one subsystem uses: pass the value
  down, as Junio suggested for commit_encoding.
- git_log_output_encoding next: it is read in 12 files and also set
  by "--encoding", so agree the design on the list before coding.
- Ask on the list before touching the comment_line_str group and the
  abbrev globals, since they are read in many places.
Weeks 7-10 (18 Jan -- 14 Feb)
- Continue bottom-up removal of the_repository in library code,
  one subsystem per series.
- Look at a harder item if mentors agree, such as have_git_dir(),
  which still depends on the_repository.
Weeks 11-13 (15 Feb -- 8 Mar 2027)
- Land rerolls, no new big series.
- Final report on the blog and the list.
- Update the "Learn C by reading Git" guide with what I learned.
Throughout: small series, reply to reviews within a day or two,
weekly blog post, weekly sync with mentors.

Availability ============

I can give 40 hours a week to the project during the internship. I am based in Lagos (WAT, UTC+1) and can adjust my hours for calls and reviews when needed.

Blogging ========

I will blog on Medium (https://medium.com/@okhuomonajayi54) and post weekly updates on my progress, what I learned and the challenges I faced. I will share each post on the mailing list, like previous interns did.

After the Internship ====================

After the internship I want to continue as an open source contributor to Git: sending patches, reviewing others' work and helping new contributors get started, the way Usman and Junio helped me. I also want to keep the "Learn C by reading Git" guide up to date so it stays useful for future applicants.

Appreciation ============

I want to thank Usman and Junio for always helping out during this contribution period. I also want to thank Patrick, Karthik, Pablo, Christian, Siddharth and Kaartic, and everyone in the Git community for being so welcoming.

References
==========
[1] https://lore.kernel.org/git/cover.1718347699.git.ps@pks.im/
[2] https://lore.kernel.org/git/20250306-b4-pks-objects-without-the-repository-v2-1-f3465327be69@pks.im/
[3] https://lore.kernel.org/git/20250207-b4-pks-path-drop-the-repository-v2-14-13cad3c11b8a@pks.im/
[4] https://lore.kernel.org/git/cover.1733236936.git.karthik.188@gmail.com/
[5] https://lore.kernel.org/git/cover.1771258573.git.belkid98@gmail.com/
[6] https://lore.kernel.org/git/xmqq33tyn5qi.fsf@gitster.g/
[7] https://lore.kernel.org/git/xmqqwmcw97z2.fsf@gitster.g/
[8] https://lore.kernel.org/git/20260611-b4-pks-setup-drop-global-state-v2-0-a6f7269c841d@pks.im/
[9] https://lore.kernel.org/git/xmqqwlrcrqaz.fsf@gitster.g/
[10] https://lore.kernel.org/git/20251009214445.1190274-1-okhuomonajayi54@gmail.com/
[11] https://lore.kernel.org/git/CAP8UFD2sdvkv_ZqiLZU9k5zF+tM3UTQ8+mJjziRZGzOra6dMFA@mail.gmail.com/
     https://lore.kernel.org/git/xmqqo6q5z6iu.fsf@gitster.g/
[12] https://github.com/servo/servo/pulls?q=is%3Apr+author%3Asix-shot+is%3Amerged
[13] https://github.com/geocaml/ocaml-tiff/pull/80
     https://github.com/raven-ml/raven/pulls?q=is%3Apr+author%3Asix-shot
     https://github.com/xhtmlboi/yocaml/pulls?q=is%3Apr+author%3Asix-shot
[14] https://gerrit.libreoffice.org/q/owner:okhuomonajayi54@gmail.com+status:merged
     https://whatsnew.libreoffice.org/25.8.4/
[15] https://github.com/mozilla-firefox/firefox/commits?author=okhuomonajayi54@gmail.com
Thanks for reading.
Okhuomon Ajayi
Christian Couder· Nov 3, 2026, 13:46 UTC · re: Okhuomon Ajayi · lore

Re: [Outreachy][Proposal]: Reduce Git's global state to enable Git's libification

Hi,

On Thu, Oct 29, 2026 at 3:18 PM Okhuomon Ajayi <okhuomonajayi54@gmail.com> wrote:

Show 5 quoted lines
>
> Hello,
>
> This is my proposal for the project "Reduce Git's global state to
> enable Git's libification" for the December 2026 Outreachy internship.
Thanks for your interest in Git.
Show 21 quoted lines
> Past Experience with Git
> ========================
>
> I have been using Git since I started coding, for my own projects
> and when collaborating with other developers.
>
> This is not my first time on the Git mailing list. I applied to
> Outreachy in October 2025 and sent about ten patches in about a week
> (patch-ids, commit.c comments, builtin/patch-id.c, gpg-interface)
> [10]. None of them were merged. I was sending too fast, my subject
> lines had doubled prefixes like "[PATCH] [PATCH v2]", and my commit
> messages did not follow the project style, as Junio and Christian
> pointed out [11].
>
> This year I slowed down. I read SubmittingPatches properly, wrote
> my commit messages in the present tense, and sent one change at a
> time. The hardest part was still sending new versions: keeping each
> version in sync with the review, the right thread and the notes on
> what changed since the last version. This time my microproject was
> merged to master, and six more topics are in 'seen', some of
> them marked "Will merge to 'next'?" in What's cooking.
Nice.
Show 16 quoted lines
> Reviews and help to other applicants
> ------------------------------------
> + list-objects-filter-options: pass repository to partial clone
>   helpers (Dorine Tipo)
>   My reply: https://lore.kernel.org/git/CAFpMFfCu6JrUC8i453qBP=AktqcG_9sGX=1-1ekEDCYm_+pkUw@mail.gmail.com/
>   Description: Dorine asked whether USE_THE_REPOSITORY_VARIABLE
>   could be dropped. I applied the patch, removed the define and
>   checked that the file still builds, so it can go in the same
>   patch.
>
> + Microproject idea: modernize a file-existence check in
>   t/t0081-find-pack.sh (Immaculate Mecha)
>   My reply: https://lore.kernel.org/git/CAFpMFfA17dnuLSRt97BrM0u3cHAifJybr_Zc2ahr_zq2nspgsw@mail.gmail.com/
>   Description: Pointed out that Shashank S had already changed that
>   exact line, and suggested searching lore and "What's cooking"
>   before choosing a microproject.
Thanks for helping with reviews.
[...]
Show 18 quoted lines
> This project reduces that global state step by step:
> - removing the_repository from library code by passing the
>   repository explicitly through the call chain, so files no longer
>   need USE_THE_REPOSITORY_VARIABLE;
> - moving repository-specific settings from environment.c into the
>   repository, mostly struct repo_config_values and struct
>   repo_settings;
> - and, where a value is only used in one place, passing just that
>   value down instead of the whole repository.
>
> A lot of progress has already been made: many settings that used
> to be globals now live in struct repo_config_values, and many files
> no longer need the_repository. But there is still plenty left.
> Over a hundred library files outside builtin/ still define
> USE_THE_REPOSITORY_VARIABLE, and environment.h still has globals
> such as git_commit_encoding, git_log_output_encoding and
> comment_line_str. That remaining library code is where I want to
> focus.

It's a good idea to focus on library code. You might also be interested in what Junio says about code in "builtin/" in:

https://lore.kernel.org/git/xmqqmru76ybk.fsf_-_@gitster.g/
[...]
Show 18 quoted lines
> Roadblocks seen in earlier work
> -------------------------------
> - Not every global belongs in struct repository. When Ayush
>   Chandekar tried to move core.attributesfile into repo_settings,
>   Junio questioned whether attribute data belongs to a repository at
>   all, since attributes come from the index and the working tree,
>   and compared it to how index_state is passed around instead of the
>   repository [7]. The config value was later stored in struct
>   repo_config_values instead [5].
> - State used during early startup cannot simply be moved; the setup
>   code has to change first. Patrick did this for
>   is_bare_repository_cfg and git_work_tree_cfg in his "setup: drop
>   global state" series [8]. have_git_dir() is still left, and
>   environment.h says it "should not have to exist at all".
> - builtin/ commands: the "repo" argument of cmd_foo() can be NULL
>   (e.g. "git foo -h" outside a repository), so blindly replacing
>   the_repository there causes crashes. Library code is the safer
>   target.

In the discussion I mentioned above, Junio says that the code in "builtin/" isn't reusable library code at all, and that it would be useful work to move that code into library helpers.

[...]
Show 7 quoted lines
> Blogging
> ========
>
> I will blog on Medium (https://medium.com/@okhuomonajayi54) and
> post weekly updates on my progress, what I learned and the
> challenges I faced. I will share each post on the mailing list,
> like previous interns did.
I wonder if blog posts on Medium are accessible to everyone.
Thanks.
Okhuomon Ajayi· Nov 3, 2026, 14:55 UTC · re: Christian Couder · lore

Re: [Outreachy][Proposal]: Reduce Git's global state to enable Git's libification

Hi Christian,

On Tue, Nov 3, 2026 at 2:46 PM Christian Couder <christian.couder@gmail.com> wrote:

> It's a good idea to focus on library code. You might also be
> interested in what Junio says about code in "builtin/" in:
>
> https://lore.kernel.org/git/xmqqmru76ybk.fsf_-_@gitster.g/
[...]
> In the discussion I mentioned above, Junio says that the code in
> "builtin/" isn't reusable library code at all, and that it would be
> useful work to move that code into library helpers.

Thanks, I'll read that discussion and add moving code from builtin/ into library helpers to the plan in v2 of my proposal.

> I wonder if blog posts on Medium are accessible to everyone.

Good point, Medium can ask readers to sign in. I'll move my blog to Hashnode / GitHub Pages so that anyone can read it without an account.

Thanks for the review.
Okhuomon

On Tue, Nov 3, 2026 at 2:46 PM Christian Couder <christian.couder@gmail.com> wrote:

Show 120 quoted lines
>
> Hi,
>
> On Thu, Oct 29, 2026 at 3:18 PM Okhuomon Ajayi
> <okhuomonajayi54@gmail.com> wrote:
> >
> > Hello,
> >
> > This is my proposal for the project "Reduce Git's global state to
> > enable Git's libification" for the December 2026 Outreachy internship.
>
> Thanks for your interest in Git.
>
> > Past Experience with Git
> > ========================
> >
> > I have been using Git since I started coding, for my own projects
> > and when collaborating with other developers.
> >
> > This is not my first time on the Git mailing list. I applied to
> > Outreachy in October 2025 and sent about ten patches in about a week
> > (patch-ids, commit.c comments, builtin/patch-id.c, gpg-interface)
> > [10]. None of them were merged. I was sending too fast, my subject
> > lines had doubled prefixes like "[PATCH] [PATCH v2]", and my commit
> > messages did not follow the project style, as Junio and Christian
> > pointed out [11].
> >
> > This year I slowed down. I read SubmittingPatches properly, wrote
> > my commit messages in the present tense, and sent one change at a
> > time. The hardest part was still sending new versions: keeping each
> > version in sync with the review, the right thread and the notes on
> > what changed since the last version. This time my microproject was
> > merged to master, and six more topics are in 'seen', some of
> > them marked "Will merge to 'next'?" in What's cooking.
>
> Nice.
>
> > Reviews and help to other applicants
> > ------------------------------------
> > + list-objects-filter-options: pass repository to partial clone
> >   helpers (Dorine Tipo)
> >   My reply: https://lore.kernel.org/git/CAFpMFfCu6JrUC8i453qBP=AktqcG_9sGX=1-1ekEDCYm_+pkUw@mail.gmail.com/
> >   Description: Dorine asked whether USE_THE_REPOSITORY_VARIABLE
> >   could be dropped. I applied the patch, removed the define and
> >   checked that the file still builds, so it can go in the same
> >   patch.
> >
> > + Microproject idea: modernize a file-existence check in
> >   t/t0081-find-pack.sh (Immaculate Mecha)
> >   My reply: https://lore.kernel.org/git/CAFpMFfA17dnuLSRt97BrM0u3cHAifJybr_Zc2ahr_zq2nspgsw@mail.gmail.com/
> >   Description: Pointed out that Shashank S had already changed that
> >   exact line, and suggested searching lore and "What's cooking"
> >   before choosing a microproject.
>
> Thanks for helping with reviews.
>
> [...]
>
> > This project reduces that global state step by step:
> > - removing the_repository from library code by passing the
> >   repository explicitly through the call chain, so files no longer
> >   need USE_THE_REPOSITORY_VARIABLE;
> > - moving repository-specific settings from environment.c into the
> >   repository, mostly struct repo_config_values and struct
> >   repo_settings;
> > - and, where a value is only used in one place, passing just that
> >   value down instead of the whole repository.
> >
> > A lot of progress has already been made: many settings that used
> > to be globals now live in struct repo_config_values, and many files
> > no longer need the_repository. But there is still plenty left.
> > Over a hundred library files outside builtin/ still define
> > USE_THE_REPOSITORY_VARIABLE, and environment.h still has globals
> > such as git_commit_encoding, git_log_output_encoding and
> > comment_line_str. That remaining library code is where I want to
> > focus.
>
> It's a good idea to focus on library code. You might also be
> interested in what Junio says about code in "builtin/" in:
>
> https://lore.kernel.org/git/xmqqmru76ybk.fsf_-_@gitster.g/
>
> [...]
>
> > Roadblocks seen in earlier work
> > -------------------------------
> > - Not every global belongs in struct repository. When Ayush
> >   Chandekar tried to move core.attributesfile into repo_settings,
> >   Junio questioned whether attribute data belongs to a repository at
> >   all, since attributes come from the index and the working tree,
> >   and compared it to how index_state is passed around instead of the
> >   repository [7]. The config value was later stored in struct
> >   repo_config_values instead [5].
> > - State used during early startup cannot simply be moved; the setup
> >   code has to change first. Patrick did this for
> >   is_bare_repository_cfg and git_work_tree_cfg in his "setup: drop
> >   global state" series [8]. have_git_dir() is still left, and
> >   environment.h says it "should not have to exist at all".
> > - builtin/ commands: the "repo" argument of cmd_foo() can be NULL
> >   (e.g. "git foo -h" outside a repository), so blindly replacing
> >   the_repository there causes crashes. Library code is the safer
> >   target.
>
> In the discussion I mentioned above, Junio says that the code in
> "builtin/" isn't reusable library code at all, and that it would be
> useful work to move that code into library helpers.
>
> [...]
>
> > Blogging
> > ========
> >
> > I will blog on Medium (https://medium.com/@okhuomonajayi54) and
> > post weekly updates on my progress, what I learned and the
> > challenges I faced. I will share each post on the mailing list,
> > like previous interns did.
>
> I wonder if blog posts on Medium are accessible to everyone.
>
> Thanks.
Okhuomon Ajayi· Nov 4, 2026, 08:33 UTC · re: Okhuomon Ajayi · lore

[Outreachy][Proposal v2]: Reduce Git's global state to enable Git's libification

Hello,
This is the second version of my proposal for the project "Reduce
Git's global state to enable Git's libification" for the December
2026 Outreachy internship. v1 is here [16].
 
Changes since v1
----------------
- Blog: moved from Medium to Hashnode, so that posts can be read
  without an account, as Christian pointed out [17].
- Plan: added moving reusable code from builtin/ into library
  helpers, following the discussion Christian pointed to [18].
- Plan: I will send related conversions as one series instead of
  many small topics, as Patrick asked [19].
- Contributions: updated statuses, added the patches sent since v1,
  and what I learned from the notes-utils review [20].
- Reviews: added my review of Srujith's submodule patch.
I'd appreciate any feedback.

Personal Information ====================

Full Name: Okhuomon Rosemary Ajayi
Email: okhuomonajayi54@gmail.com
GitHub: https://github.com/six-shot
Blog: https://hashnode.com/@okhuomonajayi
Location: Lagos, Nigeria (WAT, UTC+1)

About Me ========

I am Okhuomon Rosemary Ajayi, often known as "sixshot", a self-taught software developer from Lagos, Nigeria. I am obsessed with robots and intelligent mechanical systems. C was the first programming language I picked up, before I moved into frontend and mobile development. Working on Git during this contribution period has brought me back to C, and I have enjoyed working at that lower level again.

Before Git, I contributed to other open source projects. In Servo I fixed clippy warnings in the script crate and improved some documentation [12]. In the OCaml ecosystem I added Deflate support and horizontal differencing to ocaml-tiff, and worked on raven and YOCaml [13]. In LibreOffice I worked in the C++ core, fixing a bug where Infobar keys reached the document and cleaning up unit conversion code [14]. In Mozilla Firefox I fixed layout bugs in vertical tabs and split view [15].

As a woman in tech, I know how much it helps to see someone like yourself doing the work. That is why I volunteered to train girls at Edunity for Girls, helping them get started in tech.

Honestly, I would like to be part of the Git community and keep on contributing to open source. This project lets me do that in C, the language I started with, and my patches on the_repository so far have shown me how much there is to learn here.

Past Experience with Git ========================

I have been using Git since I started coding, for my own projects and when collaborating with other developers.

This is not my first time on the Git mailing list. I applied to Outreachy in October 2025 and sent about ten patches in about a week (patch-ids, commit.c comments, builtin/patch-id.c, gpg-interface) [10]. None of them were merged. I was sending too fast, my subject lines had doubled prefixes like "[PATCH] [PATCH v2]", and my commit messages did not follow the project style, as Junio and Christian pointed out [11].

This year I slowed down. I read SubmittingPatches properly, wrote my commit messages in the present tense, and sent one change at a time. The hardest part was still sending new versions: keeping each version in sync with the review, the right thread and the notes on what changed since the last version. This time my microproject was merged to master, three more patches are in 'next' and marked "Will merge to 'master'", and range-diff is on its way to 'next'.

Contributions to the Git Community ==================================

Microproject
------------
+ delta-islands: use Q_() for island count
  Thread: https://lore.kernel.org/git/20261013203042.58610-1-okhuomonajayi54@gmail.com/
  Branch: oa/delta-islands-i18n-use-q
  Status: merged to 'master'
  Commit: 60e16b0387 (merge commit 7ac84b7267), listed in the
  Git 2.98.0 release notes
  Description: The island count in a progress message was built with
  a plain _() so translators could not handle plural forms. Use Q_()
  instead. v2 moved a reviewer note below the --- line after
  Junio's review.
Patches related to the project (the_repository)
------------------------------------------------
+ merge: stop using the_repository
  Thread: https://lore.kernel.org/git/20261015142532.48175-1-okhuomonajayi54@gmail.com/
  Branch: oa/merge-without-the-repository
  Status: in 'seen'
  Description: Pass the repository already available at the entry
  points down to the helpers, removing the_repository and
  the_hash_algo from merge.c.
+ merge-blobs: stop using the_repository
  Thread: https://lore.kernel.org/git/20261017105244.90295-1-okhuomonajayi54@gmail.com/
  Branch: oa/merge-blobs-stop-using-the-repository
  Status: in 'seen'
  Description: Use the repository reachable from the index_state
  instead of the global.
  Usman suggested renaming "r" to "repo"; Junio preferred the short
  "r" used elsewhere for "struct repository *", so I kept it [9].
+ diffcore-break: remove USE_THE_REPOSITORY_VARIABLE
  Thread: https://lore.kernel.org/git/20261014114904.85300-1-okhuomonajayi54@gmail.com/
  Status: in 'next', marked "Will merge to 'master'"
  Description: An earlier commit removed the last use of
  the_repository in diffcore-break.c, so the file no longer needs
  USE_THE_REPOSITORY_VARIABLE. Drop the define.
+ checkout: make unique_tracking_name() use the given repository
  (2 patches)
  Thread (v3): https://lore.kernel.org/git/20261023211533.73433-1-okhuomonajayi54@gmail.com/
  Status: v3 in 'seen'; Christian suggested unwrapping some lines
  now that they are shorter, which I will do in v4
  Description: Pass the repository to unique_tracking_name() and
  carry it in struct tracking_name_data, so checkout.c no longer
  needs USE_THE_REPOSITORY_VARIABLE. Usman asked for a clearer
  commit message in v1. In v2 Junio pointed out that the function
  still walked the remotes with for_each_remote(), which only works
  on the_repository, so v3 adds repo_for_each_remote() first.
+ diffcore-rename: stop using the_repository
  Thread: https://lore.kernel.org/git/20261024221341.92086-1-okhuomonajayi54@gmail.com/
  Status: in 'next', marked "Will merge to 'master'"
  Description: diffcore_rename_extended() already has the
  repository through its options. Use its hash algorithm when
  checking for empty blobs, pass it to start_delayed_progress(),
  and drop USE_THE_REPOSITORY_VARIABLE. Patrick reviewed it and
  said it looks correct.
+ notes-cache: read the cache ref from the given repository
  Thread: https://lore.kernel.org/git/20261026102603.32377-1-okhuomonajayi54@gmail.com/
  Status: reviewed by Junio, waiting to be queued
  Description: notes_cache_match_validity() already receives the
  repository but read the ref from the_repository. Pass it to
  get_main_ref_store() so the check reads the same repository.
+ combine-diff: use the repository from diff options
  Thread: https://lore.kernel.org/git/20261026111303.92117-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: show_combined_header() and show_patch_diff()
  already have opt->repo; use it for the hash algorithm,
  abbreviation and gitlinks. The file still needs the macro for
  DEFAULT_ABBREV, which depends on the default_abbrev global.
+ negotiator/default: stop using the_repository
  Thread (v2): https://lore.kernel.org/git/20261103155038.87456-1-okhuomonajayi54@gmail.com/
  Status: v2 sent after Christian's review (use the local variable
  I had introduced, and take the repository as the first argument,
  like most functions)
  Description: Give default_negotiator_init() a repository,
  store it on the negotiation state and use it to parse commits,
  clear marks and walk refs. Drop USE_THE_REPOSITORY_VARIABLE.
+ bundle-uri: stop using the_repository
  Thread (v2): https://lore.kernel.org/git/20261029131325.79176-1-okhuomonajayi54@gmail.com/
  Status: v2 in 'next', marked "Will merge to 'master'"
  Description: unbundle_from_file() unbundles objects into the
  given repository but read and wrote refs in the_repository, and
  fetch_bundle_uri() used the_repository for tracing. v1 used the
  given repository for both and was reviewed by Karthik. Patrick
  then pointed out that only two more uses were left in the file,
  in find_temp_filename() and copy_uri_to_file(), so v2 passes the
  repository to them too and drops USE_THE_REPOSITORY_VARIABLE
  from bundle-uri.c.
+ range-diff: use diffopt->repo instead of the_repository
  Thread (v2): https://lore.kernel.org/git/20261029084720.93221-1-okhuomonajayi54@gmail.com/
  Status: queued, marked "Will merge to 'next'?"
  Description: output_pair_header() and patch_diff() receive a
  diffopt that names the repository, but still used the_repository
  and the_hash_algo. Use diffopt->repo, and give get_filespec() a
  hash algorithm parameter. v2 rewords the commit message after
  Pablo's review.
+ pseudo-merge: use writer->repo instead of the_repository
  Thread: https://lore.kernel.org/git/20261029194116.63464-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: The functions in pseudo-merge.c receive a
  bitmap_writer that names the repository, but used the_repository.
  Use writer->repo, give push_pseudo_merge() a repository
  parameter, and drop USE_THE_REPOSITORY_VARIABLE.
+ name-hash: use istate->repo instead of the_repository
  Thread: https://lore.kernel.org/git/20261030183218.32630-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: Three functions receive the index but read
  core.ignoreCase through the_repository. Read it from istate->repo
  and drop USE_THE_REPOSITORY_VARIABLE.
+ fsmonitor: stop using the_repository
  Thread: https://lore.kernel.org/git/20261031111450.66192-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: refresh_fsmonitor() gets its repository from the
  index, but the helpers it calls used the_repository. Pass the
  repository to fsmonitor_hook_version(), use the one the other
  helpers already have, and drop USE_THE_REPOSITORY_VARIABLE.
+ wt-status: use the repository the status already has
  Thread: https://lore.kernel.org/git/20261101063951.85427-1-okhuomonajayi54@gmail.com/
  Status: sent, waiting for review
  Description: Use s->repo and r where the functions already have
  a repository. The define stays because DEFAULT_ABBREV expands to
  the global default_abbrev.
+ notes-utils: use the passed repository (v1 -> v2, 2 patches)
  Thread (v2): https://lore.kernel.org/git/20261103084930.15532-1-okhuomonajayi54@gmail.com/
  Status: I will drop it, see below
  Description: v1 made create_notes_commit() and commit_notes()
  use the repository they are given. Patrick asked why I stopped
  short of dropping USE_THE_REPOSITORY_VARIABLE, so v2 also passed
  a repository to init_copy_notes_for_rewrite() and dropped it.
  Karthik found the patches good and dug into the history of the
  file. Junio then pointed out that dropping the define is
  misleading: the functions in notes.h that notes-utils.c calls
  still only work with the_repository, so notes.h has to be
  cleaned up first [20]. This taught me to follow the calls down
  before claiming a file no longer depends on the_repository.
+ environment: move commit_encoding into repo_config_values
  Thread: https://lore.kernel.org/git/20261021155608.58509-1-okhuomonajayi54@gmail.com/
  Status: v1 reviewed by Junio; v2 in progress
  Description: v1 moved the global into struct repo_config_values.
  Junio pointed out that only commit.c uses it and suggested passing
  a "const char *" encoding down to the functions instead of the
  whole repository. v2 will do that.
Other patches
-------------
+ credential-store: add lockTimeout config option (#leftoverbits)
  Thread (v2): https://lore.kernel.org/git/20261016212216.58000-1-okhuomonajayi54@gmail.com/
  Status: v2 sent after Junio's review, waiting
  Description: Junio noted in the rerere thread that
  credentialStore.lockTimeoutMS is the only timeout setting with
  the unit in its name, and suggested a synonym without "MS". Add
  credentialStore.lockTimeout; the old name keeps working.
Reviews and help to other applicants
------------------------------------
+ list-objects-filter-options: pass repository to partial clone
  helpers (Dorine Tipo)
  My reply: https://lore.kernel.org/git/CAFpMFfCu6JrUC8i453qBP=AktqcG_9sGX=1-1ekEDCYm_+pkUw@mail.gmail.com/
  Description: Dorine asked whether USE_THE_REPOSITORY_VARIABLE
  could be dropped. I applied the patch, removed the define and
  checked that the file still builds, so it can go in the same
  patch. Dorine added it to v2 with a Helped-by trailer.
+ submodule: use the submodule repository to abbreviate commits
  (Srujith Poojary)
  My review: https://lore.kernel.org/git/CAFpMFfALb1KbEw-dc4wYCxS4PXfDBwzQOD6YPRe52_bpRnGt9w@mail.gmail.com/
  Description: Confirmed that the new test fails without the fix,
  and suggested describing the problem first, naming the code area
  in the title, choosing the repository once, and falling back to
  o->repo instead of the_repository. Srujith applied all of them
  in v2. On v2 I pointed out that "git log" on submodule.c always
  writes the area in lowercase, which he fixed in v3, and Junio
  queued the patch.
+ Microproject idea: modernize a file-existence check in
  t/t0081-find-pack.sh (Immaculate Mecha)
  My reply: https://lore.kernel.org/git/CAFpMFfA17dnuLSRt97BrM0u3cHAifJybr_Zc2ahr_zq2nspgsw@mail.gmail.com/
  Description: Pointed out that Shashank S had already changed that
  exact line, and suggested searching lore and "What's cooking"
  before choosing a microproject.
Git Rev News
------------
+ Proofread edition 140 and fixed typos in the Developer Spotlight
  interview (https://github.com/git/git.github.io/pull/878). It was
  merged, and I am credited in the published edition.
Learning resource
-----------------
+ "Learn C by reading Git" -- a zero-to-hero guide
  Link: https://six-shot.github.io/six-shot-git-c-zero-to-hero/
  Description: C was the first language I learned, but I had not
  used it in a while. I built this guide during this Outreachy
  contribution period so I could understand C well by learning it
  with Git itself. It teaches C from zero using real code from
  git.git (repository.h, merge-blobs.c, git.c, ...), with
  exercises. It covers the patterns this project depends on:
  structs and pointers, passing "struct repository *" down a call
  chain, and why global variables like the_repository are a
  problem. I hope it also helps other people who want to start
  contributing to Git.

Project Overview ================

Git keeps the state of the repository it is working on in a single global object, the_repository, which is a "struct repository". A lot of internal code uses this global directly instead of taking a repository as a parameter. On top of that, many configuration and environment values are stored as global variables in environment.c rather than in the repository they belong to.

This design assumes that a process only ever works with one repository. That is not true for things like submodules, and it is one of the main things blocking the long-term goal of libifying Git, where a program could open several repositories at the same time. With shared globals, two repositories in one process would read and overwrite the same values, which can lead to wrong behaviour that is hard to debug. It also makes the code harder to read and test, because a function's dependencies are hidden instead of being visible in its parameters.

This project reduces that global state step by step:
- removing the_repository from library code by passing the
  repository explicitly through the call chain, so files no longer
  need USE_THE_REPOSITORY_VARIABLE;
- moving repository-specific settings from environment.c into the
  repository, mostly struct repo_config_values and struct
  repo_settings;
- and, where a value is only used in one place, passing just that
  value down instead of the whole repository.

A lot of progress has already been made: many settings that used to be globals now live in struct repo_config_values, and many files no longer need the_repository. But there is still plenty left. Over a hundred library files outside builtin/ still define USE_THE_REPOSITORY_VARIABLE, and environment.h still has globals such as git_commit_encoding, git_log_output_encoding and comment_line_str. That remaining library code is where I want to focus.

Review of Previous Work and Strategies ======================================

From reading past series on the list and from my own patches, I see three strategies, and the right one depends on the variable:

1. Thread the repository through the call chain, bottom-up.
   Patrick Steinhardt introduced USE_THE_REPOSITORY_VARIABLE so files
   that still depend on the global are marked [1]. Work then goes from
   the lowest layers up, removing the macro file by file (objects [2],
   path [3], packfile by Karthik [4]). My patches to merge.c,
   merge-blobs.c, diffcore-break.c, diffcore-rename.c, checkout.c,
   notes-cache.c, combine-diff.c, negotiator/default.c,
   bundle-uri.c and range-diff.c follow this pattern.
2. Move repository-scoped config into the repository.
   core.hooksPath and core.sharedRepository moved into repo-settings
   with accessors [3]. Later, Olamide Caleb Bello's Outreachy series
   added struct repo_config_values, with repo_config_values(repo) as
   the accessor, and moved core.attributesFile, core.sparseCheckout
   and branch.autoSetupMerge into it [5]. Others, such as Tian Yuchen,
   have moved more values there since.
3. Pass only the value the function needs.
   the_hash_algo was replaced by an explicit
   "const struct git_hash_algo *" in csum-file.c [2]. Junio asked for
   the same thing on my commit_encoding patch: since only commit.c
   uses the variable, pass the encoding string instead of adding it
   to repository config [6].
Roadblocks seen in earlier work
-------------------------------
- Not every global belongs in struct repository. When Ayush
  Chandekar tried to move core.attributesfile into repo_settings,
  Junio questioned whether attribute data belongs to a repository at
  all, since attributes come from the index and the working tree,
  and compared it to how index_state is passed around instead of the
  repository [7]. The config value was later stored in struct
  repo_config_values instead [5].
- State used during early startup cannot simply be moved; the setup
  code has to change first. Patrick did this for
  is_bare_repository_cfg and git_work_tree_cfg in his "setup: drop
  global state" series [8]. have_git_dir() is still left, and
  environment.h says it "should not have to exist at all".
- builtin/ commands: the "repo" argument of cmd_foo() can be NULL
  (e.g. "git foo -h" outside a repository), so blindly replacing
  the_repository there causes crashes. Library code is the safer
  target.
- Naming: Junio prefers a short "r" for "struct repository *"
  parameters [9], and most functions take it as their first
  argument.
- Hidden dependencies: a file can pass a repository everywhere and
  still depend on the_repository through the functions it calls.
  For notes-utils.c, the notes.h functions underneath still only
  work with the_repository, so dropping the define there would
  have been misleading [20]. Before dropping a define I now follow
  the calls down into the other files.
Can there be clear criteria? Only partly. My working checklist:
  a. Who reads and writes it? (git grep every use)
  b. Is it per-repository, per-index, per-subsystem or process-wide?
  c. Is it needed before a repository is set up?
  d. Does only one file use it? Then pass the value (strategy 3).
  e. Search the list for earlier attempts and objections first.
Anything still unclear goes to the list as a question before code.
Example: git_log_output_encoding
--------------------------------
This is the encoding Git uses when it shows commit messages. It is
the twin of git_commit_encoding, which my commit_encoding patch
works on, but it is harder:
- It is set in two places: from i18n.logOutputEncoding in
  environment.c, and from "git log --encoding=..." in revision.c.
  Other revision options like --reverse are stored in struct
  rev_info, but --encoding writes the global. The parsing was moved
  into revision.c in 2006 (7cbcf4d557) so that rev-list and
  diff-tree could use it too, and at that time the rest of the
  code read the encoding from a global anyway.
- It is read through get_log_output_encoding() 15 times in 12
  files. Many of these callers (log-tree.c, bundle.c, submodule.c,
  sequencer.c) copy it into
  "struct pretty_print_context.output_encoding", so that struct
  already carries the value. That points to strategy 3: fill the
  context once from the caller and let the pretty-printing code use
  ctx->output_encoding instead of calling the global getter.
- Some callers do not print a log: remote-curl.c uses it to
  re-encode an error message from the server, and sequencer.c uses
  it when building the todo list. So the value is really "the
  user's display encoding", not something that belongs to one
  repository. That is a reason NOT to put it in
  repo_config_values, which is also what Junio said about
  commit_encoding [6].

My plan for it: first do commit_encoding (single caller), then propose on the list storing the --encoding value in struct rev_info and passing it through pretty_print_context, and ask whether that design is acceptable before writing the series.

Internship Plan and Timeline ============================

The internship runs from 7 December 2026 to 8 March 2027.
Before the internship (now -- 6 Dec 2026)
- Finish open patches: commit_encoding v2, checkout v4 and the
  others waiting for review. No new topics until those are
  reviewed.
- Keep reviewing other applicants' patches in the global-state area.
- Build a list of remaining globals and USE_THE_REPOSITORY_VARIABLE
  files outside builtin/, ordered by how low in the call graph they
  sit.
Weeks 1-2 (7 Dec -- 20 Dec)
- Agree the list and order with mentors.
- First series: a group of related library files off
  USE_THE_REPOSITORY_VARIABLE, sent together instead of one topic
  per file [19].
- First blog post.
Weeks 3-6 (21 Dec -- 17 Jan)
- environment.c globals that only one subsystem uses: pass the value
  down, as Junio suggested for commit_encoding.
- git_log_output_encoding next: it is read in 12 files and also set
  by "--encoding", so agree the design on the list before coding.
- Ask on the list before touching the comment_line_str group and the
  abbrev globals, since they are read in many places.
Weeks 7-10 (18 Jan -- 14 Feb)
- Continue bottom-up removal of the_repository in library code,
  one subsystem per series.
- Move reusable code out of builtin/ into library helpers, which
  Junio describes as useful work because builtin/ code cannot be
  reused [18]. Agree candidates with mentors first.
- Look at a harder item if mentors agree, such as have_git_dir(),
  which still depends on the_repository.
Weeks 11-13 (15 Feb -- 8 Mar 2027)
- Land rerolls, no new big series.
- Final report on the blog and the list.
- Update the "Learn C by reading Git" guide with what I learned.
Throughout: related changes batched into one series, reply to
reviews within a day or two,
weekly blog post, weekly sync with mentors.

Availability ============

I can give 40 hours a week to the project during the internship. I am based in Lagos (WAT, UTC+1) and can adjust my hours for calls and reviews when needed.

Blogging ========

I will blog on Hashnode (https://hashnode.com/@okhuomonajayi), which anyone can read without an account, and post weekly updates on my progress, what I learned and the challenges I faced. I will share each post on the mailing list, like previous interns did.

After the Internship ====================

After the internship I want to continue as an open source contributor to Git: sending patches, reviewing others' work and helping new contributors get started, the way Usman and Junio helped me. I also want to keep the "Learn C by reading Git" guide up to date so it stays useful for future applicants.

Appreciation ============

I want to thank Usman and Junio for always helping out during this contribution period. I also want to thank Patrick, Karthik, Pablo, Christian, Siddharth and Kaartic, who reviewed my work and gave me feedback, and everyone in the Git community for being so welcoming.

References
==========
[1] https://lore.kernel.org/git/cover.1718347699.git.ps@pks.im/
[2] https://lore.kernel.org/git/20250306-b4-pks-objects-without-the-repository-v2-1-f3465327be69@pks.im/
[3] https://lore.kernel.org/git/20250207-b4-pks-path-drop-the-repository-v2-14-13cad3c11b8a@pks.im/
[4] https://lore.kernel.org/git/cover.1733236936.git.karthik.188@gmail.com/
[5] https://lore.kernel.org/git/cover.1771258573.git.belkid98@gmail.com/
[6] https://lore.kernel.org/git/xmqq33tyn5qi.fsf@gitster.g/
[7] https://lore.kernel.org/git/xmqqwmcw97z2.fsf@gitster.g/
[8] https://lore.kernel.org/git/20260611-b4-pks-setup-drop-global-state-v2-0-a6f7269c841d@pks.im/
[9] https://lore.kernel.org/git/xmqqwlrcrqaz.fsf@gitster.g/
[10] https://lore.kernel.org/git/20251009214445.1190274-1-okhuomonajayi54@gmail.com/
[11] https://lore.kernel.org/git/CAP8UFD2sdvkv_ZqiLZU9k5zF+tM3UTQ8+mJjziRZGzOra6dMFA@mail.gmail.com/
     https://lore.kernel.org/git/xmqqo6q5z6iu.fsf@gitster.g/
[12] https://github.com/servo/servo/pulls?q=is%3Apr+author%3Asix-shot+is%3Amerged
[13] https://github.com/geocaml/ocaml-tiff/pull/80
     https://github.com/raven-ml/raven/pulls?q=is%3Apr+author%3Asix-shot
     https://github.com/xhtmlboi/yocaml/pulls?q=is%3Apr+author%3Asix-shot
[14] https://gerrit.libreoffice.org/q/owner:okhuomonajayi54@gmail.com+status:merged
     https://whatsnew.libreoffice.org/25.8.4/
[15] https://github.com/mozilla-firefox/firefox/commits?author=okhuomonajayi54@gmail.com
[16] https://lore.kernel.org/git/20261029141818.40193-1-okhuomonajayi54@gmail.com/
[17] https://lore.kernel.org/git/CAP8UFD1VUCTeXNbb4YKGkZRWY8i56Zms_=qkR2oqF7e1Aagy1Q@mail.gmail.com/
[18] https://lore.kernel.org/git/xmqqmru76ybk.fsf_-_@gitster.g/
[19] https://lore.kernel.org/git/auhtiZ86trLamccS@pks.im/
[20] https://lore.kernel.org/git/xmqqjymt94l3.fsf@gitster.g/
Thanks for reading.
Okhuomon Ajayi
Usman Akinyemi· Nov 5, 2026, 00:16 UTC · re: Okhuomon Ajayi · lore

Re: [Outreachy][Proposal v2]: Reduce Git's global state to enable Git's libification

On Wed, Nov 4, 2026 at 9:33 AM Okhuomon Ajayi <okhuomonajayi54@gmail.com> wrote:
>
> Hello,
Thanks for your proposal. Do not forget to submit on the Outreachy website.
Thanks for your contributions and your interest in the Git project.
Thanks.
Usman.

← back to recent threads