Skip to main content

Remover dados confidenciais de um repositório

Se você fizer commit de dados confidenciais, como uma senha ou chave SSH em um repositório Git, poderá removê-los do histórico. Para remover completamente arquivos indesejados do histórico de um repositório, você pode usar a ferramenta git filter-repo ou a ferramenta de código aberto BFG Repo-Cleaner.

A ferramenta git filter-repo e o BFG Repo-Cleaner reescrevem o histórico do repositório, o que altera os SHAs dos commits existentes alterados por você e todos os commits dependentes. Os SHAs de commits alterados podem afetar as solicitações de pull abertas no repositório. Recomendamos mesclar ou fechar todas as solicitações de pull abertas antes de remover arquivos do repositório.

Você pode remover o arquivo do último commit com git rm. Para obter informações sobre como remover um arquivo que foi adicionado com o commit mais recente, confira "Sobre arquivos grandes no GitHub".

Aviso: este artigo diz a você como tornar commits com dados confidenciais inacessíveis a partir de quaisquer branches ou tags do seu repositório em GitHub AE. No entanto, esses commits talvez ainda possam ser acessados em clones ou bifurcações do repositório diretamente por meio de hashes SHA-1 em visualizações em cache no GitHub AE e por meio de qualquer pull request que faça referência a eles. Não é possível remover dados confidenciais dos clones ou bifurcações de usuários do seu repositório, mas você pode remover permanentemente as visualizações e referências em cache para os dados confidenciais em pull requests no GitHub AE entrando em contato com seu proprietário do site.

Depois de efetuar push de um commit para o GitHub AE, você deverá considerar todos os dados confidenciais no commit comprometido. Se você tiver efetuado commit de uma senha, altere-a. Se tiver feito commit de uma chave, crie outra. A remoção dos dados comprometidos não resolve sua exposição inicial, especialmente em clones ou bifurcações existentes do seu repositório. Considere essas limitações ao tomar a decisão de reescrever a história do repositório.

Remover um arquivo do histórico do repositório

Você pode limpar um arquivo do histórico do repositório usando a ferramenta git filter-repo ou a ferramenta de código aberto BFG Repo-Cleaner.

Usar o BFG

O BFG Repo-Cleaner é uma ferramenta criada e mantida pela comunidade de código aberto. Ele fornece uma alternativa mais rápida e simples ao git filter-branch para remover dados indesejados.

Por exemplo: para remover o arquivo com dados confidenciais sem alterar o commit mais recente, execute:

$ bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

Para substituir todo o texto listado em passwords.txt em todas as ocorrências no histórico do repositório, execute:

$ bfg --replace-text passwords.txt

Depois que os dados confidenciais são removidos, você deve fazer push forçado das suas alterações para GitHub AE. Fazer push forçado reescreve o histórico do repositório, o que remove dados confidenciais do histórico de commit. Se você fizer push forçado, isso poderá pode sobrescrever commits nos quais outras pessoas basearam o seu trabalho.

$ git push --force

Confira a documentação do BFG Repo-Cleaner para obter instruções completas de uso e download.

Usando arquivo git filter-repo

Aviso: se você executar git filter-repo após fazer stash das alterações, não poderá recuperar as alterações com outros comandos de stash. Antes de executar git filter-repo, é recomendado cancelar o stash das alterações feitas. Para cancelar o stash do último conjunto de alterações com stash, execute git stash show -p | git apply -R. Para obter mais informações, confira Ferramentas do Git – Stash e limpeza.

Para ilustrar como o git filter-repo funciona, mostraremos como remover o arquivo que contém dados confidenciais do histórico do repositório e adicioná-lo ao .gitignore para garantir que ele não sofra um novo commit acidental.

  1. Instale a última versão da ferramenta git filter-repo. Você pode instalar o git-filter-repo manualmente ou usando um gerenciador de pacotes. Por exemplo, para instalar a ferramenta com HomeBrew, use o comando brew install.

    brew install git-filter-repo
    

    Para obter mais informações, confira INSTALL.md no repositório newren/git-filter-repo.

  2. Se você ainda não tem uma cópia local do repositório que contém dados confidenciais no histórico, clone o repositório no computador local.

    $ git clone https://hostname/YOUR-USERNAME/YOUR-REPOSITORY
    > Initialized empty Git repository in /Users/YOUR-FILE-PATH/YOUR-REPOSITORY/.git/
    > remote: Counting objects: 1301, done.
    > remote: Compressing objects: 100% (769/769), done.
    > remote: Total 1301 (delta 724), reused 910 (delta 522)
    > Receiving objects: 100% (1301/1301), 164.39 KiB, done.
    > Resolving deltas: 100% (724/724), done.
  3. Navegue até o diretório de trabalho do repositório.

    $ cd YOUR-REPOSITORY
  4. Execute o comando a seguir, substituindo PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA pelo caminho para o arquivo que deseja remover, não apenas o nome do arquivo. Esses argumentos vão:

    • Forçar o Git a processar todo o histórico de cada branch e marca, mas não fazer check-out
    • Remover o arquivo especificado, bem como todos os commits vazios gerados como resultado
    • Remova algumas configurações, como a URL remota, armazenada no arquivo .git/config. É interessante fazer backup desse arquivo antes para que ele possa ser restaurado mais tarde.
    • Substituir as marcas existentes
      $ git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
        Parsed 197 commits
        New history written in 0.11 seconds; now repacking/cleaning...
        Repacking your repo and cleaning out old unneeded objects
        Enumerating objects: 210, done.
        Counting objects: 100% (210/210), done.
        Delta compression using up to 12 threads
        Compressing objects: 100% (127/127), done.
        Writing objects: 100% (210/210), done.
        Building bitmaps: 100% (48/48), done.
        Total 210 (delta 98), reused 144 (delta 75), pack-reused 0
        Completely finished after 0.64 seconds.

    Observação: se o arquivo com os dados confidenciais costumava estar em qualquer outro caminho (porque foi movido ou renomeado), você também precisa executar esse comando nesses caminhos.

  5. Adicione o arquivo que contém dados confidenciais ao .gitignore para garantir que ele não sofra um novo commit acidental.

    $ echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
    $ git add .gitignore
    $ git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"
    > [main 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore
    >  1 files changed, 1 insertions(+), 0 deletions(-)
  6. Verifique se você removeu tudo o que queria do histórico do repositório e se foi feito check-out de todos os branches.

  7. Quando estiver satisfeito com o estado do repositório, faça pushes forçados das alterações locais para substituir o repositório no GitHub AE, bem como todos os branches para os quais você efetuou push: É necessário um push forçado para remover dados confidenciais do seu histórico de commit.

    $ git push origin --force --all
    > Counting objects: 1074, done.
    > Delta compression using 2 threads.
    > Compressing objects: 100% (677/677), done.
    > Writing objects: 100% (1058/1058), 148.85 KiB, done.
    > Total 1058 (delta 590), reused 602 (delta 378)
    > To https://hostname/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)
  8. Para remover o arquivo confidencial das versões marcadas, você também precisará forçar o push das marcas do Git:

    $ git push origin --force --tags
    > Counting objects: 321, done.
    > Delta compression using up to 8 threads.
    > Compressing objects: 100% (166/166), done.
    > Writing objects: 100% (321/321), 331.74 KiB | 0 bytes/s, done.
    > Total 321 (delta 124), reused 269 (delta 108)
    > To https://hostname/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)

Remover completamente os dados de GitHub

Depois de usar a ferramenta BFG ou git filter-repo para remover os dados confidenciais e efetuar push das alterações para o GitHub AE, você precisa executar mais algumas etapas para remover por completo os dados do GitHub AE.

  1. Entre em contato com o seu proprietário do site e solicite a remoção das visualizações em cache e das referências aos dados confidenciais em pull requests no GitHub AE. Forneça o nome do repositório e/ou um link para a confirmação que você precisa remover.

  2. Diga aos colaboradores para trocar a base (não fazer a mesclagem) dos branches que eles criaram fora do histórico do repositório antigo (afetado). Um commit de merge poderia reintroduzir o histórico antigo completo (ou parte dele) que você acabou de se dar ao trabalho de corrigir.

  3. Depois que algum tempo tiver passado e você estiver confiante de que a ferramenta BFG/git filter-repo não teve efeitos colaterais não intencionais, force todos os objetos no repositório local a serem desreferenciados e faça a coleta de lixo com os seguintes comandos (usando o Git 1.8.5 ou mais recente):

    $ git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
    $ git reflog expire --expire=now --all
    $ git gc --prune=now
    > Counting objects: 2437, done.
    > Delta compression using up to 4 threads.
    > Compressing objects: 100% (1378/1378), done.
    > Writing objects: 100% (2437/2437), done.
    > Total 2437 (delta 1461), reused 1802 (delta 1048)

    Observação: faça isso também enviando por push o histórico filtrado para um repositório novo ou vazio e fazendo um clone novo do GitHub AE.

Evitar commits acidentais no futuro

Há alguns truques simples para evitar fazer commit de coisas não desejadas:

  • Use um programa visual como o GitHub Desktop ou o gitk para fazer commit das alterações. Nos programas visuais, geralmente é mais fácil ver exatamente quais arquivos serão adicionados, excluídos e modificados em cada commit.
  • Evite os comandos catch-all git add . e git commit -a na linha de comando: use git add filename e git rm filename para preparar os arquivos individualmente.
  • Use git add --interactive para revisar e preparar alterações individualmente em cada arquivo.
  • Use git diff --cached para revisar as alterações que você preparou para commit. Essa é a comparação exata que git commit produzirá, desde que você não use o sinalizador -a.

Leitura adicional