[KongchangAI]
· 1 min read· 844 words

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

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, run git config --global core.excludesFile to 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_global or ~/.config/git/ignore, while Windows may use %USERPROFILE%\.gitignore_global. Worth noting: ~/.config/git/ignore is Git 2.x's default lookup path and takes effect even without explicitly setting core.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:

FileScopeCommittedTypical Use
.gitignoreSingle project, team-sharedYesBuild artifacts, dependencies, logs
~/.gitignore_globalAll projects on your machineNoEditor/OS artifacts
.git/info/excludeSingle project, personal onlyNoPersonal 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 .gitignore files in any subdirectory, where rules apply only to that directory and its descendants. This directory-level .gitignore is 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 .gitignore rules 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.

#Git ignore#core.excludesFile#.git/info/exclude#global gitignore#gitignore best practices#Git configuration
Share:

Related articles