Project Files

Written & tested for accuracy by a developer (not AI) · Updated November 2026

What Is a .gitignore File?

A .gitignore file keeps secrets and local-only settings out of a project when you use Git for save-as-you-go version control. Examples and how to create one.

Git is used for save-as-you-go version control. A .gitignore file keeps files out of your project's history, such as a file containing passwords you don't want to share. It is a plain-text file, usually in the project's top folder, with a list of filenames. Save it with Git ("commit it"), with the rest of your project, so everyone who copies the project gets the same rules, and credentials or temporary files don't get saved remotely to GitHub.

You can set up a global ignore file, in your home directory, to apply to all projects. Or set up an individual .gitignore file in each project, with project specifics that are relevant for the file structure or languages used in the project. Set up .gitignore correctly and you can keep API keys and Mac clutter off GitHub in every project you start.

Experienced developers know .gitignore is a first line of defense for secrets. They also know its two limits. It cannot erase a file from commits already made. And it doesn't stop an AI agent from reading a file. Here are all the details you need to know.

What's in a Project Folder? explains the other files and folders you'll find beside a .gitignore file in a project. Setting up Git and its ignore files is one step to set up a Mac for software development.

What a .gitignore file does

Git records the history of a project's files. Each time you commit, Git saves a snapshot of the files it tracks. A new file stays "untracked" until you add it. The git status command lists every untracked file so you don't overlook any. A .gitignore file names the files Git should skip, so they no longer appear in git status and never get added by accident.

The rules apply only to untracked files. If Git already tracks a file, adding its name to .gitignore changes nothing (the fix is below, in "Fix a .gitignore that isn't working").

Developers ignore two kinds of files:

  • Secrets - for example, a .env file of API keys and passwords, explained in What Is a .env File?. Anyone who can see your project on GitHub could use them.
  • Clutter - temporary files created by your tools or your Mac, which you can rebuild and nobody else needs. That includes the .venv folder of a Python project (What Is a .venv Folder?), the node_modules folder of a JavaScript project (What Is package.json?), build output, log files, and the .DS_Store files the Finder makes (What Is a .DS_Store File?).

You can also ignore a personal settings file that only you need, such as CLAUDE.local.md for Anthropic Claude (Agent Instructions) or mise.local.toml for the mise version manager (Mise Configuration).

An example .gitignore

If you used a "Set Up Your Mac" app, your starter projects already have a basic .gitignore. Here is an example:

# Secrets: never commit these
.env

# Python (uv)
.venv/
__pycache__/
*.pyc

# Node (mise)
node_modules/

# Build output
dist/
build/

# Logs
*.log

# macOS
.DS_Store

Lines that start with # are comments. The .env line leaves out any file named .env, in any folder of the project. Patterns that end in a slash, such as .venv/ and node_modules/, leave out a whole folder and everything in it. The * in *.pyc and *.log matches any name, so those lines leave out every file that ends in .pyc (files Python makes when it runs your code) or .log. The dist/ and build/ folders hold software that is ready to run or publish.

See and edit a .gitignore file

The Mac's Finder hides any file with a name that starts with a dot. To see hidden dot files in a Finder window, press Command + Shift + . (period). The .gitignore file will appear, dimmed. Show Hidden Files on Mac explains this and other ways to see hidden files.

In a terminal application, use the ls -a command to list hidden files. Open a terminal application, go to your project folder with cd, and run:

$ ls -a

You'll see .gitignore in the list if the project has one. It is an ordinary text file with no extension, so any text editor opens it.

To make a new one, use the touch command in the project's top folder. It creates an empty file with the name you give it:

$ touch .gitignore

You can't make one in the Finder. If you rename a file to .gitignore, the Finder shows a message saying that names beginning with a dot "are reserved for the system" and the file keeps its old name.

Write .gitignore patterns

Here's what you need to know to read or write most .gitignore files, from the rules in Git's manual:

  • One pattern on each line - a blank line matches nothing. A line that starts with # is a comment.
  • A name with no slash - such as .env or *.log, matches in the top folder and every subfolder of the project.
  • * and ? - * matches any characters except a slash. A ? matches exactly one character.
  • A slash at the end - such as build/, matches only a folder, with everything inside it.
  • A slash at the start - such as /build, matches only in the folder that holds the .gitignore file, usually the project's top folder.
  • ** - matches any number of folders, so **/logs matches a logs folder anywhere. The pattern docs/**/*.pdf matches a PDF at any depth inside docs.
  • ! at the start - brings back something an earlier line left out, so *.log followed by !keep.log ignores every log file except keep.log.

When two lines match the same file, the later line decides. A project can also have a .gitignore in a subfolder. Its rules apply to that folder and override the top folder's file.

If you use ! to bring back a file, there's a tricky gotcha. You can't bring back a file whose folder is ignored:

build/
!build/notes.txt

Here build/notes.txt stays ignored. To keep one file from a folder, ignore the folder's contents with build/* instead, then add the ! line.

Fix a .gitignore that isn't working

If you add a file to .gitignore and Git still lists its changes, Git was already tracking the file. That usually means the file was committed before the rule was written. Tell Git to stop tracking it, without deleting your copy (.env is the example file here):

$ git rm --cached .env

Replace .env with the file's name, then commit. The file stays on your Mac, but Git stops tracking it. From then on, the .gitignore rule applies.

If the file holds secrets, such as a .env file, this isn't the whole fix. Git stops tracking the file, but it stays in the commits you already made, so anyone with a copy of the project's history can still read it. See "What a .gitignore file doesn't do" below.

To find the rule that ignores a file, use git check-ignore with the -v option. It shows the ignore file and the line that matched:

$ git check-ignore -v .DS_Store

If it shows nothing, first check whether Git already tracks the file, because git check-ignore skips tracked files. Otherwise, no rule matches that name, so look for a typing mistake in the pattern.

Ignore .DS_Store in every project

A project's .gitignore holds rules for everyone who works on the project. Files that come from your own Mac, such as the Finder's .DS_Store, are better ignored globally, so you don't have to add them to every project. Git reads a global ignore file in your home directory, ~/.config/git/ignore (the ~ stands for your home directory). Git looks there automatically but you need to create it first.

First, make the folder, if it doesn't exist. The -p option makes mkdir do nothing if the folder is already there:

$ mkdir -p ~/.config/git

Then add .DS_Store as a line at the end of the file. The >> adds the line and creates the file if needed, without erasing lines already in it:

$ echo ".DS_Store" >> ~/.config/git/ignore

Keep the >>, because other tools write to this file too. For example, Claude adds a line for its personal settings file, .claude/settings.local.json, the first time it saves that file in a project that doesn't ignore it. To check, run git status in a project. The .DS_Store file will be gone from the list.

You may see suggestions elsewhere to set Git's core.excludesFile setting to ~/.gitignore_global, which also works. Then Git reads that file in place of ~/.config/git/ignore. For rules that apply only to your own copy of one project, Git also reads .git/info/exclude inside the project, which is never committed.

Start from a template

You don't have to write a .gitignore from scratch. GitHub keeps an official collection of templates at github/gitignore, one for each language and many tools, and offers them when you create a repository on GitHub. Its macOS template, in the Global folder, starts with .DS_Store. I also like Toptal's gitignore generator (formerly gitignore.io), which builds a file when you enter a list of the tools you use.

What a .gitignore file doesn't do

A .gitignore file only applies to future commits. If you committed a file of secrets before you ignored it, the file is still in the project's history, and in every copy of the project. If that history reached GitHub, assume the secret is now public. GitHub's guide to removing sensitive data from a repository says to revoke or replace the secret first, which you do with the service that issued it.

It also doesn't hide files from an AI agent. A .gitignore file is a list for Git. Claude and ChatGPT Codex can read ignored files in your project. Claude's search tool skips ignored files, but Claude can still open any file by its path. To keep Claude out of a file, Anthropic's documentation says to add a Read deny rule to its settings. Codex has deny patterns in its permission settings. What Is a .env File? shows both.

The safest place for an API key is outside the project folder entirely. The starter projects keep API keys in ~/.env, a file in your home directory, so a key never lands in a project that you commit, share, or hand to an AI agent.

Continue setting up your Mac

Don't miss the full visual roadmap and checklist that shows how to set up a Mac for software development, with all the essential tools and settings you might not yet know about.