Arquivo .gitignore: como ignorar arquivos no Git e remover os já adicionados
O arquivo .gitignore na raiz do repositório lista padrões de arquivos e pastas que o Git não vai rastrear: dependências, builds, logs, segredos. Ele vale apenas para arquivos não rastreados, por isso um arquivo já commitado precisa ser removido do índice com o comando git rm --cached.
O mecanismo de git ignore é a forma de dizer ao Git: "não mexa nesses arquivos, não mostre no git status e não adicione com git add .". As regras ficam em um arquivo de texto chamado .gitignore, que é commitado junto com o projeto e vale para todo o time. O detalhe principal: o ignore só atua sobre arquivos que o Git ainda não rastreia.
O que normalmente vai no .gitignore
- Dependências:
node_modules/,vendor/,.venv/— o gerenciador de pacotes as recria. - Resultados de build:
dist/,build/,*.class,__pycache__/. - Logs e arquivos temporários:
*.log,tmp/,*.swp. - Segredos e configurações locais:
.env, chaves, configs locais. - Lixo do sistema operacional e dos editores:
.DS_Store,Thumbs.db,.idea/— embora seja melhor mantê-los no ignore global, explicado abaixo.
A regra é simples: no repositório deve estar o que as pessoas escrevem, não o que os programas geram ou o que depende de uma máquina específica.
Como criar o .gitignore
É um arquivo de texto comum na raiz do repositório. Crie-o, escreva os padrões, um por linha, e faça o commit:
cat > .gitignore <<'EOF'
# dependências
node_modules/
# build
dist/
# logs
*.log
# segredos
.env
EOF
git add .gitignore
git commit -m "chore: adicionado .gitignore"
Há modelos prontos para linguagens e frameworks populares no repositório github/gitignore; GitHub e GitLab oferecem a escolha de um modelo ao criar o projeto. Use-os como base e tire o que não for necessário.
Sintaxe dos padrões do .gitignore
| Padrão | O que ignora |
|---|---|
*.log | todos os arquivos com extensão .log em qualquer pasta |
build/ | a pasta build em qualquer nível (barra no final = só pastas) |
/build | só o build da raiz (barra no início ancora na pasta do .gitignore) |
docs/*.pdf | pdf direto em docs, mas não em docs/old/ |
docs/**/*.pdf | pdf em docs e em todas as subpastas |
**/temp | temp em qualquer pasta |
!keep.log | exceção: não ignorar keep.log |
file?.txt | ? — um caractere qualquer |
[ab].txt | a.txt ou b.txt |
# comentário | linha de comentário |
Detalhe importante: um padrão sem barra no meio (config.json) vale em qualquer nível, enquanto um padrão com barra no início ou no meio (/config.json, src/config.json) é relativo à pasta onde está esse .gitignore.
Exceções com ponto de exclamação
*.log
!important.log
A armadilha: não dá para "trazer de volta" um arquivo se a pasta-mãe dele está ignorada. O Git não entra em pastas ignoradas, então isto não funciona:
logs/
!logs/keep.txt # não funciona
O certo é ignorar o conteúdo, e não a pasta:
logs/*
!logs/keep.txt
O mesmo truque serve para manter uma pasta vazia no repositório: o Git não guarda diretórios vazios, então coloca-se nela um arquivo .gitkeep e só ele é liberado.
Onde mais dá para definir o ignore
| Local | Vale para | Vai para o repositório |
|---|---|---|
.gitignore na raiz e em subpastas | todo o time | sim |
.git/info/exclude | só este clone | não |
arquivo global core.excludesFile | todos os seus repositórios | não |
O lixo do seu sistema operacional e da sua IDE faz sentido ir para o ignore global, para não poluir o .gitignore compartilhado:
git config --global core.excludesFile ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global
Se core.excludesFile não estiver definido, o Git lê ~/.config/git/ignore, se existir.
Por que o .gitignore não funciona
A reclamação mais comum: "coloquei o arquivo no .gitignore, mas o Git continua mostrando alterações". A causa quase sempre é uma só — o arquivo já é rastreado. O ignore não afeta arquivos que já entraram em algum commit.
Para ver qual regra está sendo aplicada (ou por que não está), use o git check-ignore:
git check-ignore -v logs/app.log
# .gitignore:3:*.log logs/app.log
A saída mostra o arquivo e a linha da regra. Saída vazia significa que o arquivo não é ignorado. Outra causa de falha são espaços no fim da linha do padrão ou a codificação errada do arquivo (por exemplo, UTF-16 ao criá-lo pelo PowerShell).
Como tirar do repositório um arquivo já commitado: git rm --cached
O comando git rm remove o arquivo do índice e do disco. Com a flag --cached, só do índice: o arquivo continua com você, mas deixa de ser rastreado.
echo ".env" >> .gitignore
git rm --cached .env
git commit -m "chore: .env não é mais rastreado"
git push
Para uma pasta, é preciso -r:
git rm -r --cached node_modules/
Se as regras forem muitas e não estiver claro o que já entrou no repositório, dá para reconstruir o índice inteiro: git rm -r --cached ., depois git add . e commit. Antes do commit, confira o git status — lá aparecem os arquivos removidos do índice.
Atenção: segredos continuam no histórico
O git rm --cached tira o arquivo dos próximos commits, não dos anteriores. Se uma senha ou token entrou no repositório, ele está acessível no histórico para qualquer pessoa que tenha um clone. O segredo deve ser considerado comprometido e gerado de novo. Dá para reescrever o histórico com ferramentas como git filter-repo, mas isso muda os hashes de todos os commits seguintes e exige combinar com o time.
Outra consequência: para os colegas, depois do git pull, o arquivo removido do índice com --cached será apagado do disco. No caso do .env, avise o time antes ou mantenha um modelo .env.example no repositório.
git rm: removendo arquivos
git rm old.py # remover do disco e do índice
git rm -r legacy/ # remover uma pasta
git rm -n '*.tmp' # dry run: mostrar o que será removido
git rm -f changed.py # remover um arquivo com alterações não commitadas
Se você apagar o arquivo com um rm comum, o Git o verá como "deleted", e a remoção terá de ser adicionada com git add ou git rm. O git rm faz os dois passos de uma vez. Sem -f, ele se recusa a remover um arquivo com alterações não commitadas — é uma proteção contra perda de trabalho.
git mv: renomear e mover
git mv utils.py helpers.py
git mv helpers.py src/helpers.py
O git mv é um atalho para mv + git rm do caminho antigo + git add do novo. O Git não guarda o fato da renomeação: ele a deduz pela semelhança do conteúdo ao exibir git status, git log --follow e git diff. Por isso, renomear com git mv ou com um mv comum seguido de git add -A dá o mesmo resultado.
Dica prática: renomeie e altere o conteúdo do arquivo em commits diferentes. Se o arquivo mudar muito junto com a renomeação, o Git pode não reconhecê-lo como o mesmo arquivo, e o histórico com --follow se interrompe.
Para mudar só a caixa (maiúsculas/minúsculas) do nome no Windows e no macOS (sistemas de arquivos que não diferenciam maiúsculas), use git mv readme.md README.md — uma renomeação simples pelo explorador de arquivos pode passar despercebida pelo Git.
Ordem das regras e prioridade
Dentro de um mesmo arquivo, as regras são lidas de cima para baixo, e a última que corresponde vence. Por isso a exceção !keep.log precisa vir abaixo da regra *.log, senão será sobreposta. Entre arquivos, a prioridade é: o .gitignore de uma subpasta vale mais que o da raiz, e o ignore global e o .git/info/exclude têm a prioridade mais baixa.
Exemplo de .gitignore para um projeto web
Abaixo, uma versão que funciona para um projeto em Node.js com backend em Python. Repare nos comentários: daqui a seis meses ninguém vai lembrar por que cada regra foi adicionada.
# --- dependências ---
node_modules/
.venv/
# --- build e caches ---
/dist
/build
__pycache__/
*.pyc
.pytest_cache/
coverage/
# --- logs ---
*.log
npm-debug.log*
# --- ambiente e segredos ---
.env
.env.*
!.env.example
# --- uploads dos usuários, mas mantendo a pasta ---
uploads/*
!uploads/.gitkeep
Aqui são usados os dois truques com exceções: .env.* esconde todas as variantes locais de ambiente, mas o modelo .env.example continua no repositório, e a pasta uploads existe no clone graças ao .gitkeep.
O que não vale a pena ignorar
Exagerar no ignore também atrapalha. Os arquivos de lock de dependências — package-lock.json, poetry.lock, composer.lock — em aplicações normalmente são commitados: eles garantem que todos os desenvolvedores e o CI instalem as mesmas versões dos pacotes. Configurações comuns de formatação (.editorconfig, configs de linters) também devem ficar no repositório.
Um caso polêmico são as configurações da IDE. A pasta .vscode/ costuma ser ignorada inteira, mas às vezes se commitam as extensões recomendadas e as tarefas de build: .vscode/*, depois !.vscode/extensions.json. A decisão é do time; o importante é não manter caminhos pessoais e chaves no repositório compartilhado.
Cenário: commitou o node_modules sem querer
Erro clássico de iniciante: git add . antes de criar o .gitignore, e dezenas de milhares de arquivos vão parar no commit. A correção em três passos:
echo "node_modules/" >> .gitignore
git rm -r --cached node_modules
git commit -m "chore: node_modules removido do repositório"
Se o commit ainda não foi enviado ao servidor, é mais limpo reescrevê-lo, para que os arquivos pesados não fiquem no histórico: git reset --soft HEAD~1, depois os mesmos comandos e um novo commit. Depois do push, os arquivos já estão no histórico, e o tamanho do clone não diminui sem reescrever o histórico.
Para que isso não se repita, crie o .gitignore antes do primeiro git add e crie o hábito de olhar o git status antes de commitar: uma lista suspeitamente longa de arquivos novos é motivo para parar.
Resumo
O arquivo .gitignore é o primeiro que vale commitar em um projeto novo: dependências, builds, logs e segredos não têm lugar no repositório. O ignore só funciona para arquivos não rastreados, por isso o que já foi adicionado se remove com git rm --cached, e as regras se verificam com git check-ignore -v. Para remover e renomear, use git rm e git mv, assim as alterações vão direto para o índice. O trabalho com o índice e com o primeiro repositório é praticado no curso de Git.
Perguntas frequentes
É preciso commitar o próprio .gitignore?
Sim, para que as regras valham para todo o time; exclusões pessoais vão no .git/info/exclude ou no ignore global.
Dá para ter vários arquivos .gitignore?
Sim, dá para colocar um .gitignore em qualquer subpasta, e as regras dele valem em relação a essa pasta, complementando as da raiz.
Como adicionar ao commit um arquivo ignorado?
Use git add -f caminho/do/arquivo; depois disso o arquivo passa a ser rastreado, e o .gitignore não tem mais efeito sobre ele.
Como ver todos os arquivos ignorados do projeto?
Rode git status --ignored ou git ls-files --others --ignored --exclude-standard.
Como parar temporariamente de rastrear alterações em um arquivo commitado?
Para isso existe git update-index --skip-worktree arquivo, mas é uma configuração local e não substitui o .gitignore.
Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.
Ir para o curso