Gitignore: excluindo arquivos do controle de versão

1. O que é o .gitignore e por que usá-lo?

O arquivo .gitignore é um recurso fundamental do Git que permite especificar quais arquivos e diretórios devem ser intencionalmente ignorados pelo sistema de controle de versão. Quando você adiciona um padrão ao .gitignore, o Git automaticamente exclui esses arquivos de operações como git add, git status e git commit.

Problemas resolvidos pelo .gitignore:

  • Arquivos temporários: logs de compilação, caches de IDE, arquivos de sistema (.DS_Store, Thumbs.db)
  • Arquivos sensíveis: senhas, chaves SSH, tokens de API, variáveis de ambiente (.env)
  • Arquivos gerados: pastas node_modules/, build/, dist/, arquivos compilados (.class, .pyc)
  • Arquivos grandes: datasets, binários, dependências baixadas

Diferença crucial: Ignorar um arquivo com .gitignore impede que ele seja adicionado ao repositório. Remover um arquivo do rastreamento com git rm o deleta do índice, mas não impede que ele seja readicionado posteriormente. O .gitignore é uma proteção preventiva.

2. Criando e estruturando o .gitignore

O arquivo .gitignore deve ser criado na raiz do repositório, mas também pode existir em subdiretórios para escopos específicos.

Sintaxe básica:

# Comentários começam com #
# Linhas em branco são ignoradas

# Ignorar um arquivo específico
config.local.json

# Ignorar todos os arquivos com extensão .log
*.log

# Ignorar um diretório inteiro
build/

# Ignorar qualquer diretório chamado temp em qualquer nível
temp/

Exemplo completo para um projeto Node.js:

# Dependências
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Arquivos de ambiente
.env
.env.local
.env.*.local

# Diretórios de build
dist/
build/

# Arquivos de IDE
.vscode/
.idea/
*.swp
*.swo

# Sistema operacional
.DS_Store
Thumbs.db

# Logs
logs/
*.log

3. Padrões de correspondência de arquivos

O Git suporta padrões glob (glob patterns) para correspondência flexível:

Curingas básicos:

# * corresponde a qualquer sequência de caracteres (exceto /)
*.txt          # ignora todos os .txt na raiz
docs/*.txt     # ignora .txt dentro de docs/

# ? corresponde a um único caractere
??.txt         # ignora arquivos de 2 letras + .txt (ex: ab.txt)

# [abc] corresponde a qualquer caractere do conjunto
[abc].txt      # ignora a.txt, b.txt, c.txt

Barras e diretórios:

# / no início: corresponde apenas na raiz do repositório
/build         # ignora apenas a pasta build/ na raiz
*.txt          # ignora .txt em qualquer nível

# / no final: indica diretório
temp/          # ignora apenas diretórios chamados temp
temp           # ignora arquivos E diretórios chamados temp

# ** corresponde a qualquer número de subdiretórios
a/**/b         # ignora a/b, a/x/b, a/x/y/b

Negação com !:

# Ignorar todos os .log, exceto importante.log
*.log
!importante.log

# Ignorar todos os .txt em logs/, exceto logs/urgente.txt
logs/*.txt
!logs/urgente.txt

Ordem importa: as regras são processadas em ordem. A última regra vence. Se você ignora todos os *.log e depois nega importante.log, ele será rastreado.

4. Ignorando arquivos já rastreados

Um erro comum é adicionar um arquivo ao .gitignore e esperar que ele suma do repositório. Isso não funciona para arquivos já rastreados.

Problema: Se o arquivo já foi commitado, o Git continua rastreando suas alterações, mesmo com o .gitignore.

Solução: Use git rm --cached para remover o arquivo do índice sem deletá-lo do disco local:

# Passo 1: Adicione o padrão ao .gitignore
echo "config.local.json" >> .gitignore

# Passo 2: Remova do rastreamento (mantendo o arquivo local)
git rm --cached config.local.json

# Passo 3: Commit da mudança
git commit -m "Remove config.local.json do rastreamento"

# Passo 4: Verifique se o arquivo não aparece mais no status
git status

Cuidados com histórico: O arquivo ainda existirá em commits anteriores. Se ele contém dados sensíveis, você precisará reescrever o histórico com git filter-branch ou BFG Repo-Cleaner.

5. Escopos e herança do .gitignore

Escopo local: Um .gitignore em um subdiretório aplica regras apenas àquele diretório e seus filhos. Regras do .gitignore pai ainda são válidas, a menos que sejam sobrescritas.

# Estrutura de exemplo
meu-projeto/
├── .gitignore          # regras globais do projeto
├── src/
│   ├── .gitignore      # regras específicas de src/
│   └── ...
└── tests/
    └── .gitignore      # regras específicas de tests/

Regras globais do usuário: Você pode criar um .gitignore global que se aplica a todos os repositórios do seu computador:

# Configurar arquivo global
git config --global core.excludesFile ~/.gitignore_global

# Conteúdo do ~/.gitignore_global
.DS_Store
*.swp
Thumbs.db

Prioridade (da maior para a menor):
1. Regras locais (.gitignore no diretório atual)
2. Regras do repositório (.gitignore na raiz)
3. Regras globais do usuário (core.excludesFile)
4. Regras do sistema (/etc/gitignore)

6. Arquivos .gitignore especiais e templates

Templates prontos: Use gitignore.io ou os templates do GitHub para gerar .gitignore específicos para sua stack:

# Exemplo: template para Python
# Fonte: gitignore.io

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

Ignorando arquivos sensíveis:

# Chaves e certificados
*.pem
*.key
*.cert
*.p12

# Tokens e credenciais
.env
.aws/credentials
.gcloud/
.ssh/

# Arquivos de configuração com senhas
database.yml
config/secrets.yml

7. Verificando e depurando regras de exclusão

Comando git check-ignore: Teste se um arquivo específico será ignorado:

# Verificar um arquivo
git check-ignore config.local.json

# Verificar com detalhes (qual regra está ignorando)
git check-ignore -v config.local.json

# Verificar múltiplos arquivos
git check-ignore arquivo1.log arquivo2.txt node_modules/

Saída esperada:

$ git check-ignore -v config.local.json
.gitignore:3:config.local.json    config.local.json

Depuração de regras conflitantes:

# Verificar se um arquivo ignorado aparece no status
git status --ignored

# Forçar adição de um arquivo ignorado (útil para testes)
git add -f arquivo_ignorado.log

# Listar todos os arquivos ignorados
git ls-files --others --ignored --exclude-standard

Problemas comuns:

  • Regra muito abrangente: * na raiz ignora tudo. Use * com negação.
  • Barras esquecidas: temp ignora arquivos e diretórios; temp/ ignora apenas diretórios.
  • Ordem incorreta: Se você nega antes de ignorar, a negação é sobrescrita.

Referências