{"thread":{"id":"65042","subject":"[GSoC][Draft Proposal] Refactoring in order to reduce Git's global state","startedAt":"2026-02-22T17:59:19Z","lastAt":"2026-03-14T17:57:12Z","messageCount":18,"participants":["Tian Yuchen","Usman Akinyemi","Karthik Nayak","Phillip Wood","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"536652","messageId":"ab45758c-fbcf-42b2-96df-030eef8526c3@gmail.com","threadId":"65042","inReplyTo":null,"subject":"[GSoC][Draft Proposal] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-22T17:59:15Z","receivedAt":"2026-02-22T17:59:19Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi everyone,\n\nI'm Tian Yuchen and I'm planning to apply for GSoC this year!\n\nInstead of pasting a giant wall of text into this email, I have\ndrafted my proposal in Google Doc. I thought it might be easier for\neveryone to leave inline comments and suggestions there. (Of course, if \nyou're more accustomed to email replies, you can also quote the content \nfrom the doc in your response. Thank you.)\n\nHere is the link:\n\nhttps://docs.google.com/document/d/1t2sznOvnPz-9tOzVMH--pLxzRqYSJCFzqVWBVfL_NP8/edit?tab=t.0#heading=h.c3c40ftj1ilv\n\nFeel free to provide feedback!\n\nRegards,\n\nYuchen\n"},{"id":"536657","messageId":"CAPSxiM-f1nQiFAW=dDCCqr1Yce=ZrVrMYE0YHc+-cFAjx+5m8A@mail.gmail.com","threadId":"65042","inReplyTo":"ab45758c-fbcf-42b2-96df-030eef8526c3@gmail.com","subject":"Re: [GSoC][Draft Proposal] Refactoring in order to reduce Git's global state","fromName":"Usman Akinyemi","fromEmail":"usmanakinyemi202@gmail.com","sentAt":"2026-02-22T18:34:02Z","receivedAt":"2026-02-22T18:34:16Z","isPatch":false,"sender":{"key":"usmanakinyemi202@gmail.com","avatar":"https://avatars.githubusercontent.com/u/86585626?v=4"},"body":"On Sun, Feb 22, 2026 at 11:29 PM Tian Yuchen <a3205153416@gmail.com> wrote:\n>\n> Hi everyone,\n>\n> I'm Tian Yuchen and I'm planning to apply for GSoC this year!\n>\n> Instead of pasting a giant wall of text into this email, I have\n> drafted my proposal in Google Doc. I thought it might be easier for\n> everyone to leave inline comments and suggestions there. (Of course, if\n> you're more accustomed to email replies, you can also quote the content\n> from the doc in your response. Thank you.)\nI believe that a giant wall of text is the appropriate way to send a\nproposal to the\nGit community. I will advise you to send that giant of text actually.\nIt is easier for the\ncommunity to review and give feedback. Also future gsoc participants\ncan also learn\nfrom it. By telling the reviewer to go through the link to the docs\nand then copy it on the\nto the email just to reply is giving them an extra lot of work to do.\nSo send it through text\nand make it easy for people to review.\n>\n>\nThank you.\n"},{"id":"536681","messageId":"b3660d47-1129-4d07-9032-029e232a6d4b@gmail.com","threadId":"65042","inReplyTo":"CAPSxiM-f1nQiFAW=dDCCqr1Yce=ZrVrMYE0YHc+-cFAjx+5m8A@mail.gmail.com","subject":"Re: [GSoC][Draft Proposal] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-23T00:57:01Z","receivedAt":"2026-02-23T00:57:06Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"On 2/23/26 02:34, Usman Akinyemi wrote:\n> On Sun, Feb 22, 2026 at 11:29 PM Tian Yuchen <a3205153416@gmail.com> wrote:\n>>\n>> Hi everyone,\n>>\n>> I'm Tian Yuchen and I'm planning to apply for GSoC this year!\n>>\n>> Instead of pasting a giant wall of text into this email, I have\n>> drafted my proposal in Google Doc. I thought it might be easier for\n>> everyone to leave inline comments and suggestions there. (Of course, if\n>> you're more accustomed to email replies, you can also quote the content\n>> from the doc in your response. Thank you.)\n> I believe that a giant wall of text is the appropriate way to send a\n> proposal to the\n> Git community. I will advise you to send that giant of text actually.\n> It is easier for the\n> community to review and give feedback. Also future gsoc participants\n> can also learn\n> from it. By telling the reviewer to go through the link to the docs\n> and then copy it on the\n> to the email just to reply is giving them an extra lot of work to do.\n> So send it through text\n> and make it easy for people to review.\n>>\n>>\n> Thank you.\n\nMakes sense. I will format the proposal into plain text and send it as \nv2 shortly so it's easier to review inline and properly archived.\n\nThanks,\n\nYuchen\n"},{"id":"536682","messageId":"1bbafedb-b87b-4f1c-bce3-59089ac1ff8b@gmail.com","threadId":"65042","inReplyTo":"ab45758c-fbcf-42b2-96df-030eef8526c3@gmail.com","subject":"[GSoC][Draft Proposal V2] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-23T01:07:23Z","receivedAt":"2026-02-23T01:07:28Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hello everyone,\n\nI'm Tian Yuchen and I'm planning to apply for GSoC project this year. I \nhope you can take the time to review my proposal.\n\nPlease feel free to leave feedback!\n\nGoogle Docs link:\n\nhttps://docs.google.com/document/d/1t2sznOvnPz-9tOzVMH--pLxzRqYSJCFzqVWBVfL_NP8/edit?tab=t.0#heading=h.c3c40ftj1ilv\n\n\n\n\nRefactoring in order to reduce Git's global state\n=================================================\n\nPERSONAL INFORMATION\n--------------------\nName: Tian Yuchen\nE-mail: a3205153416@gmail.com\nPhone number: +65 98740318\nTime-zone: UTC + 08:00\nGithub: https://github.com/malon7782\n\nEducation: NTU, Singapore\nYear: Year 1 semester 2\nDegree: Electrical and Electronic Engineering (EEE)\n\n\nPRE GSOC\n--------\nI have always held a deep passion for the open-source community. \nAlthough I wasn't a computer science major, I tinkered with open-source \nprojects long before college. I have solid hands-on experience in C \nprogramming and system-level debugging.\n\nI use Ubuntu 24.04 on a daily basis, so I am proficient in using the \nLinux command line and CLI tools.\n\nI have contributed to the Git community by sending patches. Since my \nfirst commit (17/1/2026), I have maintained a nearly daily contribution. \nHere is the list of contributions I have made:\n\n* [PATCH v1] t1005: modernize \"! test -f\" to \"test_path_is_missing\"\n  \nhttps://lore.kernel.org/git/20260117062515.319664-1-a3205153416@gmail.com/\n   This patch is my microproject, the first contribution I made to the \ncodebase.\n   [Graduated to 'master']\n\n* [PATCH v2] t2203: avoid masking exit codes in git status\n  \nhttps://lore.kernel.org/git/20260118043537.338769-1-a3205153416@gmail.com/#t\n\n* [PATCH v2] symlinks: use unsigned int for flags\n  \nhttps://lore.kernel.org/git/20260120152219.398999-1-a3205153416@gmail.com/\n   [Will merge to 'next']\n\n* [PATCH v4] t/perf/p3400: speed up setup using fast-import\n  \nhttps://lore.kernel.org/git/20260130170123.642344-1-a3205153416@gmail.com/\n   [Will merge to 'master']\n\n* Re: [PATCH] [RFC] attr: use local repository state in read_attr\n  \nhttps://lore.kernel.org/git/cc2f400e-49c2-4de0-9c51-9a5c0294735e@gmail.com/\n   Code review. To verify the performance loss, I wrote a test script to\n   measure the time difference before and after the modification.\n\n* Re: Bug: git add :!x . exits with error when x is in .gitignore\n  \nhttps://lore.kernel.org/git/1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com/\n   Code review. Pointed out logical error.\n\n* [PATCH v10] setup: allow cwd/.git to be a symlink to a directory\n  \nhttps://lore.kernel.org/git/20260220164512.216901-1-a3205153416@gmail.com/\n   In progress.\n   After over half a month of discussions, repeated refactoring, and code\n   reviews, I delved deep into setup.c. I gained insights into Git's \ndesign philosophy, and learned the art of striking a balance in \ndeveloper communication. It took me a large amount of time and effort to \nthoroughly understand every line of the code. I often found myself \nporing over the call chain of a single function well into the night.... \nBut I persevered until the end, and I believe my patience will see me \nthrough even larger projects.\n\n\nABOUT THE PROJECT\n-----------------\n\n-- Synopsis\n\nAs far as I know, the Git community is actively working towards \n'libification' - making Git's internal machinery reusable as a C \nlibrary. The extensive reliance on global state is a major roadblock to \nthis goal.\n\nMany core functions implicitly read environment variables and store them \nin global static variables. This can cause several issues:\n\n   1. Global variables prevent Git's core functions from being executed \nsafely in multi-threaded contexts.\n   2. When Git is called multiple times within the same process, global \nstates can lead to memory leaks or incorrect behaviors.\n   3. Unit testing becomes difficult because the environment must be \nartificially manipulated before calling functions.\n\nTake a look at this example from environment.c:\n\n     206 const char *get_commit_output_encoding(void)\n     207 {\n     208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n     209 }\n\nIf Git is invoked as a C library by a multi-threaded server:\n- Thread A formats a commit for Repo A (using GBK);\n- Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThen they will race to read and overwrite the exact same global\n`git_commit_encoding` pointer, which is not what we expect. Therefore,\nwe have to refactor these environment variables by moving them from\nglobal scope into a well-defined and encapsulated context.\n\n\n-- Approach\n\nThe task at hand can be summed up in one sentence: repackage the global\nvariables into the `struct repository` structure. In other words:\n\n     [ Current ]\n     Core functions --------reads-------> Global variables (via getenv)\n                                          [Thread unsafe]\n\n     [ Target ]\n     Core functions ----passes context--> struct repository\n                                                 | owns\n                                                 v\n                                          struct git_env\n\nAlthough the principle is simple, the scope of changes is extensive. The\nfollowing three-step approach can serve as a guiding principle for it:\n\n   1. Identify isolated environment variables currently residing in the\n      global scope. Introduce a dedicated structure to hold these states,\n      e.g. `struct git_env` within the `struct repository`.\n   2. Modify the function signatures within the call chain to accept the\n      context, e.g., `struct repository *repo`, instead of relying on\n      implicit globals. External callers of the functions must be\n      carefully audited to prevent regressions.\n   3. Safely remove the old global variables and macro definitions. Tools\n      such as AddressSanitizer can be helpful to ensure that the new\n      struct-based lifecycle introduces zero memory leaks.\n\nAdditionally, given the anticipated high volume of commits, we must \nensure each patch is independent and atomic, preventing any \nuser-untraceable or unexplainable bugs from occurring in the codebase at \nany state.\n\n\nAVAILABILITY\n------------\nFortunately, my summer vacation coincides with the GSoC work period.\nI will treat this project as my primary focus, dedicating a minimum of\n35 hours per week. If needed, I can work a 9-to-5 schedule.\n\nI will have a significant head start to draft RFC patches before the\nofficial coding period even begins. Having this buffer period allows me\nto go through the rigorous code review process within the Git community\nwith greater ease.\n\n\nTIMELINE & MILESTONES\n---------------------\nConsidering the differences between this project and other projects on \nthe idea list, rather than hoarding massive changes, I will submit \n3-to-5-patch series frequently to respect reviewers' time and maintain a \nsteady velocity.\n\nBelow is the tentative schedule I have prepared for myself:\n\n* Community Bonding (May 1 - May 25): Planning & RFC\n   - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n     prioritized list of subsystems with my mentor.\n   - May 8 - May 25: Define the core context container. Draft and submit\n     the initial RFC patch series for this new data structure.\n\n* Phase 1 (May 26 - July 10): Foundation\n   - Weeks 1-2: Plumb the context pointer (`struct repository *repo`) \nthrough call chains for simple variables (e.g., boolean flags or integer \nconfigs).\n   - Weeks 3-4: Audit and update external callers to use the new API.\n   - Weeks 5-6: Submit the first major refactoring patch series. Address\n     mailing list feedback and resolve merge conflicts. (Midterm Evaluation)\n\n* Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n   - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related \nglobals).\n   - Weeks 9-10: Compile the codebase with AddressSanitizer and run the \nfull test suite to execute strict memory leak checks.\n   - Weeks 11-12: Remove unused global macro definitions and static \nvariables. Update internal documentation and write the final GSoC report.\n\n(The above is for reference only. Personally, I always finish tasks \nfaster than planned ;)\n\n\n~$ git checkout HEAD@{postGSoC}\n-------------------------------\nThis past month since joining the Git community has been the most \nenjoyable month of my programming journey. To quote a close friend of \nmine (who is applying for the Neovim GSoC project):\n\n   \"Only fools chase trends; open source is the game for the brave.\"\n\nThe words may be blunt, but the logic holds true. This statement surely\nresonates with me (and maybe many other GSoC contributors): our passion\nfor code and open-source drives us forward.\n\nEven if I didn't make the cut, so what? ~$ git reset --hard...\nJust kidding. The Git codebase is far too interesting to abandon now.\n\n-------------------------------------------------------------------------\nChanges since V1:\n\n  - Transfer the text from Google Docs to here.\n\n\n\nRegards,\n\nYuchen\n"},{"id":"537104","messageId":"b98780d7-3aa9-4838-9234-290b1d72ffd7@gmail.com","threadId":"65042","inReplyTo":"ab45758c-fbcf-42b2-96df-030eef8526c3@gmail.com","subject":"Re: [GSoC][Draft Proposal v3] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-25T17:11:23Z","receivedAt":"2026-02-25T17:11:28Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi mentors and the git community,\n\nHere is the proposal V3.\n\n\nRefactoring in order to reduce Git's global state\n=================================================\n\nPERSONAL INFORMATION\n--------------------\nName: Tian Yuchen\nE-mail: a3205153416@gmail.com\nPhone number: +65 98740318\nTime-zone: UTC + 08:00\nGithub: https://github.com/malon7782\n\nEducation: NTU, Singapore\nYear: Year 1 semester 2\nDegree: Electrical and Electronic Engineering (EEE)\n\n\nPRE GSOC\n--------\nI have always held a deep passion for the open-source community. \nAlthough I wasn't a computer science major, I tinkered with open-source \nprojects long before college. I have solid hands-on experience in C \nprogramming and system-level debugging.\n\nI use Ubuntu 24.04 on a daily basis, so I am proficient in using the \nLinux command line and CLI tools.\n\nI have contributed to the Git community by sending patches. Since my \nfirst commit (17/1/2026), I have maintained a nearly daily contribution. \nHere is the list of contributions I have made:\n\n* [PATCH v1] t1005: modernize \"! test -f\" to \"test_path_is_missing\"\n\nhttps://lore.kernel.org/git/20260117062515.319664-1-a3205153416@gmail.com/\n   This patch is my microproject, the first contribution I made to the \ncodebase.\n   [Graduated to 'master']\n\n* [PATCH v2] t2203: avoid masking exit codes in git status\n\nhttps://lore.kernel.org/git/20260118043537.338769-1-a3205153416@gmail.com/#t\n\n* [PATCH v2] symlinks: use unsigned int for flags\n\nhttps://lore.kernel.org/git/20260120152219.398999-1-a3205153416@gmail.com/\n   [Will merge to 'next']\n\n* [PATCH v4] t/perf/p3400: speed up setup using fast-import\n\nhttps://lore.kernel.org/git/20260130170123.642344-1-a3205153416@gmail.com/\n   [Will merge to 'master']\n\n* Re: [PATCH] [RFC] attr: use local repository state in read_attr\n\nhttps://lore.kernel.org/git/cc2f400e-49c2-4de0-9c51-9a5c0294735e@gmail.com/\n   Code review. To verify the performance loss, I wrote a test script to\n   measure the time difference before and after the modification.\n\n* Re: Bug: git add :!x . exits with error when x is in .gitignore\n\nhttps://lore.kernel.org/git/1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com/\n   Code review. Pointed out logical error.\n\n* [PATCH v10] setup: allow cwd/.git to be a symlink to a directory\n\nhttps://lore.kernel.org/git/20260220164512.216901-1-a3205153416@gmail.com/\n   [Under review]\n   After over half a month of discussions, repeated refactoring, and code\n   reviews, I delved deep into setup.c. I gained insights into Git's \ndesign philosophy, and learned the art of striking a balance in \ndeveloper communication. It took me a large amount of time and effort to \nthoroughly understand every line of the code. I often found myself \nporing over the call chain of a single function well into the night.... \nBut I persevered until the end, and I believe my patience will see me \nthrough even larger projects.\n\n\nABOUT THE PROJECT\n-----------------\n\n-- Synopsis\n\nAs far as I know, the Git community is actively working towards \n'libification' - making Git's internal machinery reusable as a C \nlibrary. The extensive reliance on global state is a major roadblock to \nthis goal.\n\nMany core functions implicitly read environment variables and store them \nin global static variables. This can cause several issues:\n\n   1. Global variables prevent Git's core functions from being executed \nsafely in multi-threaded contexts. For example, When unexpected states \n(e.g., a permission denied error when probing a directory), they often \nrely on the global state to decide whether to call die(), which \ninternally calls exit(). It’s fine for a standalone CLI tool, but for a \nlinked C library used by a long-running multi-threaded server, a single \ndie() call will kill the entire host process. Structured status, instead \nof fatal exits, should be returned.\n   2. When Git is called multiple times within the same process, global \nstates can lead to memory leaks or incorrect behaviors.\n   3. Unit testing becomes difficult because the environment must be \nartificially manipulated before calling functions.\n\nTake a look at this example from environment.c:\n\n     206 const char *get_commit_output_encoding(void)\n     207 {\n     208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n     209 }\n\nIf Git is invoked as a C library by a multi-threaded server:\n- Thread A formats a commit for Repo A (using GBK);\n- Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThen they will race to read and overwrite the exact same global\n`git_commit_encoding` pointer, which is not what we expect. Therefore,\nwe have to refactor these environment variables by moving them from\nglobal scope into a well-defined and encapsulated context.\n\n\n-- Approach\n\nThe task at hand goes beyond simply repackaging the global variables \ninto the struct repository structure. Based on my recent experience \nrefactoring setup.c, I realized that libification requires careful \nmanagement of variable lifecycles and api boundaries:\n\n     [ Current ]\n     Core functions --------reads-------> Global variables (via getenv)\n                                          [Thread unsafe]\n\n     [ Target ]\n     Core functions ----passes context--> struct repository\n                                                 | owns\n                                                 v\n                                          struct git_env\n\nAlthough the principle is simple, the scope of changes is extensive. The\nfollowing three-step approach can serve as a guiding principle for it:\n\n   1. Identify isolated environment variables currently residing in the\n      global scope. Introduce a dedicated structure to hold these states,\n      e.g. `struct git_env` within the `struct repository`.\n   2. Instead of blindly passing struct repository *repo down into every\n      single low-level library function, bubbling the dependency up is\n      the true goal. External callers of the functions must be carefully\n      audited to prevent regressions.\n   3. Safely remove the old global variables and macro definitions. Tools\n      such as AddressSanitizer can be helpful to ensure that the new\n      struct-based lifecycle introduces zero memory leaks.\n   4. Many globals like are parsed once and remain available globally.\n      New data flow might need to be designed to maintain the lazy-\n      loading efficiency.\n\nAdditionally, given the anticipated high volume of commits, we must \nensure each patch is independent and atomic, preventing any \nuser-untraceable or unexplainable bugs from occurring in the codebase at \nany state.\n\n\nAVAILABILITY\n------------\nFortunately, my summer vacation coincides with the GSoC work period.\nI will treat this project as my primary focus, dedicating a minimum of\n35 hours per week. If needed, I can work a 9-to-5 schedule.\n\nI will have a significant head start to draft RFC patches before the\nofficial coding period even begins. Having this buffer period allows me\nto go through the rigorous code review process within the Git community\nwith greater ease.\n\n\nTIMELINE & MILESTONES\n---------------------\nConsidering the differences between this project and other projects on \nthe idea list, rather than hoarding massive changes, I will submit \n3-to-5-patch series frequently to respect reviewers' time and maintain a \nsteady velocity.\n\nBelow is the tentative schedule I have prepared for myself:\n\n* Community Bonding (May 1 - May 25): Planning & RFC\n   - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n     prioritized list of subsystems with my mentor.\n   - May 8 - May 25: Define the core context container. Draft and submit\n     the initial RFC patch series for this new data structure.\n\n* Phase 1 (May 26 - July 10): Foundation\n   - Weeks 1-2: Plumb the context pointer (`struct repository *repo`) \nthrough call chains for simple variables (e.g., boolean flags or integer \nconfigs).\n   - Weeks 3-4: Audit and update external callers to use the new API.\n   - Weeks 5-6: Submit the first major refactoring patch series. Address\n     mailing list feedback and resolve merge conflicts. (Midterm Evaluation)\n\n* Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n   - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related \nglobals).\n   - Weeks 9-10: Compile the codebase with AddressSanitizer and run the \nfull test suite to execute strict memory leak checks.\n   - Weeks 11-12: Remove unused global macro definitions and static \nvariables. Update internal documentation and write the final GSoC report.\n\n(The above is for reference only. Personally, I always finish tasks \nfaster than planned 😉)\n\n\n~$ git checkout HEAD@{postGSoC}\n-------------------------------\nThis past month since joining the Git community has been the most \nenjoyable month of my programming journey. To quote a close friend of \nmine (who is applying for the Neovim GSoC project):\n\n   \"Only fools chase trends; open source is the game for the brave.\"\n\nThe words may be blunt, but the logic holds true. This statement surely\nresonates with me (and maybe many other GSoC contributors): our passion\nfor code and open-source drives us forward.\n\nEven if I didn't make the cut, so what? ~$ git reset --hard...\nJust kidding. The Git codebase is far too interesting to abandon now.\n\n-------------------------------------------------------------------------\nChanges since V3:\n\n  - Based on reviewing last year's contributors' changes and recent \nexperience modifying setup.c, additional descriptions have been added to \nthe synopsis & approach section.\n"},{"id":"537177","messageId":"CAOLa=ZSyeNg7kSGV4=5wg02FYomGe0CbJ7GzCzT6okC64UWHMA@mail.gmail.com","threadId":"65042","inReplyTo":"b98780d7-3aa9-4838-9234-290b1d72ffd7@gmail.com","subject":"Re: [GSoC][Draft Proposal v3] Refactoring in order to reduce Git's global state","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2026-02-26T09:27:20Z","receivedAt":"2026-02-26T09:27:22Z","isPatch":false,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Tian Yuchen <a3205153416@gmail.com> writes:\n\nHello Tian,\n\n> Hi mentors and the git community,\n>\n> Here is the proposal V3.\n>\n\n[snip]\n\n>\n> -- Approach\n>\n> The task at hand goes beyond simply repackaging the global variables\n> into the struct repository structure. Based on my recent experience\n> refactoring setup.c, I realized that libification requires careful\n> management of variable lifecycles and api boundaries:\n>\n>      [ Current ]\n>      Core functions --------reads-------> Global variables (via getenv)\n>                                           [Thread unsafe]\n>\n>      [ Target ]\n>      Core functions ----passes context--> struct repository\n>                                                  | owns\n>                                                  v\n>                                           struct git_env\n>\n> Although the principle is simple, the scope of changes is extensive. The\n> following three-step approach can serve as a guiding principle for it:\n>\n>    1. Identify isolated environment variables currently residing in the\n>       global scope. Introduce a dedicated structure to hold these states,\n>       e.g. `struct git_env` within the `struct repository`.\n\nWell it depends, we already have `struct repo_settings`, and individual\nsettings within the `struct repository` struct. It would be a very case\nby case basis, to understand which variables fit where.\n\n>    2. Instead of blindly passing struct repository *repo down into every\n>       single low-level library function, bubbling the dependency up is\n>       the true goal. External callers of the functions must be carefully\n>       audited to prevent regressions.\n>    3. Safely remove the old global variables and macro definitions. Tools\n>       such as AddressSanitizer can be helpful to ensure that the new\n>       struct-based lifecycle introduces zero memory leaks.\n\nYes, we also have CI jobs for GitLab and GitHub which do this already,\nyou can run them locally too, meson makes it very easy to do this too:\n\n  $ meson setup address --fatal-meson-warnings --warnlevel 3 --werror \\\n  --wrap-mode nofallback -Dfuzzers=true -Db_sanitize=address \\\n  -Db_lundef=false\n  $ cd address\n  $ meson test\n\n>    4. Many globals like are parsed once and remain available globally.\n\nI think you're missing a reference in this sentence.\n\n>       New data flow might need to be designed to maintain the lazy-\n>       loading efficiency.\n>\n> Additionally, given the anticipated high volume of commits, we must\n> ensure each patch is independent and atomic, preventing any\n> user-untraceable or unexplainable bugs from occurring in the codebase at\n> any state.\n>\n>\n> AVAILABILITY\n> ------------\n> Fortunately, my summer vacation coincides with the GSoC work period.\n> I will treat this project as my primary focus, dedicating a minimum of\n> 35 hours per week. If needed, I can work a 9-to-5 schedule.\n>\n> I will have a significant head start to draft RFC patches before the\n> official coding period even begins. Having this buffer period allows me\n> to go through the rigorous code review process within the Git community\n> with greater ease.\n>\n>\n> TIMELINE & MILESTONES\n> ---------------------\n> Considering the differences between this project and other projects on\n> the idea list, rather than hoarding massive changes, I will submit\n> 3-to-5-patch series frequently to respect reviewers' time and maintain a\n> steady velocity.\n>\n> Below is the tentative schedule I have prepared for myself:\n>\n> * Community Bonding (May 1 - May 25): Planning & RFC\n>    - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n>      prioritized list of subsystems with my mentor.\n>    - May 8 - May 25: Define the core context container. Draft and submit\n>      the initial RFC patch series for this new data structure.\n>\n\nWhat is the 'core context container' here?\n\n> * Phase 1 (May 26 - July 10): Foundation\n>    - Weeks 1-2: Plumb the context pointer (`struct repository *repo`)\n> through call chains for simple variables (e.g., boolean flags or integer\n> configs).\n>    - Weeks 3-4: Audit and update external callers to use the new API.\n>    - Weeks 5-6: Submit the first major refactoring patch series. Address\n>      mailing list feedback and resolve merge conflicts. (Midterm Evaluation)\n>\n> * Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n>    - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related\n> globals).\n>    - Weeks 9-10: Compile the codebase with AddressSanitizer and run the\n> full test suite to execute strict memory leak checks.\n>    - Weeks 11-12: Remove unused global macro definitions and static\n> variables. Update internal documentation and write the final GSoC report.\n>\n> (The above is for reference only. Personally, I always finish tasks\n> faster than planned 😉)\n>\n>\n> ~$ git checkout HEAD@{postGSoC}\n> -------------------------------\n> This past month since joining the Git community has been the most\n> enjoyable month of my programming journey. To quote a close friend of\n> mine (who is applying for the Neovim GSoC project):\n>\n>    \"Only fools chase trends; open source is the game for the brave.\"\n>\n> The words may be blunt, but the logic holds true. This statement surely\n> resonates with me (and maybe many other GSoC contributors): our passion\n> for code and open-source drives us forward.\n>\n> Even if I didn't make the cut, so what? ~$ git reset --hard...\n> Just kidding. The Git codebase is far too interesting to abandon now.\n>\n> -------------------------------------------------------------------------\n> Changes since V3:\n>\n>   - Based on reviewing last year's contributors' changes and recent\n> experience modifying setup.c, additional descriptions have been added to\n> the synopsis & approach section.\n\nThanks for the proposal :)\n"},{"id":"537189","messageId":"2c0ff47a-0501-44b3-8fab-1ed93116d9ef@gmail.com","threadId":"65042","inReplyTo":"CAOLa=ZSyeNg7kSGV4=5wg02FYomGe0CbJ7GzCzT6okC64UWHMA@mail.gmail.com","subject":"Re: [GSoC][Draft Proposal v3] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-26T14:03:35Z","receivedAt":"2026-02-26T14:03:39Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi karthik,\n\nThank you so much for the review.\n\n> Well it depends, we already have `struct repo_settings`, and individual\n> settings within the `struct repository` struct. It would be a very case\n> by case basis, to understand which variables fit where.\n\nThat makes sense to me. I will update the approach to emphasize a \ncase-to-case analysis & mapping variables to their rightful existing homes.\n\n> Yes, we also have CI jobs for GitLab and GitHub which do this already,\n> you can run them locally too, meson makes it very easy to do this too:\n\nThank you for providing the information above. I have integrated this \ninto the V4 proposal. It indeed looks much more robust in terms of \nmemory leak auditing and other checks.\n\n> I think you're missing a reference in this sentence.\n\nSorry that was a typo. While writing the proposal, I went back to the \nsource code to confirm the function name here, but I forgot to add it \nback in LOL. I meant 'editor_program' :)\n\n> What is the 'core context container' here?\n\nEmmmm...It was referring to the 'struct git_env' idea (or something like \nthat), which is flawed as you mentioned earlier. Will revise the \ntimeline: the bonding period will be spent categorizing the targeted \nglobal variables and determining their appropriate stuctural \ndestinations (via RFC patches? I don't know if it's proper behavior).\n\n> Thanks for the proposal :)\n\nWill incorporate all these refinements and send out V4 within ~3 days (I \nhave midterm tests these days). Thanks again for your time and patience ;)\n\nRegards,\n\nYuchen\n\n"},{"id":"537191","messageId":"eca82f16-ae97-4dc1-8d2c-bb84cc856d9a@gmail.com","threadId":"65042","inReplyTo":"CAOLa=ZSyeNg7kSGV4=5wg02FYomGe0CbJ7GzCzT6okC64UWHMA@mail.gmail.com","subject":"Re: [GSoC][Draft Proposal v3] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-26T14:16:19Z","receivedAt":"2026-02-26T14:16:41Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi karthink,\n\nOne thing I forgot to mention—I plan to practice with a simple target \nfollowing the proposal's process to see if it works in the coming days. \nIf you have time to review it and offer some feedback, I'd be most grateful!\n\nThanks,\n\nYuchen\n\n"},{"id":"537210","messageId":"5e5f07ec-72ba-46ee-812c-d6773a4bdbe7@gmail.com","threadId":"65042","inReplyTo":"b98780d7-3aa9-4838-9234-290b1d72ffd7@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-26T17:02:51Z","receivedAt":"2026-02-26T17:03:11Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi all,\n\nHere is the V4 patch.\n\nThanks Karthink Nayak <karthink.188@gamil.com>, for help and guidance.\n\n\nRefactoring in order to reduce Git's global state\n=================================================\n\nPERSONAL INFORMATION\n--------------------\nName: Tian Yuchen\nE-mail: a3205153416@gmail.com\nPhone number: +65 98740318\nTime-zone: UTC + 08:00\nGithub: https://github.com/malon7782\n\nEducation: NTU, Singapore\nYear: Year 1 semester 2\nDegree: Electrical and Electronic Engineering (EEE)\n\n\nPRE GSOC\n--------\nI have always held a deep passion for the open-source community. \nAlthough I wasn't a computer science major, I tinkered with open-source \nprojects long before college. I have solid hands-on experience in C \nprogramming and system-level debugging.\n\nI use Ubuntu 24.04 on a daily basis, so I am proficient in using the \nLinux command line and CLI tools.\n\nI have contributed to the Git community by sending patches. Since my \nfirst commit (17/1/2026), I have maintained a nearly daily contribution. \nHere is the list of contributions I have made:\n\n* [PATCH v1] t1005: modernize \"! test -f\" to \"test_path_is_missing\"\n\nhttps://lore.kernel.org/git/20260117062515.319664-1-a3205153416@gmail.com/\n   This patch is my microproject, the first contribution I made to the \ncodebase.\n   [Graduated to 'master']\n\n* [PATCH v2] t2203: avoid masking exit codes in git status\n\nhttps://lore.kernel.org/git/20260118043537.338769-1-a3205153416@gmail.com/#t\n\n* [PATCH v2] symlinks: use unsigned int for flags\n\nhttps://lore.kernel.org/git/20260120152219.398999-1-a3205153416@gmail.com/\n   [Will merge to 'next']\n\n* [PATCH v4] t/perf/p3400: speed up setup using fast-import\n\nhttps://lore.kernel.org/git/20260130170123.642344-1-a3205153416@gmail.com/\n   [Will merge to 'master']\n\n* Re: [PATCH] [RFC] attr: use local repository state in read_attr\n\nhttps://lore.kernel.org/git/cc2f400e-49c2-4de0-9c51-9a5c0294735e@gmail.com/\n   Code review. To verify the performance loss, I wrote a test script to\n   measure the time difference before and after the modification.\n\n* Re: Bug: git add :!x . exits with error when x is in .gitignore\n\nhttps://lore.kernel.org/git/1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com/\n   Code review. Pointed out logical error.\n\n* [PATCH v10] setup: allow cwd/.git to be a symlink to a directory\n\nhttps://lore.kernel.org/git/20260220164512.216901-1-a3205153416@gmail.com/\n   [Under review]\n   After over half a month of discussions, repeated refactoring, and code\n   reviews, I delved deep into setup.c. I gained insights into Git's \ndesign philosophy, and learned the art of striking a balance in \ndeveloper communication. It took me a large amount of time and effort to \nthoroughly understand every line of the code. I often found myself \nporing over the call chain of a single function well into the night.... \nBut I persevered until the end, and I believe my patience will see me \nthrough even larger projects.\n\n\nABOUT THE PROJECT\n-----------------\n\n-- Synopsis\n\nAs far as I know, the Git community is actively working towards \n'libification' - making Git's internal machinery reusable as a C \nlibrary. The extensive reliance on global state is a major roadblock to \nthis goal.\n\nMany core functions implicitly read environment variables and store them \nin global static variables. This can cause several issues:\n\n   1. Global variables prevent Git's core functions from being executed \nsafely in multi-threaded contexts. For example, When unexpected states \n(e.g., a permission denied error when probing a directory), they often \nrely on the global state to decide whether to call die(), which \ninternally calls exit(). It’s fine for a standalone CLI tool, but for a \nlinked C library used by a long-running multi-threaded server, a single \ndie() call will kill the entire host process. Structured status, instead \nof fatal exits, should be returned.\n   2. When Git is called multiple times within the same process, global \nstates can lead to memory leaks or incorrect behaviors.\n   3. Unit testing becomes difficult because the environment must be \nartificially manipulated before calling functions.\n\nTake a look at this example from environment.c:\n\n     206 const char *get_commit_output_encoding(void)\n     207 {\n     208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n     209 }\n\nIf Git is invoked as a C library by a multi-threaded server:\n- Thread A formats a commit for Repo A (using GBK);\n- Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThen they will race to read and overwrite the exact same global\n`git_commit_encoding` pointer, which is not what we expect. Therefore,\nwe have to refactor these environment variables by moving them from\nglobal scope into a well-defined and encapsulated context.\n\n\n-- Approach\n\nThe task at hand goes beyond simply repackaging the global variables \ninto the struct repository structure. Based on my recent experience \nrefactoring setup.c, I realized that libification requires careful \nmanagement of variable lifecycles and api boundaries:\n\n     [ Current ]\n     Core functions --------reads-------> Global variables (via getenv)\n                                          [Thread unsafe]\n\n     [ Target ]\n     Core functions ----passes context--> struct repository\n                                                 | owns\n                                                 v\n                                          struct repo_settings\n\n\t\t\t\t         other domain-specific structs\n\nAlthough the principle is simple, the scope of changes is extensive. The\nfollowing three-step approach can serve as a guiding principle for it:\n\n   1. Identify isolated environment variables currently residing in the\n      global scope. Conduct a case-by-case analysis to map each variable\n      to its most appropriate existing home (e.g., struct repo_settings\n      for configuration values, or specific localized structs within\n      struct repository).\n   2. Instead of blindly passing struct repository *repo down into every\n      single low-level library function, bubbling the dependency up is\n      the true goal. External callers of the functions must be carefully\n      audited to prevent regressions.\n   3. Safely remove the old global variables and macro definitions. Make\n      full use of Git's existing GitLab/GitHub CI and utilize local\n      Meson builds with AddressSanitizer enabled to ensure that the new\n      lifecycle introduces zero memory leaks.\n   4. Many globals like `editor_program` are parsed once and remain\n      available globally. New data flow might need to be designed to\n      maintain the lazy-loading efficiency.\n\nAdditionally, given the anticipated high volume of commits, we must \nensure each patch is independent and atomic, preventing any \nuser-untraceable or unexplainable bugs from occurring in the codebase at \nany state.\n\n\nAVAILABILITY\n------------\nFortunately, my summer vacation coincides with the GSoC work period.\nI will treat this project as my primary focus, dedicating a minimum of\n35 hours per week. If needed, I can work a 9-to-5 schedule.\n\nI will have a significant head start to draft RFC patches before the\nofficial coding period even begins. Having this buffer period allows me\nto go through the rigorous code review process within the Git community\nwith greater ease.\n\n\nTIMELINE & MILESTONES\n---------------------\nConsidering the differences between this project and other projects on \nthe idea list, rather than hoarding massive changes, I will submit \n3-to-5-patch series frequently to respect reviewers' time and maintain a \nsteady velocity.\n\nBelow is the tentative schedule I have prepared for myself:\n\n* Community Bonding (May 1 - May 25): Planning & RFC\n   - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n     prioritized list of subsystems with my mentor.\n   - May 8 - May 25: Categorize the targeted global variables and map out\n     their intended destinations (e.g., repo_settings). Draft and submit\n     the initial RFC patch series.\n\n* Phase 1 (May 26 - July 10): Foundation\n   - Weeks 1-2: Plumb the context pointer (`struct repository *repo`) \nthrough call chains for simple variables (e.g., boolean flags or integer \nconfigs).\n   - Weeks 3-4: Audit and update external callers to use the new API.\n   - Weeks 5-6: Submit the first major refactoring patch series. Address\n     mailing list feedback and resolve merge conflicts. (Midterm Evaluation)\n\n* Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n   - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related \nglobals).\n   - Weeks 9-10: Compile the codebase with AddressSanitizer and run the \nfull test suite to execute strict memory leak checks.\n   - Weeks 11-12: Remove unused global macro definitions and static \nvariables. Update internal documentation and write the final GSoC report.\n\n(The above is for reference only. Personally, I always finish tasks \nfaster than planned 😉)\n\n\n~$ git checkout HEAD@{postGSoC}\n-------------------------------\nThis past month since joining the Git community has been the most \nenjoyable month of my programming journey. To quote a close friend of \nmine (who is applying for the Neovim GSoC project):\n\n   \"Only fools chase trends; open source is the game for the brave.\"\n\nThe words may be blunt, but the logic holds true. This statement surely\nresonates with me (and maybe many other GSoC contributors): our passion\nfor code and open-source drives us forward.\n\nEven if I didn't make the cut, so what? ~$ git reset --hard...\nJust kidding. The Git codebase is far too interesting to abandon now.\n\n-------------------------------------------------------------------------\nChanges since V3:\n\n  - The idea of introducing a new container is abandoned now. Therefore, \nIn approach section, the diagram and corresponding \ndescriptions/\"guidelines\" are modified;\n  - Emphasize on Meson and GitLab/GitHub which can be used for necessary \nsafety checks;\n  - Refined timeline section (community bonding).\n\n  ** I wrote \"Changes since v3\" as well in last patch (V3). Sorry for \nthe typo :( **\n\nRegards,\n\nYuchen\n"},{"id":"537277","messageId":"1d43d1d0-bf6b-4806-834e-89f545fab766@gmail.com","threadId":"65042","inReplyTo":"5e5f07ec-72ba-46ee-812c-d6773a4bdbe7@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-02-27T09:03:46Z","receivedAt":"2026-02-27T09:03:49Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Tian\n\nOn 26/02/2026 17:02, Tian Yuchen wrote:\n> [...]\n> Although the principle is simple, the scope of changes is extensive. The\n> following three-step approach can serve as a guiding principle for it:\n\nThere are four steps below\n\n>    1. Identify isolated environment variables currently residing in the\n>       global scope. Conduct a case-by-case analysis to map each variable\n>       to its most appropriate existing home (e.g., struct repo_settings\n>       for configuration values, or specific localized structs within\n>       struct repository).\n\nNote that as settings in struct repo_settings are lazily parsed, it is \nonly suitable for settings that are already lazily parsed. That means it \nis not a suitable home for any settings that are parsed at startup by \ngit_default_config().\n\n>    2. Instead of blindly passing struct repository *repo down into every\n>       single low-level library function, bubbling the dependency up is\n>       the true goal. External callers of the functions must be carefully\n>       audited to prevent regressions.\n\nWhere a function only needs one piece of information from struct \nrepository that sounds like a good strategy.\n\n>    3. Safely remove the old global variables and macro definitions. Make\n>       full use of Git's existing GitLab/GitHub CI and utilize local\n>       Meson builds with AddressSanitizer enabled to ensure that the new\n>       lifecycle introduces zero memory leaks.\n>    4. Many globals like `editor_program` are parsed once and remain\n>       available globally. New data flow might need to be designed to\n>       maintain the lazy-loading efficiency.\n\nAlthough `editor_program` is parsed once, that happens in \ngit_default_config() so it is not lazily loaded and making it lazily \nloaded would be a regression as if the config value is invalid we want \nto exit with an error early in the process, not just before we prompt \nthe user to edit a file.\n\nThanks\n\nPhillip\n\n"},{"id":"537293","messageId":"86cf5f3f-1459-4281-ae97-24f2d834e099@gmail.com","threadId":"65042","inReplyTo":"1d43d1d0-bf6b-4806-834e-89f545fab766@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-27T15:07:54Z","receivedAt":"2026-02-27T15:07:59Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi Phillip,\n\nWow, your reply is very detailed. Appreciate.\n\n> There are four steps below...\n\nYup, a typo.\n\n> Note that as settings in struct repo_settings are lazily parsed, it is \n> only suitable for settings that are already lazily parsed. That means it \n> is not a suitable home for any settings that are parsed at startup by \n> git_default_config().\n\nThis makes sense to me. So for variables in like 'git_default_config()', \ntheir startup parsing nature must be preserved. Will update the proposal \nto explicitly distinguish between these different lifecycles.\n\n\n> Where a function only needs one piece of information from struct \n> repository that sounds like a good strategy.\n\nIt's much better to pass just that value down rather than passing the \nentire 'struct repository', right?\n\n> Although `editor_program` is parsed once, that happens in \n> git_default_config() so it is not lazily loaded and making it lazily \n> loaded would be a regression as if the config value is invalid we want \n> to exit with an error early in the process, not just before we prompt \n> the user to edit a file.\n\nOh, I thought it was lazy-loaded. I completely overlooked the user \nexperience in terms of a delayed fatal config error also. Will double \ncheck the source code and rewrite this part.\n\nI'm delighted to see more people reviewing my proposal. I've truly \ngained valuable insights into Git's design philosophy. My sincere \ngratitude to you.\n\nRegards,\n\nYuchen\n\n"},{"id":"537305","messageId":"0a944142-7c51-4143-af00-2a5798ea68af@gmail.com","threadId":"65042","inReplyTo":"5e5f07ec-72ba-46ee-812c-d6773a4bdbe7@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-02-27T16:58:16Z","receivedAt":"2026-02-27T16:58:22Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi all,\n\nHere is the V5 patch.\n\nThanks Phillip Wood, for help and guidance.\n\n\nRefactoring in order to reduce Git's global state\n=================================================\n\nPERSONAL INFORMATION\n--------------------\nName: Tian Yuchen\nE-mail: a3205153416@gmail.com\nPhone number: +65 98740318\nTime-zone: UTC + 08:00\nGithub: https://github.com/malon7782\n\nEducation: NTU, Singapore\nYear: Year 1 semester 2\nDegree: Electrical and Electronic Engineering (EEE)\n\n\nPRE GSOC\n--------\nI have always held a deep passion for the open-source community. \nAlthough I wasn't a computer science major, I tinkered with open-source \nprojects long before college. I have solid hands-on experience in C \nprogramming and system-level debugging.\n\nI use Ubuntu 24.04 on a daily basis, so I am proficient in using the \nLinux command line and CLI tools.\n\nI have contributed to the Git community by sending patches. Since my \nfirst commit (17/1/2026), I have maintained a nearly daily contribution. \nHere is the list of contributions I have made:\n\n* [PATCH v1] t1005: modernize \"! test -f\" to \"test_path_is_missing\"\n\nhttps://lore.kernel.org/git/20260117062515.319664-1-a3205153416@gmail.com/\n   This patch is my microproject, the first contribution I made to the \ncodebase.\n   [Graduated to 'master']\n\n* [PATCH v2] t2203: avoid masking exit codes in git status\n\nhttps://lore.kernel.org/git/20260118043537.338769-1-a3205153416@gmail.com/#t\n\n* [PATCH v2] symlinks: use unsigned int for flags\n\nhttps://lore.kernel.org/git/20260120152219.398999-1-a3205153416@gmail.com/\n   [Will merge to 'next']\n\n* [PATCH v4] t/perf/p3400: speed up setup using fast-import\n\nhttps://lore.kernel.org/git/20260130170123.642344-1-a3205153416@gmail.com/\n   [Will merge to 'master']\n\n* Re: [PATCH] [RFC] attr: use local repository state in read_attr\n\nhttps://lore.kernel.org/git/cc2f400e-49c2-4de0-9c51-9a5c0294735e@gmail.com/\n   Code review. To verify the performance loss, I wrote a test script to\n   measure the time difference before and after the modification.\n\n* Re: Bug: git add :!x . exits with error when x is in .gitignore\n\nhttps://lore.kernel.org/git/1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com/\n   Code review. Pointed out logical error.\n\n* [PATCH v10] setup: allow cwd/.git to be a symlink to a directory\n\nhttps://lore.kernel.org/git/20260220164512.216901-1-a3205153416@gmail.com/\n   [Under review]\n   After over half a month of discussions, repeated refactoring, and code\n   reviews, I delved deep into setup.c. I gained insights into Git's \ndesign philosophy, and learned the art of striking a balance in \ndeveloper communication. It took me a large amount of time and effort to \nthoroughly understand every line of the code. I often found myself \nporing over the call chain of a single function well into the night.... \nBut I persevered until the end, and I believe my patience will see me \nthrough even larger projects.\n\n\nABOUT THE PROJECT\n-----------------\n\n-- Synopsis\n\nAs far as I know, the Git community is actively working towards \n'libification' - making Git's internal machinery reusable as a C \nlibrary. The extensive reliance on global state is a major roadblock to \nthis goal.\n\nMany core functions implicitly read environment variables and store them \nin global static variables. This can cause several issues:\n\n   1. Global variables prevent Git's core functions from being executed \nsafely in multi-threaded contexts. For example, When unexpected states \n(e.g., a permission denied error when probing a directory), they often \nrely on the global state to decide whether to call die(), which \ninternally calls exit(). It’s fine for a standalone CLI tool, but for a \nlinked C library used by a long-running multi-threaded server, a single \ndie() call will kill the entire host process. Structured status, instead \nof fatal exits, should be returned.\n\n   2. When Git is called multiple times within the same process, global \nstates can lead to memory leaks or incorrect behaviors.\n\n   3. Unit testing becomes difficult because the environment must be \nartificially manipulated before calling functions.\n\nTake a look at this example from environment.c:\n\n     206 const char *get_commit_output_encoding(void)\n     207 {\n     208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n     209 }\n\nIf Git is invoked as a C library by a multi-threaded server:\n- Thread A formats a commit for Repo A (using GBK);\n- Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThen they will race to read and overwrite the exact same global\n`git_commit_encoding` pointer, which is not what we expect. Therefore,\nwe have to refactor these environment variables by moving them from\nglobal scope into a well-defined and encapsulated context.\n\n\n-- Approach\n\nThe task at hand goes beyond simply repackaging the global variables \ninto the struct repository structure. Based on my recent experience \nrefactoring setup.c, I realized that libification requires careful \nmanagement of variable lifecycles and api boundaries:\n\n     [ Current ]\n     Core functions --------reads-------> Global variables (via getenv)\n                                          [Thread unsafe]\n\n     [ Target ]\n     Core functions ----passes context--> struct repository\n                                                 | owns\n                                                 v\n                                          struct repo_settings\n\n                    \t                 other domain-specific structs\n\nAlthough the principle is simple, the scope of changes is extensive. The \nfollowing insights can serve as a guiding principle for it:\n\n   1. Identify isolated environment variables currently residing in the\n      global scope. Conduct a case-by-case analysis to map each variable\n      to its most appropriate existing home based on their lifecycles:\n\n\tVariables that are only parsed when needed will be safely mapped\n\tto struct repo_settings.\n\n\tVariables parsed at startup (e.g., editor_program)\n\tmust not be moved to lazily parsed structs to ensure that\n\tinvalid configurations can trigger early failures before\n\texecution proceeds too far, which is also for the sake of user\n         experience.\n\n   2. Instead of blindly passing struct repository *repo down into every\n      single low-level library function, bubbling the dependency up is\n      the true goal. External callers of the functions must be carefully\n      audited to prevent regressions.\n\n   3. Safely remove the old global variables and macro definitions. Make\n      full use of Git's existing GitLab/GitHub CI and utilize local\n      Meson builds with AddressSanitizer enabled to ensure that the new\n      lifecycle introduces zero memory leaks.\n\n\nAdditionally, given the anticipated high volume of commits, we must \nensure each patch is independent and atomic, preventing any \nuser-untraceable or unexplainable bugs from occurring in the codebase at \nany state.\n\n\nAVAILABILITY\n------------\nFortunately, my summer vacation coincides with the GSoC work period.\nI will treat this project as my primary focus, dedicating a minimum of\n35 hours per week. If needed, I can work a 9-to-5 schedule.\n\nI will have a significant head start to draft RFC patches before the\nofficial coding period even begins. Having this buffer period allows me\nto go through the rigorous code review process within the Git community\nwith greater ease.\n\n\nTIMELINE & MILESTONES\n---------------------\nConsidering the differences between this project and other projects on \nthe idea list, rather than hoarding massive changes, I will submit \n3-to-5-patch series frequently to respect reviewers' time and maintain a \nsteady velocity.\n\nBelow is the tentative schedule I have prepared for myself:\n\n* Community Bonding (May 1 - May 25): Planning & RFC\n   - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n     prioritized list of subsystems with my mentor.\n   - May 8 - May 25: Categorize the targeted global variables and map out\n     their intended destinations (e.g., repo_settings). Draft and submit\n     the initial RFC patch series.\n\n* Phase 1 (May 26 - July 10): Foundation\n   - Weeks 1-2: Plumb the context pointer ('struct repository *repo') \nthrough call chains for simple variables (e.g., boolean flags or integer \nconfigs).\n   - Weeks 3-4: Audit and update external callers to use the new API.\n   - Weeks 5-6: Submit the first major refactoring patch series. Address\n     mailing list feedback and resolve merge conflicts. (Midterm Evaluation)\n\n* Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n   - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related \nglobals).\n   - Weeks 9-10: Compile the codebase with AddressSanitizer and run the \nfull test suite to execute strict memory leak checks.\n   - Weeks 11-12: Remove unused global macro definitions and static \nvariables. Update internal documentation and write the final GSoC report.\n\n(The above is for reference only. Personally, I always finish tasks \nfaster than planned 😉)\n\n\n~$ git checkout HEAD@{postGSoC}\n-------------------------------\nThis past month since joining the Git community has been the most \nenjoyable month of my programming journey. To quote a close friend of \nmine (who is applying for the Neovim GSoC project):\n\n   \"Only fools chase trends; open source is the game for the brave.\"\n\nThe words may be blunt, but the logic holds true. This statement surely\nresonates with me (and maybe many other GSoC contributors): our passion\nfor code and open-source drives us forward.\n\nEven if I didn't make the cut, so what? ~$ git reset --hard...\nJust kidding. The Git codebase is far too interesting to abandon now.\n\n-------------------------------------------------------------------------\nChanges since V4:\n\n  - “Treating variables or functions differently based on their \nlifecycle” has been added to the Approach section.\n\n  - Fixed a typo below the diagram.\n\nRegards,\n\nYuchen\n"},{"id":"537449","messageId":"eecd6531-a7b5-4f0e-8e4d-3807f47d1f9d@gmail.com","threadId":"65042","inReplyTo":"0a944142-7c51-4143-af00-2a5798ea68af@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-03-01T16:43:03Z","receivedAt":"2026-03-01T16:43:08Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Tian\n\nOn 27/02/2026 16:58, Tian Yuchen wrote:\n> \n> \n>    3. Unit testing becomes difficult because the environment must be \n> artificially manipulated before calling functions.\n> \n> Take a look at this example from environment.c:\n> \n>      206 const char *get_commit_output_encoding(void)\n>      207 {\n>      208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n>      209 }\n> \n> If Git is invoked as a C library by a multi-threaded server:\n> - Thread A formats a commit for Repo A (using GBK);\n> - Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThe encoding config is really a user preference that lets the user \ncompose commit messages in their preferred encoding while allowing git \nto store the message encoded as UTF-8. I'm struggling to see why two \nthreads would be using different encodings as it implies that the user \nis using different encodings in different repositories.\n\nBelow you say\n\n >      Variables parsed at startup (e.g., editor_program)\n >      must not be moved to lazily parsed structs to ensure that\n >      invalid configurations can trigger early failures before\n >      execution proceeds too far, which is also for the sake of user\n >          experience.\n\ni18n.commitEncoding is another such setting as it is currently eagerly \nparsed so I'm surprised to see it being converted to lazy parsing in \nhttps://lore.kernel.org/20260228190201.3684705-1-a3205153416@gmail.com\n\nI'm afraid that the suggestion on the project webpage is not very \nhelpful. Most config variables are unsuited to a conversion based on \nrepository_settings, it would be better to look at the approach \nimplemented in \nhttps://lore.kernel.org/48821a3848bef25c13038be8377ad73e7c17a924.1771258573.git.belkid98@gmail.com \nthat is discussed in https://lore.kernel.org/xmqqwm1vk83a.fsf@gitster.g\n\nThanks\n\nPhillip\n\n> Then they will race to read and overwrite the exact same global\n> `git_commit_encoding` pointer, which is not what we expect. Therefore,\n> we have to refactor these environment variables by moving them from\n> global scope into a well-defined and encapsulated context.\n> \n> \n> -- Approach\n> \n> The task at hand goes beyond simply repackaging the global variables \n> into the struct repository structure. Based on my recent experience \n> refactoring setup.c, I realized that libification requires careful \n> management of variable lifecycles and api boundaries:\n> \n>      [ Current ]\n>      Core functions --------reads-------> Global variables (via getenv)\n>                                           [Thread unsafe]\n> \n>      [ Target ]\n>      Core functions ----passes context--> struct repository\n>                                                  | owns\n>                                                  v\n>                                           struct repo_settings\n> \n>                                          other domain-specific structs\n> \n> Although the principle is simple, the scope of changes is extensive. The \n> following insights can serve as a guiding principle for it:\n> \n>    1. Identify isolated environment variables currently residing in the\n>       global scope. Conduct a case-by-case analysis to map each variable\n>       to its most appropriate existing home based on their lifecycles:\n> \n>      Variables that are only parsed when needed will be safely mapped\n>      to struct repo_settings.\n> \n>      Variables parsed at startup (e.g., editor_program)\n>      must not be moved to lazily parsed structs to ensure that\n>      invalid configurations can trigger early failures before\n>      execution proceeds too far, which is also for the sake of user\n>          experience.\n> \n>    2. Instead of blindly passing struct repository *repo down into every\n>       single low-level library function, bubbling the dependency up is\n>       the true goal. External callers of the functions must be carefully\n>       audited to prevent regressions.\n> \n>    3. Safely remove the old global variables and macro definitions. Make\n>       full use of Git's existing GitLab/GitHub CI and utilize local\n>       Meson builds with AddressSanitizer enabled to ensure that the new\n>       lifecycle introduces zero memory leaks.\n> \n> \n> Additionally, given the anticipated high volume of commits, we must \n> ensure each patch is independent and atomic, preventing any user- \n> untraceable or unexplainable bugs from occurring in the codebase at any \n> state.\n> \n> \n> AVAILABILITY\n> ------------\n> Fortunately, my summer vacation coincides with the GSoC work period.\n> I will treat this project as my primary focus, dedicating a minimum of\n> 35 hours per week. If needed, I can work a 9-to-5 schedule.\n> \n> I will have a significant head start to draft RFC patches before the\n> official coding period even begins. Having this buffer period allows me\n> to go through the rigorous code review process within the Git community\n> with greater ease.\n> \n> \n> TIMELINE & MILESTONES\n> ---------------------\n> Considering the differences between this project and other projects on \n> the idea list, rather than hoarding massive changes, I will submit 3- \n> to-5-patch series frequently to respect reviewers' time and maintain a \n> steady velocity.\n> \n> Below is the tentative schedule I have prepared for myself:\n> \n> * Community Bonding (May 1 - May 25): Planning & RFC\n>    - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n>      prioritized list of subsystems with my mentor.\n>    - May 8 - May 25: Categorize the targeted global variables and map out\n>      their intended destinations (e.g., repo_settings). Draft and submit\n>      the initial RFC patch series.\n> \n> * Phase 1 (May 26 - July 10): Foundation\n>    - Weeks 1-2: Plumb the context pointer ('struct repository *repo') \n> through call chains for simple variables (e.g., boolean flags or integer \n> configs).\n>    - Weeks 3-4: Audit and update external callers to use the new API.\n>    - Weeks 5-6: Submit the first major refactoring patch series. Address\n>      mailing list feedback and resolve merge conflicts. (Midterm \n> Evaluation)\n> \n> * Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n>    - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related \n> globals).\n>    - Weeks 9-10: Compile the codebase with AddressSanitizer and run the \n> full test suite to execute strict memory leak checks.\n>    - Weeks 11-12: Remove unused global macro definitions and static \n> variables. Update internal documentation and write the final GSoC report.\n> \n> (The above is for reference only. Personally, I always finish tasks \n> faster than planned 😉)\n> \n> \n> ~$ git checkout HEAD@{postGSoC}\n> -------------------------------\n> This past month since joining the Git community has been the most \n> enjoyable month of my programming journey. To quote a close friend of \n> mine (who is applying for the Neovim GSoC project):\n> \n>    \"Only fools chase trends; open source is the game for the brave.\"\n> \n> The words may be blunt, but the logic holds true. This statement surely\n> resonates with me (and maybe many other GSoC contributors): our passion\n> for code and open-source drives us forward.\n> \n> Even if I didn't make the cut, so what? ~$ git reset --hard...\n> Just kidding. The Git codebase is far too interesting to abandon now.\n> \n> -------------------------------------------------------------------------\n> Changes since V4:\n> \n>   - “Treating variables or functions differently based on their \n> lifecycle” has been added to the Approach section.\n> \n>   - Fixed a typo below the diagram.\n> \n> Regards,\n> \n> Yuchen\n> \n\n"},{"id":"537452","messageId":"7fa1f5c9-d1c1-4d81-a170-74a77468b923@gmail.com","threadId":"65042","inReplyTo":"eecd6531-a7b5-4f0e-8e4d-3807f47d1f9d@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-03-01T16:58:17Z","receivedAt":"2026-03-01T16:58:23Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi Phillip,\n\nThank you so much for taking the time to review both my patch and my \nGSoC proposal draft.\n\nYou are right on all points:\n\n1. I now agree that commit encoding being a user/environment preference \nrather than a repository-specific attribution. My example was indeed a \nflawed assumption.\n\n2. Thank you for catching the contradiction between my patch and my \nproposal's guiding principles. However, I changed it to lazy-loading not \nbecause I didn't follow the workflow I wrote, but because I thought the \noriginal eagerly parsing behavior was *incorrect*. But since I now \nunderstand point 1 above, this is no longer an issue to me anymore.\n\n3. I deeply appreciate you pointing out that the GSoC ideas page might \nbe misleading. I will study through the link you provide.\n\nThank you again for steering me in the right direction!\n\nRegards,\n\nYuchen\n"},{"id":"537587","messageId":"xmqqy0kayrtd.fsf@gitster.g","threadId":"65042","inReplyTo":"eecd6531-a7b5-4f0e-8e4d-3807f47d1f9d@gmail.com","subject":"Re: [GSoC][Draft Proposal v4] Refactoring in order to reduce Git's global state","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-02T19:06:22Z","receivedAt":"2026-03-02T19:06:26Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> i18n.commitEncoding is another such setting as it is currently eagerly \n> parsed so I'm surprised to see it being converted to lazy parsing in \n> https://lore.kernel.org/20260228190201.3684705-1-a3205153416@gmail.com\n>\n> I'm afraid that the suggestion on the project webpage is not very \n> helpful. Most config variables are unsuited to a conversion based on \n> repository_settings,...\n\nThanks for a dose of sanity here.  Very much appreciated.\n\n"},{"id":"537657","messageId":"f19c95fd-756e-4890-b718-10ccf09c31fa@gmail.com","threadId":"65042","inReplyTo":"0a944142-7c51-4143-af00-2a5798ea68af@gmail.com","subject":"[GSoC][Draft Proposal v6] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-03-03T12:11:35Z","receivedAt":"2026-03-03T12:11:40Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi all,\n\nHere is the V6 Draft. Looking forward to hearing your feedback (ゝ∀･)\n\nRefactoring in order to reduce Git's global state\n=================================================\n\nPERSONAL INFORMATION\n--------------------\nName: Tian Yuchen\nE-mail: a3205153416@gmail.com\nPhone number: +65 98740318\nTime-zone: UTC + 08:00\nGithub: https://github.com/malon7782\n\nEducation: NTU, Singapore\nYear: Year 1 semester 2\nDegree: Electrical and Electronic Engineering (EEE)\n\n\nPRE GSOC\n--------\nI have always held a deep passion for the open-source community. \nAlthough I'm not a computer science major, I tinkered with open-source \nprojects long before college. I have solid hands-on experience in C \nprogramming and system-level debugging.\n\nI use Ubuntu 24.04 on a daily basis, so I am proficient in using the \nLinux command line and CLI tools.\n\nI have contributed to the Git community by sending patches. Since my \nfirst commit (17/1/2026), I have maintained a nearly daily contribution. \nHere is the list of contributions I have made:\n\n* [PATCH v1] t1005: modernize \"! test -f\" to \"test_path_is_missing\"\n\nhttps://lore.kernel.org/git/20260117062515.319664-1-a3205153416@gmail.com/\n   This patch is my microproject, the first contribution I made to the \ncodebase.\n   [Graduated to 'master']\n\n* [PATCH v2] t2203: avoid masking exit codes in git status\n\nhttps://lore.kernel.org/git/20260118043537.338769-1-a3205153416@gmail.com/#t\n\n* [PATCH v2] symlinks: use unsigned int for flags\n\nhttps://lore.kernel.org/git/20260120152219.398999-1-a3205153416@gmail.com/\n   [Merged to 'next']\n\n* [PATCH v4] t/perf/p3400: speed up setup using fast-import\n\nhttps://lore.kernel.org/git/20260130170123.642344-1-a3205153416@gmail.com/\n   [Will merge to 'master']\n\n* Re: [PATCH] [RFC] attr: use local repository state in read_attr\n\nhttps://lore.kernel.org/git/cc2f400e-49c2-4de0-9c51-9a5c0294735e@gmail.com/\n   Code review. To verify the performance loss, I wrote a test script to\n   measure the time difference before and after the modification.\n\n* Re: Bug: git add :!x . exits with error when x is in .gitignore\n\nhttps://lore.kernel.org/git/1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com/\n   Code review. Pointed out logical error.\n\n* [PATCH v11] setup: allow cwd/.git to be a symlink to a directory\n\nhttps://lore.kernel.org/git/20260220164512.216901-1-a3205153416@gmail.com/\n   [Under review]\n   After over half a month of discussions, repeated refactoring, and code\n   reviews, I delved deep into setup.c. I gained insights into Git's \ndesign philosophy, and learned the art of striking a balance in \ndeveloper communication. It took me a large amount of time and effort to \nthoroughly understand every line of the code. I often found myself \nporing over the call chain of a single function well into the night.... \nBut I persevered until the end, and I believe my patience will see me \nthrough even larger projects.\n\n* [PATCH v4 0/3] move encoding configs to repo_config_values()\n\nhttps://lore.kernel.org/git/20260228190201.3684705-1-a3205153416@gmail.com/\n   [In progress]\n   A practice patch for working according to the workflow described in \nthis proposal.\n\n* Re: [PATCH 4/4] repo: add the field path.toplevel\n\nhttps://lore.kernel.org/git/e6e7e272-4aec-461e-aebd-33ec0a324770@gmail.com/\n   Code review. Question unreasonable designs.\n\n\n\nABOUT THE PROJECT\n-----------------\n\n-- Synopsis\n\nAs far as I know, the Git community is actively working towards \n'libification' - making Git's internal machinery reusable as a C \nlibrary. The extensive reliance on global state is a major roadblock to \nthis goal.\n\nMany core functions implicitly read environment variables and store them \nin global static variables. This can cause several issues:\n\n   1. When Git is called multiple times within the same process, global \nstates can lead to memory leaks or incorrect behaviors.\n\n   2. Unit testing becomes difficult because the environment must be \nartificially manipulated before calling functions.\n\n   3. Global variables prevent Git's core functions from being executed \nsafely in multi-threaded contexts. For example, When unexpected states \n(e.g., a permission denied error when probing a directory), they often \nrely on the global state to decide whether to call die(), which \ninternally calls exit(). It’s fine for a standalone CLI tool, but for a \nlinked C library used by a long-running multi-threaded server, a single \ndie() call will kill the entire host process. Structured status, instead \nof fatal exits, should be returned.\n\nTake a look at this example from environment.c:\n\n     206 const char *get_commit_output_encoding(void)\n     207 {\n     208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n     209 }\n\nIf Git is invoked as a C library by a multi-threaded server:\n- Thread A formats a commit for Repo A (using GBK);\n- Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThen they will race to read and overwrite the exact same global\n`git_commit_encoding` pointer, which is not what we expect. Therefore,\nwe have to refactor these environment variables by moving them from\nglobal scope into a well-defined and encapsulated context.\n\n\n-- Approach\n\nThe task at hand goes beyond simply repackaging the global variables \ninto the struct repository structure. Based on my recent experience \nrefactoring setup.c, I realized that libification requires careful \nmanagement of variable lifecycles and api boundaries:\n\n     [ Current ]\n     Core functions --------reads-------> Global variables (via getenv)\n                                          [Thread unsafe]\n\n     [ Target ]\n     Core functions ----passes context--> struct repository\n                                                 | owns\n                                                 v\n                                      struct repo_settings(lazy)\n\n\t\t  \t          struct repo_config_values (eager) [1]\n\n                                      other domain-specific structs\n\nAlthough the principle is simple, the scope of changes is extensive. The \nfollowing insights can serve as a guiding principle for it:\n\n   1. Identify isolated environment variables currently residing in the\n      global scope. Conduct a case-by-case analysis to map each variable\n      to its most appropriate existing home based on their lifecycles:\n\n     \tVariables that are only parsed when needed will be safely mapped\n\tto struct repo_settings.\n\n     \tVariables parsed at startup (e.g., editor_program) must not be\n\tmoved to lazily parsed structs to ensure that invalid\n\tconfigurations can trigger early failures before execution\n\tproceeds too far, which is also for the sake of user experience.\n\t(Phillip Wood points out that the struct repo_config_values()\n\tcan serve as a good home to these variables, though this\n\tapproach remains in its early stages and has not yet been fully\n\tconfirmed and implemented. [2])\n\n   2. Instead of blindly passing struct repository *repo down into every\n      single low-level library function, bubbling the dependency up is\n      the true goal. External callers of the functions must be carefully\n      audited to prevent regressions.\n\n   3. Safely remove the old global variables and macro definitions. Make\n      full use of Git's existing GitLab/GitHub CI and utilize local\n      Meson builds with AddressSanitizer enabled to ensure that the new\n      lifecycle introduces zero memory leaks. [3]\n\n\nAdditionally, given the anticipated high volume of commits, we must \nensure each patch is independent and atomic [4], preventing any \nuser-untraceable or unexplainable bugs from occurring in the codebase at \nany state.\n\n\nAVAILABILITY\n------------\nFortunately, my summer vacation perfectly coincides with the GSoC work \nperiod. I will treat this project as my primary focus, dedicating a \nminimum of 35 hours per week. If needed, I can work a 9-to-5 schedule.\n\nI will have a significant head start to draft RFC patches before the\nofficial coding period even begins. Having this buffer period allows me\nto go through the rigorous code review process within the Git community\nwith greater ease.\n\n\nTIMELINE & MILESTONES\n---------------------\nConsidering the differences between this project and other projects on \nthe idea list, rather than hoarding massive changes, I will submit \n3-to-5-patch series frequently to respect reviewers' time and maintain a \nsteady velocity.\n\nBelow is the tentative schedule I have prepared for myself:\n\n* Community Bonding (May 1 - May 25): Planning & RFC\n   - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n     prioritized list of subsystems with my mentor.\n   - May 8 - May 25: Categorize the targeted global variables and map out\n     their intended destinations (e.g., repo_settings vs \nrepo_config_values). Draft and submit\n     the initial RFC patch series.\n\n* Phase 1 (May 26 - July 10): Foundation\n   - Weeks 1-2: Plumb the context pointer ('struct repository *repo') \nthrough call chains for simple variables (e.g., boolean flags or integer \nconfigs).\n   - Weeks 3-4: Audit and update external callers to use the new API.\n   - Weeks 5-6: Submit the first major refactoring patch series. Address\n     mailing list feedback and resolve merge conflicts. (Midterm Evaluation)\n\n* Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n   - Weeks 7-8: Refactor higher-complexity variables (e.g., path-related \nglobals).\n   - Weeks 9-10: Compile the codebase with AddressSanitizer and run the \nfull test suite to execute strict memory leak checks.\n   - Weeks 11-12: Remove unused global macro definitions and static \nvariables. Update internal documentation and write the final GSoC report.\n\n(The above is for reference only. Personally, I always finish tasks \nfaster than planned 😉)\n\n\n~$ git checkout HEAD@{postGSoC}\n-------------------------------\nThis past month since joining the Git community has been the most \nenjoyable month of my programming journey. To quote a close friend of \nmine (who is applying for the Neovim GSoC project):\n\n   \"Only fools chase trends; open source is the game for the brave.\"\n\nThe words may be blunt, but the logic holds true. This statement surely\nresonates with me (and maybe many other GSoC contributors): our passion\nfor code and open-source drives us forward.\n\nEven if I didn't make the cut, so what? ~$ git reset --hard...\nJust kidding. The Git codebase is far too interesting to abandon now.\n\n\nREFERENCE\n-------------------------------\n[1]\n\nhttps://lore.kernel.org/all/48821a3848bef25c13038be8377ad73e7c17a924.1771258573.git.belkid98@gmail.com/\n\n[2]\n\nhttps://lore.kernel.org/git/CAP8UFD2Q7gctwzGOe+rbgdXZSbDbV0dmM-cx4qt_d8nKi88=HA@mail.gmail.com/T/#t\n\n[3]\n\nhttps://lore.kernel.org/all/CAOLa=ZR=2B7yH+vtyiAPcCyU17yd2GZwonaj=JRo1f+LzSCoTg@mail.gmail.com/\n\n[4]\n\nhttps://lore.kernel.org/all/xmqqy0kp7wai.fsf@gitster.g/\n\n\n\n\n\n-------------------------------------------------------------------------\nChanges since V5:\n\n  - Once again, the diagram and approach sections emphasize \ndistinguishing variables across different life cycles.\n\n  - Modified the --Synopsis section. (issues with global variables)\n\n  - Included recent contributions and updated progress.\n\n  - Reference links has been added at the end to clarify the source of \nmy viewpoint/plan.\n\nRegards,\n\nYuchen\n"},{"id":"538205","messageId":"a71b334d-95e1-4645-9877-f4a892f5a30a@gmail.com","threadId":"65042","inReplyTo":"f19c95fd-756e-4890-b718-10ccf09c31fa@gmail.com","subject":"Re: [GSoC][Draft Proposal v7] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-03-08T17:38:15Z","receivedAt":"2026-03-08T17:38:20Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"Hi all,\n\nHere is the V7 Draft. Looking forward to hearing your feedback (ゝ∀･)\n\nRefactoring in order to reduce Git's global state\n=================================================\n\nPERSONAL INFORMATION\n--------------------\nName: Tian Yuchen\nE-mail: a3205153416@gmail.com\nPhone number: +65 98740318\nTime-zone: UTC + 08:00\nGithub: https://github.com/malon7782\n\nEducation: NTU, Singapore\nYear: Year 1 semester 2\nDegree: Electrical and Electronic Engineering (EEE)\n\n\nPRE GSOC\n--------\nI have always held a deep passion for the open-source community. \nAlthough I'm not a computer science major, I tinkered with open-source \nprojects long before college. I have solid hands-on experience in C \nprogramming and system-level debugging.\n\nI use Ubuntu 24.04 on a daily basis, so I am proficient in using the \nLinux command line and CLI tools.\n\nI have contributed to the Git community by sending patches. Since my \nfirst commit (17/1/2026), I have maintained a nearly daily contribution. \nHere is the list of contributions I have made:\n\n* [PATCH v1] t1005: modernize \"! test -f\" to \"test_path_is_missing\"\n\nhttps://lore.kernel.org/git/20260117062515.319664-1-a3205153416@gmail.com/\n   This patch is my microproject, the first contribution I made to the \ncodebase.\n   [Graduated to 'master']\n\n* [PATCH v2] t2203: avoid masking exit codes in git status\n\nhttps://lore.kernel.org/git/20260118043537.338769-1-a3205153416@gmail.com/#t\n\n* [PATCH v2] symlinks: use unsigned int for flags\n\nhttps://lore.kernel.org/git/20260120152219.398999-1-a3205153416@gmail.com/\n   [Merged to 'next']\n\n* [PATCH v4] t/perf/p3400: speed up setup using fast-import\n\nhttps://lore.kernel.org/git/20260130170123.642344-1-a3205153416@gmail.com/\n   [Will merge to 'master']\n\n* Re: [PATCH] [RFC] attr: use local repository state in read_attr\n\nhttps://lore.kernel.org/git/cc2f400e-49c2-4de0-9c51-9a5c0294735e@gmail.com/\n   Code review. To verify the performance loss, I wrote a test script to\n   measure the time difference before and after the modification.\n\n* Re: Bug: git add :!x . exits with error when x is in .gitignore\n\nhttps://lore.kernel.org/git/1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com/\n   Code review. Pointed out logical error.\n\n* [PATCH v11] setup: allow cwd/.git to be a symlink to a directory\n\nhttps://lore.kernel.org/git/20260220164512.216901-1-a3205153416@gmail.com/\n   [Under review]\n   After over half a month of discussions, repeated refactoring, and code\n   reviews, I delved deep into setup.c. I gained insights into Git's \ndesign philosophy, and learned the art of striking a balance in \ndeveloper communication. It took me a large amount of time and effort to \nthoroughly understand every line of the code. Throughout this process, I \nmeticulously examined portions of the call chain in setup.c, the timing \nof die() usage, expected lookup/error handling behavior, external \ncallers, and ran several full CI tests. I managed to correct my initial \nassumptions and it taught me why die() cannot be casually bypassed in \nlibification without rigorous error propagation, as well as how to \nhandle cross-platform CI edge cases.\n\n* [PATCH v4 0/3] move encoding configs to repo_config_values()\n\nhttps://lore.kernel.org/git/20260228190201.3684705-1-a3205153416@gmail.com/\n   [In progress]\n   A practice patch for working according to the workflow described in \nthis proposal.\n\n* Re: [PATCH 4/4] repo: add the field path.toplevel\n\nhttps://lore.kernel.org/git/e6e7e272-4aec-461e-aebd-33ec0a324770@gmail.com/\n   Code review. Questioned unreasonable designs.\n\n* Re: [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting\n\nhttps://lore.kernel.org/git/24f40e5a-a5fd-49ec-86e7-921b44e4abd9@gmail.com/\n   Code review. Clarify lazy-loading and eager-loading. Pointed out \nproblems with the patch.\n\n* [PATCH] patch-ids: achieve const correctness in patch_id_neq()\n   https://lore.kernel.org/git/xmqqseaasuph.fsf@gitster.g/T/#t\n   [In progress]\n   Discuss and modify the items marked NEEDSWORK in patch-ids.c\n\nTo date, developing diverse patches across various domains has been a \nthoroughly enjoyable experience for me. I relish exploring different \nfields while maintaining the discipline to delve deeply into them. I \nnever settle for superficial patches.\n\n\nABOUT THE PROJECT\n-----------------\n\n-- Synopsis\n\nAs far as I know, the Git community is actively working towards \n'libification' (laid by Patrick Steinhardt's config/path refactoring, \nand Olamide Bello's recent introduction of repo_config_values) - making \nGit's internal machinery reusable as a C library. The extensive reliance \non global state is a major roadblock to this goal.\n\nMany core functions implicitly read environment variables and store them \nin global static variables. This can cause several issues:\n\n   1. When Git is called multiple times within the same process, global \nstates can lead to memory leaks or incorrect behaviors.\n\n   2. Unit testing becomes difficult because the environment must be \nartificially manipulated before calling functions.\n\n   3. Global variables prevent Git's core functions from being executed \nsafely in multi-threaded contexts. For example, when encountering \nunexpected states (e.g., a permission denied error when probing a \ndirectory), core functions often rely on the global state to decide \nwhether to call die(), which internally calls exit(). It’s fine for a \nstandalone CLI tool, but for a linked C library used by a long-running \nmulti-threaded server, a single die() call will kill the entire host \nprocess. Structured status, instead of fatal exits, should be returned.\n\nTake a look at this example from environment.c:\n\n     206 const char *get_commit_output_encoding(void)\n     207 {\n     208     return git_commit_encoding ? git_commit_encoding : \"UTF-8\";\n     209 }\n\nIf Git is invoked as a C library by a multi-threaded server:\n- Thread A formats a commit for Repo A (using GBK);\n- Thread B concurrently formats a commit for Repo B (using UTF-8);\n\nThen they will race to read and overwrite the exact same global\n`git_commit_encoding` pointer, which is not what we expect. Therefore,\nwe have to refactor these environment variables by moving them from\nglobal scope into a well-defined and encapsulated context.\n\n-- Trade-off?\n\nA naive approach to achieve this is blindly moving every global variable \ninto struct repository. For the previous encoding case, this approach \ndoes not seem entirely unfeasible. However, it is easy to cite another \nexample:\n\n“What if some variables are accessed before setup_git_directory() \nsuccessfully initializes the repo struct?”\n\nFor instance, early discovery flags like is_bare_repository_cfg are \nassigned during the .git directory probe, long before a struct \nrepository object can be safely instantiated. We create a \nchicken-and-egg initialization paradox if we force these early-startup \nvariables into repo_settings. How can a variable dictate the discovery \nof a repository if it lives inside the repository it is trying to discover?\n\nI believe the key point to note for this case is the boundary between \nRepository State and Process/Startup State. Encapsulating it within the \nearly-boot context might be a viable option... but more importantly, \nthis example illustrates that eliminating global variables is never a \nmatter of blindly “moving … to …” Instead, it requires careful, \nmultifaceted consideration and a thorough weighing of the trade-offs.\n\n\n-- Approach\n\nTherefore, the task at hand goes beyond simply repackaging the global \nvariables into the struct repository structure. Based on my recent \nexperience refactoring setup.c, I realized that libification requires \ncareful management of variable lifecycles and api boundaries:\n\n     [ Current ]\n     Core functions --------reads-------> Global variables (via getenv)\n                                          [Thread unsafe]\n\n     [ Target ]\n     Core functions ----passes context--> struct repository\n                                                 | owns\n                                                 v\n                                      struct repo_settings(lazy)\n\n                                 struct repo_config_values (eager) [1]\n\n                                      other domain-specific structs\n\nAlthough the principle is simple, the scope of changes is extensive. The \nfollowing insights can serve a guiding principles (but not the absolute \nrules to obey):\n\n   1. Identify isolated environment variables currently residing in the\n      global scope. Conduct a case-by-case analysis to map each variable\n      to its most appropriate existing home based on their lifecycles:\n\n         Variables that are only parsed when needed will be safely mapped\n     to struct repo_settings.\n\n         Variables parsed at startup (e.g., editor_program) must not be\n     moved to lazily parsed structs to ensure that invalid\n     configurations can trigger early failures before execution\n     proceeds too far, which is also for the sake of user experience.\n     (Phillip Wood points out that the struct repo_config_values\n     can serve as a good home to these variables, though this\n     approach remains in its early stages and has not yet been fully\n     confirmed and implemented. [2])\n\n   2. Instead of blindly passing struct repository *repo down into every\n      single low-level library function, bubbling the dependency up is\n      the true goal. External callers of the functions must be carefully\n      audited to prevent regressions.\n\n   3. Safely remove the old global variables and macro definitions. Make\n      full use of Git's existing GitLab/GitHub CI and utilize local\n      Meson builds with AddressSanitizer enabled to ensure that the new\n      lifecycle introduces zero memory leaks. [3]\n\n\nAdditionally, given the anticipated high volume of commits, we must \nensure each patch is independent and atomic [4], preventing any \nuser-untraceable or unexplainable bugs from occurring in the codebase at \nany state.\n\n\nAVAILABILITY\n------------\nFortunately, my summer vacation perfectly coincides with the GSoC work \nperiod. I will treat this project as my primary focus, dedicating a \nminimum of 35 hours per week. If needed, I can work a 9-to-5 schedule.\n\nI will have a significant head start to draft RFC patches before the\nofficial coding period even begins. Having this buffer period allows me\nto go through the rigorous code review process within the Git community\nwith greater ease.\n\nI've always kept up the habit of blogging (though previously it was \nmostly literary essays and musings). For this GSoC project, I'll provide \nregular progress updates (every week or every other week). I'll also \noccasionally share technical insights.\n\n\nTIMELINE & MILESTONES\n---------------------\nI believe that outlining a rigid, day-by-day schedule months in advance \nis unrealistic for a breathing codebase like Git. I will employ a \npipeline-driven workflow:\n\n   1. Small refactoring every 3-5 days, major refactoring every 2-3 \nweeks, alternating between the two.\n   2. After gathering sufficient, well-directed review suggestions, \nrevisit and modify the previous refactoring.\n   3. Ensure these patches do not depend on one another to prevent a \ndomino effect.\n\n\nBelow is the tentative schedule I have prepared for myself:\n\n* Community Bonding (May 1 - May 25): Planning & RFC\n   - May 1 - May 7: Wrap up university finals. Discuss and finalize the\n     prioritized list of subsystems with my mentor.\n   - May 8 - May 25: Categorize the targeted global variables and map out\n     their intended destinations (e.g., repo_settings vs \nrepo_config_values). Draft and submit\n     the initial RFC patch series.\n\n* Phase 1 (May 26 - July 10): Foundation\n\n   - Weeks 1-3: Target straightforward boolean flags and integer configs \nin environment.c (e.g., is_bare_repository_cfg). Plumb the context \npointer, adapt callers, and dispatch the first 2-3 patch series.\n   - Weeks 4-6: Process mailing list feedback and iterate (v2/v3). \nConcurrently begin migrating the next batch of variables. By the midterm \nevaluation, a steady rhythm of proposing, reviewing, and merging should \nbe established.\n\n* Phase 2 (July 11 - August 18): Complex Migration & Cleanup\n\n   - Weeks 7-8: Shift focus to higher-complexity variables and string \nconfigurations (e.g., editor_program, comment_line_str). Apply the \nrepo_config_values API where eager loading is strictly required.\n   - Weeks 9-10: Finalize the remaining targeted globals. Conduct a \nglobal audit for any dangling macro definitions (like \nUSE_THE_REPOSITORY_VARIABLE in fully refactored subsystems) and \neliminate them.\n   - Weeks 11-12: Update internal documentation \n(Documentation/technical/), ensure all patch series are either merged or \nin a stable state on the next branch, and write the final GSoC report.\n\n\n~$ git checkout HEAD@{postGSoC}\n-------------------------------\nI plan to stay active in the community long after the summer ends — \nreviewing related patches, mentoring future newcomers, and seeing the \nlibification effort through to the end.\n\nThis past month since joining the Git community has been the most \nenjoyable month of my programming journey. To quote a close friend of \nmine (who is applying for the Neovim GSoC project):\n\n   \"Only fools chase trends; open source is the game for the brave.\"\n\nThe words may be blunt, but the logic holds true. This statement surely \nresonates with me (and maybe many other GSoC contributors): our passion \nfor code and open-source drives us forward.\n\nEven if I didn't make the cut, so what? ~$ git reset --hard…\n\nJokes aside, diving into Git's codebase this past month has been \nimmensely rewarding. Win or lose, I'm here to stay and help.\n\n\nREFERENCE\n-------------------------------\n[1]\n\nhttps://lore.kernel.org/all/48821a3848bef25c13038be8377ad73e7c17a924.1771258573.git.belkid98@gmail.com/\n\n[2]\n\nhttps://lore.kernel.org/git/CAP8UFD2Q7gctwzGOe+rbgdXZSbDbV0dmM-cx4qt_d8nKi88=HA@mail.gmail.com/T/#t\n\n[3]\n\nhttps://lore.kernel.org/all/CAOLa=ZR=2B7yH+vtyiAPcCyU17yd2GZwonaj=JRo1f+LzSCoTg@mail.gmail.com/\n\n[4]\n\nhttps://lore.kernel.org/all/xmqqy0kp7wai.fsf@gitster.g/\n\n\n\n\n\n-------------------------------------------------------------------------\nChanges since V6:\n\n  - Update recent contributions. Rewrite descriptions for some of the \ncontributions.\n\n  - Add a section on trade-offs, discussing insights gained from \nchallenging scenarios I may encounter.\n\n  - Completely rewrite the schedule.\n\n  - Some expressions have been modified.\n\nRegards,\n\nYuchen\n"},{"id":"538984","messageId":"89938f03-0d4b-4852-8f00-edf06e315a16@gmail.com","threadId":"65042","inReplyTo":"a71b334d-95e1-4645-9877-f4a892f5a30a@gmail.com","subject":"Re: [GSoC][Draft Proposal v7] Refactoring in order to reduce Git's global state","fromName":"Tian Yuchen","fromEmail":"a3205153416@gmail.com","sentAt":"2026-03-14T17:57:06Z","receivedAt":"2026-03-14T17:57:12Z","isPatch":false,"sender":{"key":"cat@malon.dev","avatar":"https://avatars.githubusercontent.com/u/232002048?v=4"},"body":"I really hope someone can offer some advice!  After all, the deadline is \nfast approaching...\n\nBy the way, I was wondering how the mentors review proposals. Can we \nrevise and resubmit them multiple times? Is it better to submit the \nproposal as early as possible?\n\nI’ve made some final (and quite significant) adjustments. Compared to \nv7, it incorporates more personal insights and methodologies. Here’s a \nlink to the Google Doc.\n\nhttps://docs.google.com/document/d/1t2sznOvnPz-9tOzVMH--pLxzRqYSJCFzqVWBVfL_NP8/edit?tab=t.0#heading=h.c3c40ftj1ilv\n\nRegards,\n\nYuchen\n"}]}