Tutorial

Arquivo .gitignore: como ignorar arquivos no Git e remover os já adicionados

Atualizado: · Skillaria.Top

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ãoO que ignora
*.logtodos os arquivos com extensão .log em qualquer pasta
build/a pasta build em qualquer nível (barra no final = só pastas)
/buildsó o build da raiz (barra no início ancora na pasta do .gitignore)
docs/*.pdfpdf direto em docs, mas não em docs/old/
docs/**/*.pdfpdf em docs e em todas as subpastas
**/temptemp em qualquer pasta
!keep.logexceção: não ignorar keep.log
file?.txt? — um caractere qualquer
[ab].txta.txt ou b.txt
# comentáriolinha 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

LocalVale paraVai para o repositório
.gitignore na raiz e em subpastastodo o timesim
.git/info/excludesó este clonenão
arquivo global core.excludesFiletodos os seus repositóriosnã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.

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.

Ir para o curso