aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

gitignore Guide: Excluding Files and Using Templates

A .gitignore file tells Git which files it should ignore, and good gitignore usage keeps your repository from bloating with build output, secret keys and editor leftovers. Once files like node_modules/, vendor/, .env or .DS_Store land in version history, your repo grows needlessly and one day you might accidentally publish someone's password. This article walks through the right way to exclude files, the pattern syntax, and the mistakes people make most often.

One rule up front: .gitignore only affects files that are not yet tracked. Adding a file to the ignore list after you've committed it does not remove it automatically — this is the single most common point of confusion, and I gave it its own section below.

Where does .gitignore go?

In most projects a single .gitignore lives in the repository root and is itself committed, so the whole team shares the same rules. But Git supports several layers:

  • Root .gitignore — shared rules for the entire project; included in version control.
  • Subdirectory .gitignore — an extra file placed in any folder applies only to that folder and below. Paths are relative to that directory.
  • .git/info/exclude — rules for your machine only; never committed or shared.
  • Global gitignore — personal rules applied to all your repositories (see below).

Deeper files, read later, can override the ones above. So a .gitignore in a subfolder can re-include a rule that the root one excluded, using a negation.

Pattern syntax

Each line is a pattern. Blank lines are ignored, and lines starting with # are comments. The basics:

# Comment line
*.log              # all .log files (in any directory)
build/             # a trailing / matches directories only
/config.local      # a leading / anchors the pattern to the repo root
temp?.txt          # ? matches a single character
cache[0-9].dat     # square brackets are a character range
!important.log      # ! negation: track this file anyway

Key distinctions:

  • * matches anything except a slash (/); ** crosses directory boundaries. For example logs/**/*.log catches .log files at any depth under logs.
  • A leading / anchors the pattern to the repo root: /build excludes only the build folder at the root, not build folders in subdirectories.
  • A trailing / targets directories only: build/ won't exclude a file of the same name.
  • ! re-includes a file excluded by an earlier rule — but if the file's parent folder is fully ignored, negation won't help, because Git never looks inside that folder.

A typical .gitignore example

In a Laravel + Node project, the root .gitignore looks roughly like this:

# Dependencies
/node_modules
/vendor

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

# Build output
/public/build
/dist

# Logs and temporary files
*.log
/storage/*.key

# Editor and OS
.DS_Store
.idea/
.vscode/
Thumbs.db

Note: .env.* excludes every environment file, while the !.env.example line deliberately keeps the example template tracked — new developers use it to fill in their own .env.

Excluding a file that is already tracked

Suppose you forgot to ignore node_modules/ at the start and committed it. Adding it to .gitignore now isn't enough; you have to remove the files from Git's tracking. The fix is to drop them from the index without deleting them from disk:

git rm -r --cached node_modules
git commit -m "chore: stop tracking node_modules"

The --cached flag is crucial: the files stay in your working directory and only leave Git's index. After this commit the .gitignore rule kicks in and the files are never re-added. For a single file, git rm --cached file is enough.

Global gitignore: silence personal leftovers everywhere

Files like .DS_Store, .idea/ or *.swp are specific to your OS or editor; adding them to every project's .gitignore is unfair to your teammates. The right approach is a global gitignore:

git config --global core.excludesFile ~/.gitignore_global

Then you write your personal patterns into ~/.gitignore_global. Those rules apply only on your machine, across all your repositories, without polluting the project file.

Ready-made templates and debugging

You don't need to write every language from scratch. GitHub's official github/gitignore repository hosts ready templates for hundreds of languages and tools, while gitignore.io generates a combined file based on the technologies you pick. Use them as a starting point, then trim to fit your project.

If you want to know why a file is being ignored, don't guess — ask Git:

git check-ignore -v dist/app.js

This command shows which line of which .gitignore excluded the file. If you do need to add an ignored file, you can force it with git add -f file.

Frequently Asked Questions

Why is a file I added to .gitignore still being committed?

Most likely the file is already tracked. .gitignore only affects untracked files. Remove it from the index with git rm --cached file, then commit; the rule applies after that.

How do I include an empty folder in the repo?

Git doesn't track empty directories. The convention is to drop an empty file named .gitkeep inside the folder (it's not an official Git feature, just a convention) and commit that file so the folder is preserved.

I accidentally published a .env file — what should I do?

First untrack the file with git rm --cached .env and add it to .gitignore. But remember it remains in past commits: if it was truly secret, rotate every password and token inside it immediately — cleaning history alone is not enough assurance.

Keeping your repositories clean is a small but lasting win. If you'd like to work through your Git setup, deploy flow, or starting a project correctly from day one, get in touch with me.

Bu kategorideki tüm yazılar →

Devamı için