A ferramenta git filter-repo
e o BFG Repo-Cleaner reescrevem o histórico do seu repositório, que muda os SHAs para os commits existentes que você altera e quaisquer commits dependentes. Os SHAs do commit alterados podem afetar as pull requests abertas no repositório. Recomendamos que você faça merge ou feche todas todas as pull requests abertas antes de remover os arquivos do repositório.
Você pode remover o arquivo com o commit mais recente com git rm
. Para obter informações sobre a remoção de um arquivo que foi adicionado com o commit mais recente, consulte "Sobre arquivos grandes em GitHub".
Este artigo explica como fazer commits com dados confidenciais que não podem ser acessados de nenhum branch ou tag no repositório do GitHub Enterprise Server. No entanto, é importante destacar que 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 Enterprise Server 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 Enterprise Server entrando em contato com your site administrator.
Aviso: Depois de ter feito o push de um commit para GitHub Enterprise Server, você deve considerar todos os dados confidenciais no commit comprometido. Se você fez o 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
You can purge a file from your repository's history using either the git filter-repo
tool or the BFG Repo-Cleaner open source tool.
Usar o BFG
O BFG Repo-Cleaner é uma ferramenta desenvolvida e mantida pela comunidade de código aberto. Ele fornece uma alternativa mais rápida e simples ao git filter-branch
para remover dados não desejados.
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 relacionado no passwords.txt
sempre que ele for encontrado 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 Enterprise Server.
$ git push --force
Consulte as instruções completas de download e uso na documentação do BFG Repo-Cleaner.
Usando arquivo git filter-repo
Aviso: se você executar git filter-repo
após acumular as alterações, você não poderá recuperar suas alterações com outros comandos acumulados. Antes de executar git filter-repo
, recomendamos cancelar a acumulação de todas as alterações que você fez. Para desfazer o stash do último conjunto de alterações no qual você fez stash, execute git stash show -p | git apply -R
. Para obter mais informações, consulte Ferramentas do Git - Acúmulo e limpeza.
Para ilustrar como git filter-repo
funciona, mostraremos como remover seu arquivo com dados confidenciais do histórico do repositório e adicioná-lo a . itignore
para garantir que não se faça o commit novamente de forma acindelal.
-
Instale a versão mais recente da ferramenta git filter-repo. Você pode instalar
git-filter-repo
manualmente ou usando um gerenciador de pacotes. Por exemplo, para instalar a ferramenta com o HomeBrew, use o comandobrew install
.brew install git-filter-repo
Para obter mais informações, consulte INSTALL.md no repositório
newren/git-filter-repo
. -
Se você ainda não tiver uma cópia local do repositório com dados confidenciais no histórico, faça um clone do 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.
-
Acesse o diretório de trabalho do repositório.
$ cd YOUR-REPOSITORY
-
Execute o seguinte comando substituindo
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
pelo caminho do arquivo que deseja remover, não apenas o nome do arquivo. Esses argumentos vão:- Forçar o Git a processar, mas não fazer checkout, do histórico completo de cada branch e tag
- Remover o arquivo especificado, bem como qualquer commit vazio gerado como resultado
- Remova algumas configurações, como a URL remota, armazenada no arquivo .git/config. Você deverá fazer backup deste arquivo com antecedência para a restauração mais adiante.
- Sobrescrever as tags 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. Contando objetos: 100% (210/210), concluído. 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 dados confidenciais existir em qualquer outro caminho (porque foi movido ou renomeado), execute esse comando nesses caminhos também.
-
Adicione o arquivo com dados confidenciais ao
.gitignore
para impedir a repetição acidental do commit.$ 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(-)
-
Verifique se você removeu todo o conteúdo desejado do histórico do repositório e fez checkout de todos os branches.
-
Quando estiver satisfeito com o estado do repositório, force o push das alterações locais para sobrescrever o repositório do GitHub Enterprise Server e todos os branches presentes no push:
$ 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)
-
Para remover o arquivo com dados confidenciais das versões com tag, você também precisará forçar o push das tags 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)
Fully removing the data from GitHub
After using either the BFG tool or git filter-repo
to remove the sensitive data and pushing your changes to GitHub Enterprise Server, you must take a few more steps to fully remove the data from GitHub Enterprise Server.
-
Entre em contato com o your site administrator e solicite a remoção das visualizações em cache e das referências aos dados confidenciais em pull requests no GitHub Enterprise Server. Please provide the name of the repository and/or a link to the commit you need removed.
-
Peça para os colaboradores fazerem rebase, e não merge, nos branches criados a partir do histórico antigo do repositório. Um commit de merge poderia reintroduzir o histórico antigo completo (ou parte dele) que você acabou de se dar ao trabalho de corrigir.
-
After some time has passed and you're confident that the BFG tool /
git filter-repo
had no unintended side effects, you can force all objects in your local repository to be dereferenced and garbage collected with the following commands (using Git 1.8.5 or newer):$ 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: você também pode conseguir isso fazendo push do histórico filtrado em um repositório novo ou vazio e, em seguida, criando um clone usando o GitHub Enterprise Server.
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 e 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 .
egit commit -a
na linha de comando— usegit add filename
egit rm filename
para fazer stage de arquivos individuais. - Use o
git add --interactive
para revisar e fazer stage das alterações em cada arquivo de forma individual. - Use o
git diff --cached
para revisar as alterações que você incluiu no stage para commit. Esse é o diff exato que ogit commit
produzirá, contanto que você não use o sinalizador-a
.