Pular para o conteúdo
Setup do Dev
Publicidade
Guias

Como tirar uma senha ou token do histórico do Git com o git-filter-repo

Apagar o arquivo no commit seguinte não basta: o segredo continua no histórico. Primeiro troque a credencial, depois reescreva o histórico do jeito certo.

Por Setup do Dev
4 min de leitura
Compartilhar
Capa do Setup do Dev com o logo do Git: "Como tirar uma senha do histórico do Git", com um terminal rodando o git-filter-repo e uma linha de commits com um deles removido
Logo do Git: Jason Long, <a href="https://creativecommons.org/licenses/by/3.0/deed.pt-br" target="_blank" rel="noopener">CC BY 3.0</a>

Todo mundo que programa já fez um commit com o que não devia: o .env com a senha do banco, a chave de uma API, um token colado num arquivo de configuração. O reflexo é apagar o arquivo e fazer outro commit. Só que o Git guarda tudo: o segredo continua no histórico, a um git checkout de distância de quem clonar o repositório. Foi esse tipo de descuido que pesou no vazamento da Meta no GitHub.

Este guia segue o caminho da documentação do GitHub: trocar a credencial, reescrever o histórico com o git-filter-repo e evitar que aconteça de novo.

Antes de tudo, troque a credencial

Se o que vazou é uma senha, um token ou uma chave, o primeiro passo é revogá-la ou gerar outra no serviço de onde ela veio. Uma credencial trocada não serve para mais nada, e muitas vezes isso já resolve o problema: a própria documentação diz que reescrever o histórico pode nem ser necessário depois disso.

Publicidade

Reescrever vale a pena quando o dado não pode simplesmente ser trocado, como informação pessoal de clientes, ou quando o repositório é público e você não quer o arquivo à vista. E tem custo: os hashes de todos os commits a partir dali mudam, assinaturas de commits e tags somem, e pull requests abertas podem perder os comentários. Feche ou integre as PRs abertas antes de começar.

Instale o git-filter-repo

A ferramenta recomendada é o git-filter-repo, numa versão com a opção --sensitive-data-removal, ou seja, a 2.47 ou mais nova. No macOS, pelo Homebrew:

brew install git-filter-repo

Para outros sistemas, o repositório do projeto tem as instruções de instalação. Depois, clone o repositório e entre na pasta dele:

git clone https://github.com/SEU-USUARIO/SEU-REPOSITORIO
cd SEU-REPOSITORIO

Tire o arquivo (ou só o texto) do histórico

Para apagar um arquivo de todos os branches e tags, passe o caminho completo dele dentro do repositório, e não só o nome:

git-filter-repo --sensitive-data-removal --invert-paths --path config/.env

Se o arquivo mudou de lugar ou de nome em algum momento, acrescente um --path para cada caminho que ele já teve. E quando o problema é um texto espalhado em vários arquivos, como uma senha que aparece no código e num script, dá para trocá-lo em todo o histórico a partir de uma lista guardada fora do repositório:

git-filter-repo --sensitive-data-removal --replace-text ../senhas.txt

Confira o resultado antes de enviar. A documentação sugere contar quantas pull requests a reescrita vai afetar:

grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refs

Se o número for maior do que você esperava, ainda dá para voltar: basta apagar esse clone e recomeçar. Depois do próximo passo, não dá mais.

Envie o histórico novo e avise quem clonou

Com tudo certo, sobrescreva o repositório no GitHub:

git push --force --mirror origin

O envio das referências que começam com refs/pull/ vai falhar, porque o GitHub as trata como somente leitura, e isso é esperado. Se outro branch falhar, provavelmente há proteção de branch ativa: desligue-a por um momento e repita.

Publicidade

Falta o que está fora do seu alcance. Quem já tinha clonado o repositório precisa descartar o clone e clonar de novo, e quem criou branches a partir do histórico antigo deve fazer rebase, e não merge, para não trazer o segredo de volta. Forks continuam com o commit antigo, e as visualizações em cache no GitHub só somem pelo suporte, que pede o nome do repositório, o número de PRs afetadas e os primeiros commits alterados que o git-filter-repo mostrou na saída.

Como não passar por isso de novo

A prevenção é mais barata que a limpeza. Ponha no .gitignore todo arquivo que guarda segredo, e guarde as credenciais em variáveis de ambiente ou num cofre de segredos, em vez de deixá-las no código. Troque o git add . por adicionar arquivo a arquivo, e confira exatamente o que vai no commit com:

git diff --cached

Por fim, ligue a proteção de push do GitHub, que detecta segredos escritos no código e barra o envio antes de ele chegar ao repositório. Se você ainda se enrola com o histórico, vale ler também o nosso guia sobre git reset, revert e restore.

Fonte: GitHub Docs: remover dados confidenciais de um repositório

Produzido com auxílio de IA e revisado pela redação.

Publicidade

Comentários (0)

Ainda não há comentários. Comece a conversa.

Deixe seu comentário

Seu e-mail não será publicado. O primeiro comentário de cada pessoa passa por moderação.

Seja respeitoso
Publicidade

Neste artigo

  1. Antes de tudo, troque a credencial
  2. Instale o git-filter-repo
  3. Tire o arquivo (ou só o texto) do histórico
  4. Envie o histórico novo e avise quem clonou
  5. Como não passar por isso de novo

Mais lidas

Editorias

Publicidade

Leia também

Newsletter semanal

O essencial da tecnologia, toda sexta no seu e-mail

Uma curadoria da redação com as notícias que importam para quem desenvolve, joga e trabalha com tecnologia. Sem spam.

Ao assinar, você concorda com a política de privacidade. Cancele quando quiser.

Publicidade