Gostaria de colocar um projeto Git no GitHub, mas ele contém certos arquivos com dados confidenciais (nomes de usuário e senhas, como /config/deploy.rb para capistrano).
Eu sei que posso adicionar esses nomes de arquivo ao .gitignore , mas isso não removeria o histórico deles no Git.
Também não quero começar de novo excluindo o diretório /.git.
Existe uma maneira de remover todos os vestígios de um arquivo específico no seu histórico do Git?
Respostas:
Para todos os fins práticos, a primeira coisa com que você deve se preocupar é MUDAR SUAS SENHAS! Não está claro em sua pergunta se o seu repositório git é totalmente local ou se você possui um repositório remoto em outro lugar; se for remoto e não protegido por terceiros, você tem um problema. Se alguém clonou esse repositório antes de você consertar isso, eles terão uma cópia de suas senhas na máquina local e não há como você forçá-los a atualizar para a sua versão "fixa" com o histórico retirado. A única coisa segura que você pode fazer é alterar sua senha para outra em qualquer lugar em que você a tenha usado.
Com isso fora do caminho, veja como corrigi-lo. O GitHub respondeu exatamente a essa pergunta como uma FAQ :
Nota para usuários do Windows : use aspas duplas (") em vez de singles neste comando
Atualização 2019:
Este é o código atual da FAQ:
Lembre-se de que depois de enviar esse código para um repositório remoto como o GitHub e outros clonarem esse repositório remoto, você estará em uma situação em que está reescrevendo o histórico. Quando outras pessoas tentam retirar suas alterações mais recentes depois disso, elas receberão uma mensagem indicando que as alterações não podem ser aplicadas porque não é um avanço rápido.
Para corrigir isso, eles terão que excluir o repositório existente e cloná-lo novamente ou seguir as instruções em "RECUPERANDO DO UPSTREAM REBASE" na página de manual do git-rebase .
Dica : Executar
git rebase --interactive
No futuro, se você acidentalmente confirmar algumas alterações com informações confidenciais, mas perceber antes de enviar para um repositório remoto, existem algumas correções mais fáceis. Se você tiver confirmado por último a inclusão de informações confidenciais, basta remover as informações confidenciais e executar:
Isso alterará a confirmação anterior com as novas alterações feitas, incluindo remoções de arquivos inteiras feitas com a
git rm
. Se as alterações estiverem mais antigas, mas ainda não forem enviadas para um repositório remoto, você poderá fazer uma nova análise interativa:Isso abre um editor com os commit que você fez desde seu último ancestral comum com o repositório remoto. Altere "pick" para "edit" em qualquer linha que represente um commit com informações confidenciais e salve e saia. O Git analisará as alterações e o deixará em um local onde você pode:
Para cada alteração com informações confidenciais. Eventualmente, você retornará à sua filial e poderá enviar com segurança as novas alterações.
fonte
filter-branch
código e o da página do github ao qual você vinculou. Por exemplo, sua terceira linha--prune-empty --tag-name-filter cat -- --all
. A solução mudou ou estou faltando alguma coisa?<introduction-revision-sha1>..HEAD
não funcionará. Ele remove apenas o arquivo do segundo commit em diante. (Como faço para incluir o commit inicial no intervalo de commits?) A maneira de salvar é apontada aqui: help.github.com/articles/…git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \ --prune-empty --tag-name-filter cat -- --all
Alterar suas senhas é uma boa ideia, mas, para o processo de remoção de senhas do histórico de seu repositório, recomendo o BFG Repo-Cleaner , uma alternativa mais rápida e simples ao
git-filter-branch
projetado explicitamente para remover dados particulares dos repositórios Git.Crie um
private.txt
arquivo listando as senhas, etc, que você deseja remover (uma entrada por linha) e, em seguida, execute este comando:Todos os arquivos abaixo de um tamanho limite (1 MB por padrão) no histórico do seu repositório serão verificados e qualquer sequência correspondente (que não esteja no seu último commit) será substituída pela sequência "*** REMOVED ***" ". Você pode usar
git gc
para limpar os dados mortos:O BFG geralmente é 10 a 50 vezes mais rápido que a execução
git-filter-branch
e as opções são simplificadas e adaptadas a esses dois casos de uso comuns:Divulgação completa: sou o autor do BFG Repo-Cleaner.
fonte
git commit
. Caso contrário, uma nova ferramenta para a caixa de ferramentas do desenvolvedor :)These are your protected commits, and so their contents will NOT be altered
ao percorrer e revisar o restante do seu histórico de commit. Se você precisou reverter, no entanto, sim, seria necessário fazer uma pesquisa***REMOVED***
no commit para o qual acabou de reverter.Se você empurrou para o GitHub, forçar o envio não é suficiente, exclua o repositório ou entre em contato com o suporte
Mesmo se você forçar a pressão um segundo depois, não será suficiente, conforme explicado abaixo.
Os únicos cursos de ação válidos são:
é o que vazou uma credencial mutável como uma senha?
não (fotos nuas):
você se importa se todos os problemas no repositório forem resolvidos?
sim:
Forçar um segundo depois não é suficiente porque:
O GitHub continua comprometendo os commits por um longo tempo.
A equipe do GitHub tem o poder de excluir esses commit dangling se você entrar em contato com eles.
Eu experimentei isso em primeira mão quando carreguei todos os emails de confirmação do GitHub em um repositório que eles me pediram para removê-lo, então eu fiz e eles fizeram a
gc
. No entanto, as solicitações pull que contêm os dados precisam ser excluídas : esses dados de repo permaneceram acessíveis até um ano após a remoção inicial devido a isso.Os commits dangling podem ser vistos através de:
Uma maneira conveniente de obter a fonte nesse commit é usar o método zip de download, que pode aceitar qualquer referência, por exemplo: https://github.com/cirosantilli/myrepo/archive/SHA.zip
É possível buscar os SHAs ausentes por:
type": "PushEvent"
. Por exemplo, o meu: https://api.github.com/users/cirosantilli/events/public ( máquina Wayback )Existem scrappers como http://ghtorrent.org/ e https://www.githubarchive.org/ que agrupam regularmente os dados do GitHub e os armazenam em outros lugares.
Não consegui descobrir se eles rasparam o diff de confirmação real, e isso é improvável, porque haveria muitos dados, mas é tecnicamente possível, e a NSA e os amigos provavelmente têm filtros para arquivar apenas coisas vinculadas a pessoas ou comissões de interesse.
Se você excluir o repositório em vez de apenas forçar o envio, as confirmações desaparecem mesmo da API imediatamente e fornecem 404, por exemplo, https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 Isso funciona mesmo se você recriar outro repositório com o mesmo nome.
Para testar isso, criei um repositório: https://github.com/cirosantilli/test-dangling e fiz:
Veja também: Como remover um commit dangling do GitHub?
fonte
Eu recomendo este script de David Underhill, funcionou como um encanto para mim.
Ele adiciona esses comandos além do ramo de filtro do natacado para limpar a bagunça que deixa para trás:
Roteiro completo (todo o crédito a David Underhill)
Os dois últimos comandos podem funcionar melhor se forem alterados para o seguinte:
fonte
git gc --aggressive --prune=now
Para ser claro: a resposta aceita está correta. Experimente primeiro. No entanto, pode ser desnecessariamente complexo para alguns casos de uso, principalmente se você encontrar erros desagradáveis, como 'fatal: revisão ruim - poda vazia', ou realmente não se importa com o histórico do seu repo.
Uma alternativa seria:
Obviamente, isso removerá todas as ramificações do histórico de consolidação e os problemas do seu repositório github e do repositório git local. Se isso for inaceitável, você terá que usar uma abordagem alternativa.
Chame isso de opção nuclear.
fonte
Você pode usar
git forget-blob
.O uso é bem simples
git forget-blob file-to-forget
. Você pode obter mais informações aquihttps://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
Ele desaparecerá de todos os commits em seu histórico, reflog, tags e assim por diante
Eu sempre encontro o mesmo problema de vez em quando, e toda vez que tenho que voltar a este post e a outros, é por isso que automatizei o processo.
Créditos para colaboradores do Stack Overflow que me permitiram juntar isso
fonte
Aqui está a minha solução no Windows
verifique se o caminho está correto, caso contrário não funcionará
Espero que ajude
fonte
Use ramo de filtro :
fonte
Eu tive que fazer isso algumas vezes até hoje. Observe que isso funciona apenas em 1 arquivo por vez.
Obtenha uma lista de todas as confirmações que modificaram um arquivo. O da parte inferior será o primeiro commit:
git log --pretty=oneline --branches -- pathToFile
Para remover o arquivo do histórico, use o primeiro commit sha1 e o caminho para o arquivo do comando anterior e preencha-os neste comando:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
fonte
Então, parece algo como isto:
fonte
No meu projeto android, eu tinha admob_keys.xml como arquivo xml separado na pasta app / src / main / res / values / . Para remover esse arquivo sensível, usei o script abaixo e funcionei perfeitamente.
fonte