Two Git Ignore Files You've Been Overlooking: Global and Local Exclude Configuration

Git has three ignore layers — using them correctly keeps .gitignore focused and clutter-free.
Most developers know only the project-level `.gitignore`, but Git actually provides three ignore layers. The global ignore file (configured via `core.excludesFile`) applies to all repositories on your machine and is ideal for editor caches and OS artifacts. `.git/info/exclude` is never committed and only affects the current repo for the current user, making it perfect for personal debug scripts or local configs. Two questions guide where a rule belongs: Is it useful to others? Does it apply across all projects? Layering rules correctly keeps the shared `.gitignore` lean and reduces noise from personal environment differences.
You Probably Only Know One .gitignore
Almost every developer who has used Git is familiar with the .gitignore file in the project root. It gets committed alongside the code, shared across the team, and keeps compiled artifacts, dependency directories, and log files out of version control.
But that's only part of Git's ignore mechanism. Beyond the project-level .gitignore, Git offers two lesser-known ignore files that each solve a different problem. Understanding how all three work together can keep your repositories cleaner and prevent you from stuffing personal preferences into shared team rules.
Global Ignores: core.excludesFile
The first overlooked mechanism is the global ignore file. It doesn't belong to any specific repository — it applies to every Git project on your machine.
Setting it up is straightforward:
git config --global core.excludesFile ~/.gitignore_global
Then add your rules to ~/.gitignore_global. This file is the right place for artifacts that are personal to your environment and unrelated to the project, such as:
- macOS's
.DS_Store - Editor cache directories like
.idea/or.vscode/ - Vim swap files
*.swp - Various temporary files
What these all have in common is that they're generated by your operating system or editor, not the project itself. Dropping them into a project's .gitignore isn't really appropriate — your teammates might use completely different editors, and adding IDE-specific ignore rules pollutes a shared file. The global ignore file solves this awkwardness cleanly.
If you've never set
core.excludesFile, rungit config --global core.excludesFileto check the current value — an empty result means it's not configured. Some Git clients (like GitHub Desktop) automatically create a global ignore file on first install, at paths that vary by OS: macOS/Linux typically use~/.gitignore_globalor~/.config/git/ignore, while Windows may use%USERPROFILE%\.gitignore_global. Worth noting:~/.config/git/ignoreis Git 2.x's default lookup path and takes effect even without explicitly settingcore.excludesFile, which means you might already have an active global ignore file without realizing it.
Per-Repository Private Ignores: .git/info/exclude
The second hidden mechanism is the .git/info/exclude file inside each repository. Its syntax is identical to .gitignore, but it's never committed, since the .git directory itself isn't under version control.
It sits between the project level and the global level: rules apply only to this one repository and only for you. Good use cases include:
- Debug scripts or notes you've temporarily generated inside the project
- Local config files that only you use
- Temporary exclusions you don't want to commit and don't want to push into the team's
.gitignore
In short, when you want to ignore a file but feel like "this is just a personal need and shouldn't affect anyone else," .git/info/exclude is exactly the right place for it.
How the Three Layers Divide Responsibility
Looking at all three files together, Git's ignore system forms a clear three-layer structure:
| File | Scope | Committed | Typical Use |
|---|---|---|---|
.gitignore | Single project, team-shared | Yes | Build artifacts, dependencies, logs |
~/.gitignore_global | All projects on your machine | No | Editor/OS artifacts |
.git/info/exclude | Single project, personal only | No | Personal temporary files |
To decide where a rule belongs, think along two dimensions: Is this rule useful to others? (determines shared vs. private) and Does this rule apply across all projects? (determines global vs. local).
- Useful to everyone and part of the project →
.gitignore - Only useful to you and applies across all projects → global ignore
- Only useful to you and specific to the current project → local exclude
Beyond these three static files, Git supports a fourth ignore mechanism: placing
.gitignorefiles in any subdirectory, where rules apply only to that directory and its descendants. This directory-level.gitignoreis common in monorepos or multi-module projects, where each submodule maintains its own ignore rules independently. When matching, Git walks up from the file's location, merging all.gitignorerules it finds, with closer files taking precedence. Strictly speaking, Git's ignore system is "multi-level" rather than a strict "three-layer" model — but for most single-repository projects, understanding the project, global, and private layers is more than enough.
Why This Small Detail Is Worth Caring About
This topic sparked considerable discussion on Hacker News, with one recurring observation: adding personal editor configs to a project's .gitignore is a common but inelegant practice. It causes the shared file to gradually bloat with fragments for every editor and operating system under the sun.
Using global ignores and local excludes appropriately lets the project's .gitignore return to its proper role — describing only the ignore rules that are genuinely relevant to the project, staying concise and readable. This matters especially for open-source projects, where contributors come from wildly different development environments.
Developing the habit of layering rules in the right place won't give you an immediate performance boost, but over time it significantly reduces "configuration noise" in your repositories and cuts down on pointless churn caused by individual environment differences. It's exactly the kind of thing you can't un-know once you learn it.
Related articles

Uber Deploys ChatGPT Work Company-Wide: AI in the Workplace Enters the Scaled Implementation Phase
Uber deploys ChatGPT Work to 30,000+ employees, extending it from engineering to all roles. We analyze its expert-engineer pairing, end-to-end automation, and questions of AI control and power concentration—insights for scaling AI in the workplace.

Shift at Midnight Hands-On: When "ID Verification" Becomes Alien Hunting
Shift at Midnight blends ID verification with horror survival in a four-player co-op game. We break down its inspection mechanics and chaotic humor.

Zelensky Recounts the Outbreak of War: I Need Ammunition, Not a Ride
Zelensky recalls the first day of war in a YouTube interview: farewell to family, rejecting Biden's evacuation offer with "I need ammunition, not a ride," and how Bucha shaped his stance on compromise and peace talks.