Git Troubleshooting, Root‑Cause Analysis, and Community Contribution Guide
This article walks through a real Git‑induced failure, explains how to reproduce and diagnose the nested process loop, analyzes the underlying commit‑graph and alternates interactions, and then details step‑by‑step how to seek help and contribute a fix to the Git open‑source community.
About Git
Git is the world’s most widely used version control system and a mature, active open‑source project.
Created by Linus Torvalds in 2005, Git has been iterated for 17 years, and like any software, it still contains bugs.
“Bugs will happen, if they don’t happen in hardware, they will happen in software and if they don’t happen in your software they will happen in somebody else’s software.” – Linus Torvalds
Below we examine a Git‑related incident, show how to investigate it, and outline how to contribute a fix back to the Git community.
Git Issue Diagnosis
On‑site Reproduction
On 2022‑06‑08 the code‑platform service raised an alarm due to a flood of Git download requests. Examination of the affected servers revealed a chain of Git processes whose PIDs and PPIDs form a closed loop, creating a classic nested‑process cycle.
The loop generated a large number of Git processes, stressing the platform and exhausting local resources.
Because the condition can be reliably triggered, we obtained a copy of the problematic repository to begin analysis.
Problem Dissection
Key characteristics of the abnormal repository:
.git/objects/info contains a commit‑graph file.
The repository uses .git/objects/info/alternates to reference external objects.
Partial clone is enabled; traces are visible in .git/config : [remote "origin"] promisor = true partialclonefilter = blob:none
To avoid further impact on the platform, we reproduced the issue locally:
Extract the repository copy into a work directory.
Clone the remote repository as a bare repo: git clone --bare {url} remote.git
Redirect the remote URL of work to the local bare repo: git -C work remote set-url origin "$(pwd)remote.git"
We then executed the failing command to reproduce the issue.
Tracing can be enabled with GIT_TRACE=1 or GIT_TRACE2_EVENT="$(pwd)/event.trace" . Additional debugging may involve modifying Git source (e.g., adding trace_print ) or using LLDB/GDB.
The investigation uncovered a terrifying infinite‑fetch loop:
git fetch
-> do_fetch_pack_v2()
-> deref_without_lazy_fetch()
-> lookup_commit_in_graph()
-> repo_has_object_file()
-> promisor_remote_get_direct()
-> fetch_objects()
-> git fetch (😊, we are back at the start of the cycle)Root‑Cause Analysis
The loop originates from the following chain:
Partial clone leaves some objects missing locally, triggering lazy‑fetch.
During lazy‑fetch, deref_without_lazy_fetch() first consults the commit‑graph for acceleration.
lookup_commit_in_graph() calls repo_has_object_file() , which may cause another lazy‑fetch and thus another git fetch .
The new git fetch again hits the commit‑graph, repeating steps 2‑3.
The key problem is that the commit‑graph references objects that are absent in the local object store because the repository relies on objects/info/alternates to import external objects. After a git gc (or automatic GC) the unreachable object B is pruned from the shared repository, leaving the commit‑graph entry dangling. Any subsequent lazy‑fetch therefore re‑enters the loop, spawning many Git processes.
Hypothesis Verification
Using objects/info/alternates introduces an external shared repository to reduce local storage, while the commit‑graph speeds up commit lookup. When GC removes an unreachable object that still appears in the commit‑graph, lazy‑fetch of that missing object triggers the infinite loop.
Because the misuse of alternates and commit‑graph is hard to prevent for end users, we decided to seek assistance from the Git community.
Seeking Help from the Git Community
We set out to engage the community.
Entry Points
Three main ways to get help:
[email protected] – the primary mailing list for code review, announcements, and design discussions.
[email protected] – a newcomer‑friendly list for asking questions and receiving guidance.
#git-devel on Libera Chat – an IRC channel for real‑time discussion with contributors.
Preparing a Mail
When using the mailing list, send plain‑text emails (e.g., Gmail’s “Plain text mode”) or use git send-email . Include an In-Reply-To header so the thread stays organized.
git send-email \
--in-reply-to={Message-ID} \
[email protected] \
[email protected] \
--subject='Re: [PATCH v2 0/1] scalar: move to the top-level, test, CI and "install" support' \
/path/to/YOUR_REPLYLearning Resources
Before submitting a patch, read the following Git documentation:
Submitting Patches – guidelines for creating and sending patches.
Coding Guidelines – strict style rules used by the Git project.
Test Framework – the Sharness‑based test suite (see t/README ).
Submitting Your Fix
Once the patch passes CI, send it to the mailing list following the guidelines, and your contribution will become part of Git’s evolution.
Conclusion
We started from a Git‑induced failure, traced the root cause, reproduced the issue, and then outlined how to seek help and contribute a fix to the Git open‑source project.
Since its inception in 2005, Git’s success is driven by widespread adoption and a vibrant community of contributors; discovering problems and improving the tool is a rewarding experience for any developer.
ByteDance Web Infra
ByteDance Web Infra team, focused on delivering excellent technical solutions, building an open tech ecosystem, and advancing front-end technology within the company and the industry | The best way to predict the future is to create it
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.