What .gitignore is for
A .gitignore file tells Git which files to leave untracked. Without one, git status quickly fills with noise — dependency folders, compiled output, editor settings, OS metadata — and it becomes dangerously easy to commit a secret or a 200 MB build artefact by accident. A good .gitignore, added at the very first commit, keeps your repository lean and your history clean.
The .gitignore Generator assembles one for you by combining vetted templates, but knowing how the patterns work lets you customise with confidence.
How pattern matching works
Each non-comment line in .gitignore is a pattern. Git compares every untracked path against these patterns and ignores the matches. The syntax is small but expressive:
folder
node_modules/
wildcard
*.log
root-only
/dist
negation
!keep.log
- A trailing slash (
build/) matches a directory and everything inside it. - An asterisk (
*.log) matches any sequence of characters except a slash, so it coverserror.loganddebug.logbut notlogs/error.log. - A leading slash (
/dist) anchors the pattern to the directory containing the.gitignore, so only the top-leveldistis ignored, notsrc/dist. - A leading
!(!important.log) negates a previous match, re-including a file that an earlier pattern excluded. - Lines starting with
#are comments and are ignored by Git.
Precedence and ordering
Order matters when negation is involved. Git evaluates patterns top to bottom, and the last matching pattern wins. To ignore every log file except one, you must list the broad rule first and the exception after:
*.log
!keep.log
Reverse those two lines and keep.log gets ignored along with the rest. There’s one important limitation: you cannot re-include a file if its parent directory is ignored. If you’ve ignored logs/, a later !logs/keep.log won’t work — you’d need to ignore the contents (logs/*) rather than the folder itself.
The most common gotcha: already-tracked files
The single most frequent confusion is adding a file to .gitignore and finding Git still tracks it. The rule is simple but easy to forget: .gitignore only affects untracked files. Once a file is in the index, ignoring it has no effect until you remove it from tracking:
git rm --cached secrets.env
git commit -m "Stop tracking secrets.env"
After that commit, the ignore rule applies and the file stays out of future commits while remaining on your disk. This matters most for secrets — if you’ve already committed an API key, removing it from tracking is not enough, because it lives in your history. Rotate the key and consider scrubbing the history.
Where to put the file
Place your primary .gitignore in the repository root, beside the .git directory. Its rules apply to the whole project. You can add extra .gitignore files in subdirectories for localised rules, and deeper files take precedence over shallower ones. For ignores that are personal to your machine and shouldn’t be shared — your editor’s scratch files, say — use a global gitignore configured with git config --global core.excludesfile, or the untracked .git/info/exclude file.
Which templates to combine
A real project usually needs several templates layered together. A typical full-stack web app might combine:
- A language base — Node, Python, Go, or Rust — to ignore dependency folders and build output.
- A framework layer — React or Next.js — for framework-specific caches like
.next/. - Operating systems — macOS and Windows — so
.DS_StoreandThumbs.dbnever reach the repo, regardless of who clones it. - Editors — JetBrains or VS Code — to exclude IDE settings while optionally keeping shared config.
The .gitignore Generator lets you tick all of these at once and removes the duplicate patterns that overlapping templates inevitably share, so node_modules/ appears exactly once even if three templates list it.
Keeping secrets out
Secrets deserve special attention. Environment files (.env, .env.local) almost always belong in .gitignore, and committing them is one of the most common ways credentials leak. If you work with .env files regularly, the Env File Parser and its guide explain how to handle them safely. The golden rule: ignore the real .env, commit a .env.example with blank values instead.
Ignoring versus tracking empty folders
Git tracks files, not directories, which produces a small but common surprise: an empty folder you want to keep — logs/ or tmp/, say — simply won’t appear in the repository at all. The conventional fix is to add a placeholder file such as .gitkeep inside it and then ignore the folder’s contents while keeping the placeholder. A pattern like logs/* paired with !logs/.gitkeep ignores everything generated in the folder but preserves its existence in the repo. It’s a neat illustration of how negation and directory rules interact in practice.
Global ignores for personal noise
Not every ignore rule belongs in the shared project file. Your editor’s swap files, your operating system’s metadata, and tooling specific to your own machine are personal — forcing them into the project .gitignore clutters it for everyone else. Git supports a global ignore file for exactly this. Point Git at one with git config --global core.excludesfile ~/.gitignore_global, list your personal patterns there, and they apply across every repository you work on without touching any project’s committed rules. This keeps the project .gitignore focused on what the project needs, while your individual quirks stay on your machine. It’s a small habit that scales well across teams, because nobody has to argue about whether .idea/ belongs in a shared file.
Best-practice checklist
- Add
.gitignorebefore your first commit, not after files have been tracked. - Combine a language template with your OS and editor templates so the repo is clean for every contributor.
- Always ignore environment and secret files; commit an example file in their place.
- Commit the
.gitignoreitself so the whole team shares the rules. - Use a global gitignore for personal, machine-specific noise.
Wrapping up
.gitignore is a small file with outsized impact on repository hygiene. Its pattern syntax is compact, precedence is last-match-wins, and the one rule everyone forgets is that it only governs untracked files. Start every project by generating a combined, de-duplicated file with the .gitignore Generator, commit it first, and your history stays clean from day one.