Programming and IT
The .gitignore file
Every project has files that do not belong in the repository — caches, build folders, editor settings, local passwords. You keep the list of such files in .gitignore, and Git stops offering to add them.
In this article
Why you need it#
Without a list of exclusions, git status turns into a junk pile: hundreds of
cache files hang next to your edits, and it is easy to miss what matters among
them. Worse, a file with passwords or a key added by accident gets into history and
goes to the server along with the commit.
.gitignore is an ordinary text file that lives in the repository and is
committed itself: the rules should be the same for everyone who works on the
project. It only affects files Git is not tracking yet. That is the main source of
confusion, covered below.
Pattern syntax#
One line, one rule. Blank lines are skipped, and a line starting with a hash is a comment.
| Pattern | What it matches |
|---|---|
secrets.txt |
a file with that name in any folder of the repository |
*.log |
any file with the log extension |
build/ |
the build folder and everything inside it, at any level |
/build |
only build in the same folder as this .gitignore |
docs/*.pdf |
pdf files directly in docs, but not in its subfolders |
docs/**/*.pdf |
pdf files in docs and all of its subfolders |
*.py[cod] |
.pyc, .pyo and .pyd files |
!example.log |
an exception to the previous rule: do not ignore this file |
The rules are simple, but two points are worth remembering. A slash inside a
pattern anchors it to the folder of the .gitignore file; without a slash the
pattern matches at any depth. And the exclamation mark does not work if the whole
folder is ignored: Git does not look inside an excluded folder and cannot see that
something there is allowed — in that case you ignore the contents (logs/*) and
then add the exception.
A ready-made example#
A file in the root of a Python project:
__pycache__/
*.py[cod]
.venv/
venv/
.idea/
.vscode/
.DS_Store
/dist/
/build/
*.egg-info/
.env
*.local.yml
*.log
!example.log
The first two blocks are what the language itself creates. Then editor settings and
operating-system clutter. Then build output — with a leading slash so you do not
accidentally hide a build folder inside your sources. And at the end, local
settings with secrets, plus logs, with one sample file deliberately kept.
Templates for dozens of languages and tools are collected in the open
github/gitignore repository — taking one from there and adding your own lines is
faster than remembering everything from scratch.
The file is already in the repository and the rule does nothing#
The most common complaint. .gitignore works only for untracked files; once a file
has been committed, Git keeps tracking it no matter how many rules you add. You
need to stop tracking it while keeping it on disk:
rm '.env'
For a folder it is the same with -r: git rm --cached -r .idea. Then you record
the change with a commit, and from that moment the rule applies.
An important note about secrets: untracking a file removes it from future commits, not from past ones. A password or token that was in a pushed commit counts as compromised — you change it, you do not scrub it from history.
Where else rules live#
There can be more than one .gitignore. A file in a subfolder applies to that
folder and everything below it, and its rules are added to the root ones — handy
when part of the project has its own clutter.
Personal habits do not belong in the shared file: the list for your editor or operating system is better kept in a global file so it works in every project at once.
Rules needed only in this copy of the repository and by nobody else go into
.git/info/exclude — it is not committed and never reaches the server.
How to test a rule#
When you cannot tell why a file is ignored (or is not), ask directly:
.gitignore:4:.venv/ .venv/bin/python
Read the answer as: the source of the rule, the line number, the pattern itself and
the path. An empty answer means no rule matches the file. git status --ignored
shows the whole list of ignored files.
If the rule is written correctly but the file still shows up in git status, it is
almost certainly already tracked — go back to git rm --cached and a
git commit. The other everyday commands are listed in
the cheat sheet.
Step-by-step plan
- Create the file in the rootA plain-text .gitignore next to the .git folder.
- Add the obviousLanguage caches, build folders, virtual environments, editor settings, local secrets.
- Check the outputgit status: no more clutter in the untracked list.
- Untrack old filesgit rm --cached for files that got into the repository before the rule.
- Commit the file itself.gitignore is part of the project and everyone on it needs it.
Start learning this in your own space
The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.
Check yourself
1.The .env file got into the repository earlier, and you have now added a rule to .gitignore. What else do you need to do?
2.What does the line build/ in .gitignore ignore?
3.Which command shows exactly which rule ignores a file?
Sources
-
Pro Git bookThe section “Ignoring Files”free
-
gitignore referencePattern format and the order rules are applied infree
-
github/gitignore templatesReady-made files for languages and toolsfree
Was this helpful?