Files Git Should Never See
Run git status on a real project and it will offer you things you have no interest in committing: a file your editor created, a folder your tools generated, a note containing a password.
The fix is a file called .gitignore: a plain text list of what Git should pretend it cannot see. It sits at the top of the repository, it is committed like any other file, and it is one of the first things you should write in a new project.
The four categories
Secrets — passwords, API keys, tokens, anything in a .env file. This is the expensive category: a committed secret is a security problem rather than a tidiness problem, and the next topic covers what to do when it happens.
Generated output — build folders, compiled files, anything your tools produce from your source. It can be recreated at any time, so storing it just makes every diff unreadable.
Dependencies — libraries installed by a package manager, of which node_modules/ is the famous example. Enormous, reinstallable from a single list, and the usual reason a beginner's first repository is several hundred megabytes.
Machine noise — .DS_Store on macOS, Thumbs.db on Windows, your editor's settings folder. Individually harmless, collectively enough to make git status unreadable, which means you stop reading it.
Writing one
Create a file called .gitignore in the top folder of the project. One pattern per line:
# machine noise .DS_Store Thumbs.db # local notes, not for the club notes/private/ # anything with credentials in it .env *.key
A plain name matches that file. A name ending in a slash matches a whole folder. An asterisk stands for "anything", so *.key matches every file with that extension. A line starting with # is a comment, and comments are worth writing — six months later "why is this ignored" is a real question.
What ignoring actually does
Ignored files stop appearing in git status and are never picked up by git add .. They stay on your disk, completely untouched; Git simply stops mentioning them.
git status # four untracked files, three of them noise git add .gitignore git status # one clean line
That second reading is the point. A status output you can take in at a glance is a status output you will actually read, and reading it is what stops the accidents in the rest of this chapter.
.gitignore is itself committed
This surprises people, who assume a file about what to hide should itself be hidden. The opposite: the rules belong in the repository so that everyone working on the project ignores the same things.
git add .gitignore git commit -m "Ignore local notes and system files"
The file contains rules, not secrets. Nobody learns anything dangerous from reading that you ignore .env — they learn it from reading .env itself, which is exactly what the rule prevents.
Where to get a good one
You do not have to invent these. GitHub offers a ready-made .gitignore for every common language and toolchain when you create a repository, and those templates are maintained by people who know which files a given toolchain leaves behind.
Start from the template for whatever you are building and add your own lines. For Sandpiper — plain HTML and CSS — the four lines above are genuinely enough.
The one thing it cannot do
An ignore rule applies to files Git is not already tracking. Add a rule for a file that has already been committed and nothing happens: Git keeps tracking what it already tracks.
That is the single most surprising behaviour in this chapter, and it is the whole of the next topic.
- "Ignoring a file deletes it." The file stays exactly where it is on your disk. Git stops watching it and stops mentioning it, and that is the entire effect.
- "
.gitignoreshould itself be secret." It is shared on purpose, so that everyone on the project ignores the same things. Its contents are rules, not credentials. - "Adding a file to
.gitignoreremoves it from the repository." Not if it is already tracked. Ignore rules only apply to files Git has not been asked to record, which is the next topic. - "I can add ignore rules later, once the project is bigger." The expensive mistakes happen in the first week, before anyone is being careful. Four lines on day one is the cheapest insurance in this book.
- A committed secret is a real incident with a real cost, and a
.gitignorewritten before the first commit is what prevents it. - Ignoring generated output keeps diffs readable. Nobody can review a change that includes ten thousand lines of build output, and in Chapter 8 somebody will be trying.
- A short, clean
git statusis a status you actually read — which is the habit every accident in Chapter 4 was avoidable by.
Knowledge Check
What happens to a file on your disk when you add it to .gitignore?
- Nothing at all, since it stays where it is and Git simply stops mentioning it
- It is moved into a hidden folder so that it cannot be committed by accident
- It is deleted, since Git assumes anything ignored is no longer needed
- It is committed once more, then excluded from every commit after that
Why is .gitignore committed to the repository rather than kept private?
- So that everyone working on the project ignores exactly the same files
- Because Git refuses to read the file unless it has been committed first
- Because an uncommitted
.gitignoreis deleted the next time you switch branches - Because the rules would otherwise be visible to anyone who clones the project
You add .env to .gitignore, but it was committed last week. What happens?
- Nothing changes, since Git keeps tracking a file it already tracks
- The file is removed from the repository at your next commit
- The file is removed from every past commit in the history
- Git reports an error because the rule conflicts with an existing tracked file
Which of these belongs in a .gitignore for almost any project?
- Installed dependency folders, which are huge and reinstallable from one list
- The main source files, since they change most often and create the largest diffs
- The
.gitignorefile itself, so that its rules stay out of the history - The README, because its contents are meant for people rather than for Git
You got correct