Skip to main content

Git Ignore Engineering Guide

Managing Untracked Files Across Project, Local, and Global Scopes

Git provides three levels of ignore configuration to control which files are excluded from version control. Understanding when and where to use each level is essential for clean repositories and efficient team workflows.

Ignore Levels Overview

LevelFile / ConfigScopeShared?Use Case
Project.gitignoreRepository-wideYes (committed)Build artifacts, dependencies, IDE configs
Local.git/info/excludeSingle local repoNoPersonal editor files, local scripts
Globalcore.excludesFileAll repos for a userNoOS files (.DS_Store), editor backups

Project-Level: .gitignore

The .gitignore file is committed to the repository and shared across all collaborators. It defines ignore rules that apply to everyone working on the project.

Placement and Scope

  • A .gitignore file applies to its directory and all subdirectories recursively.
  • Multiple .gitignore files can exist at different levels of the tree.
  • Rules in a subdirectory's .gitignore take precedence over parent directory rules.

Pattern Syntax

PatternMeaningExample
*.logMatch all .log files in this directory and subdirectoriesdebug.log, error.log
build/Match the build directory and all contentsbuild/output.js
tempMatch any file or directory named temp anywheretemp/, src/temp
/tempMatch only temp at the root (leading slash anchors to .gitignore location)temp/ but not src/temp
**/logsMatch logs at any depthlogs/, a/b/logs/
**/logs/**Match everything inside any logs directorya/b/logs/x.txt
!important.logNegation: do NOT ignore this file (overrides previous rules)Re-include a specific file
doc/*.txtMatch .txt files directly in doc/ (no subdirectories)doc/notes.txt
doc/**/*.txtMatch .txt files in doc/ and all subdirectoriesdoc/a/b/notes.txt

Negation Rules

Use ! to re-include a file previously ignored by a broader rule:

# Ignore all .log files
*.log

# Except important.log
!important.log
caution

Negation only works if the parent directory is not itself ignored. If logs/ is ignored, !logs/important.log will not work — Git never looks inside ignored directories.

Common Project Patterns

# Dependencies
node_modules/
vendor/
.pnp/
.pnp.js

# Build output
dist/
build/
out/
*.o
*.pyc

# Environment and secrets
.env
.env.*
!.env.example
*.pem
*.key

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Python
__pycache__/
*.pyc
.pytest_cache/
.mypy_cache/

# Docusaurus / Node.js
.docusaurus/
.cache/

Local-Level: .git/info/exclude

The .git/info/exclude file lives inside the .git directory of a specific repository. It functions identically to .gitignore but is never committed or shared.

When to Use

  • Personal IDE configuration files that shouldn't be in the project's .gitignore
  • Local helper scripts or scratch files
  • Temporary files specific to your workflow
  • Files that are relevant to the project but not to other team members

Location

<repo-root>/.git/info/exclude

Example

# Personal scratch files
scratch.md
notes/

# Local editor config not shared with team
.local-editor-settings.json

# OS-specific files you don't want to pollute git status
.DS_Store
tip

Use .git/info/exclude when a file is project-specific but shouldn't force an ignore rule on the entire team. This keeps .gitignore clean and focused on universally relevant patterns.


Global-Level: core.excludesFile

Global ignores apply to all repositories on your machine. Configure them once and never worry about OS or editor clutter files again.

Setup

# 1. Create a global ignore file
touch ~/.gitignore_global

# 2. Tell Git to use it
git config --global core.excludesFile ~/.gitignore_global
# macOS
.DS_Store
.AppleDouble
.LSOverride
._*

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini

# Linux
*~
.directory

# Editor files
*.swp
*.swo
*~
.vscode/settings.json
.idea/workspace.xml

# Diff and merge tool backups
*.orig
*.rej
*.merge-file-backup

# Python
__pycache__/
*.pyc

# Node.js (if you work on many JS projects)
node_modules/

Verify Configuration

# Check the current global excludesFile path
git config --global core.excludesFile

# View all ignore-related config
git config --global --get-regexp ignore

Precedence and Evaluation Order

Git evaluates ignore rules in the following order (later rules override earlier ones):

  1. Command-line flagsgit add -f <file> forces tracking regardless of any ignore rule.
  2. .gitignore rules — Read from the file in the current directory, then parent directories up to the root. Closer files take precedence.
  3. .git/info/exclude — Local repository exclude file.
  4. core.excludesFile — Global ignore file.
info

Within a single .gitignore file, the last matching rule wins. A negation !pattern placed after an ignore pattern will re-include matching files.


Tracked Files Are Never Ignored

A critical rule: Git does not ignore files that are already tracked. If a file has been committed, adding it to .gitignore will have no effect.

Removing a Tracked File from the Index

# Remove from Git index but keep on disk
git rm --cached <file>

# Remove a directory recursively
git rm --cached -r <directory>

# Commit the change
git commit -m "chore: stop tracking <file>"

After git rm --cached, the file becomes untracked and the .gitignore rules will apply to it.


Debugging Ignore Rules

Check Why a File Is Ignored

git check-ignore -v <file>

Output format:

.gitignore:3:*.log debug.log

This shows: the file .gitignore at line 3, the rule *.log, matched the file debug.log.

Check Multiple Files

git check-ignore -v *.log *.tmp

Find All Ignored Files

# List all ignored files in the working tree
git status --ignored

# List with details
git ls-files --others --ignored --exclude-standard

Best Practices

PracticeRationale
Commit .gitignore earlyPrevents accidental commits of build artifacts or secrets.
Keep it specificUse explicit patterns over broad wildcards to avoid surprises.
Use .git/info/exclude for personal filesKeeps shared .gitignore clean.
Set up global ignores onceEliminate OS and editor clutter across all repos.
Add comments in .gitignoreGroup rules by purpose with blank-line-separated sections.
Never ignore with .gitignore what belongs in .git/info/excludePersonal workflow files should not be enforced on the team.
Use git check-ignore -v for debuggingQuickly identify which rule is ignoring a file.