Sim, é muito ruim, yada yada, mas por algum motivo eu preciso favorito.
James Morris
44
Eu sei que isso é estúpido, mas às vezes acontece uma merda - como testar logons e usar senhas de texto sem formatação no seu código, que são credenciais reais de login. E
opa
6
credenciais reais Login .. Sim me lembra de alguns whoopos
Estou tão cansado desse discurso acadêmico sobre como isso é perigoso e como nunca deve ser feito yada yada. Há momentos em que é muito melhor remover coisas da história do git e lidar com os conflitos / quebra de outros desenvolvedores. É realmente assim tão simples. As pessoas que ignoram isso provavelmente nunca trabalharam fora de uma sala de aula.
crush
Respostas:
369
Você é git reset --hardsua filial local para remover as alterações da árvore e índice de trabalho e git push --forcesua filial local revisada para o controle remoto. ( outra solução aqui , envolvendo excluir a ramificação remota e pressioná-la novamente)
Esta resposta do SO ilustra o perigo de um comando desse tipo, especialmente se as pessoas dependem do histórico remoto para seus próprios repositórios locais.
Você precisa estar preparado para apontar pessoas para a seção RECUPERANDO DO UPSTREAM REBASE da git rebasepágina de manual
Estranho. Parece que eu já tentei isso. Juntamente com algumas reformulações - funciona como um encanto. Obrigado.
Arnis Lapsa
7
@Arnis: perfeito então;) push --forceafastado
VonC
Usei o BFG Repo-Cleaner para me livrar de alguns dados confidenciais, que me deixaram com uma ramificação "sem nome" com o arquivo original, depois de redefinir para o último commit desejado e forçar a origem, tudo correu bem (:
Rodrirokr
Observe que o URL do commit ainda está ativo (pelo menos por algum tempo); portanto, se alguém tiver o URL do commit (você o deu a Deus sabe por que), ele poderá acessar o código.
Resposta perfeita, elegante e mais simples. Eu só revertido para a última stabe cometer eu precisava tanto na remota e localmente
lauWM
2
Isso me levou a perder minhas alterações locais também. Eu não estava esperando isso. Mas meh, melhor do que confirmar sua senha pessoal para repo trabalhar.
Airwavezx
3
você pode salvar suas alterações locais com git stash .... fazer algumas coisas .... e git pop esconderijo (suas alterações locais estão de volta)
Montea
Isso me dá um erro como "remote: error: negando referências / cabeças / master que não são de avanço rápido (você deve puxar primeiro)"
Saurabhcdt
@ Airwavezx é o que git reset --harddeveria fazer.
Luke
146
Importante: Certifique-se de especificar quais ramificações no "git push -f" ou modificar inadvertidamente outras ramificações![*]
Existem três opções mostradas neste tutorial . Caso o link seja quebrado, deixarei as etapas principais aqui.
Certifique-se de especificar quais ramificações em "git push <remote_repo> <remote_branch> -f" ou pode modificar inadvertidamente outras ramificações!
Nigel Sheridan-Smith
Somente as etapas 1 e 2 fizeram o trabalho e responderam à pergunta original. (Não execute a etapa 3)
Saad Benbouzid 11/03/16
Essas são opções para diferentes cenários, não etapas a serem seguidas. No meu caso, o rebase interativo (opção 3) fez o que eu estava procurando.
9788 Steve Jobswell
Eu tive que fazer o passo 3 embora. Por que você não deve executar este @Saad? Felizmente o meu << remoto >> era simplesmente o padrão 'origem' e <remote_branch> o padrão 'master'
Bart
30
Se você deseja excluir, por exemplo, as últimas 3confirmações, execute o seguinte comando para remover as alterações do sistema de arquivos (árvore de trabalho) e confirmar o histórico (índice) em sua filial local:
git reset --hard HEAD~3
Em seguida, execute o seguinte comando (na máquina local) para forçar a ramificação remota a reescrever seu histórico:
git push --force
Parabéns! Tudo feito!
Algumas notas:
Você pode recuperar o ID de confirmação desejado executando
git log
Então você pode substituir HEAD~Ncom <desired-commit-id>como esta:
git reset --hard <desired-commit-id>
Se você deseja manter as alterações no sistema de arquivos e apenas modificar o índice (histórico de consolidação), use --softsinalizador como git reset --soft HEAD~3. Então você tem a chance de verificar as alterações mais recentes e manter ou descartar todas ou parte delas. Neste último caso, runnig git statusmostra os arquivos alterados desde então <desired-commit-id>. Se você usar a --hardopção, git statusinformará que sua filial local é exatamente igual à remota. Se você não usar --hardnem --soft, o modo padrão será usado --mixed. Nesse modo,git help reset diz:
Redefine o índice, mas não a árvore de trabalho (ou seja, os arquivos alterados são preservados, mas não marcados para confirmação) e relata o que não foi atualizado.
Isso pode ser tarde demais, mas o que me ajudou é a opção "nuclear" que soa legal. Basicamente usando o comandofilter-branch você pode remover arquivos ou alterar algo em um grande número de arquivos ao longo de todo o seu histórico do git.
Não é tarde demais. Pode tornar-se útil para andarilhos com problemas semelhantes :)
Arnis Lapsa
9
Simplificando a partir da resposta do pctroll, similarmente com base nesta postagem do blog .
# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote
Funciona para mim, obrigado. E eu quero excluir permanentemente um commit (por exemplo, contém pwd) do histórico de filial remota, como fazer isso?
Smiles
1
Funciona para mim também, mas tenho a mesma pergunta que o Smiles, não quero que ninguém veja meu commit / rever na história .. como removo isso?
Roberto Rodriguez
4
Às vezes, a maneira mais fácil de corrigir esse problema é criar uma nova ramificação no local em que você sabe que o código é bom. Em seguida, você pode deixar o histórico de ramificação incorreto sozinho, caso precise escolher outros commits posteriormente. Isso também garante que você não perdeu nenhum histórico de consolidação.
Do seu ramo local errante:
git log
copie o hash de confirmação em que você deseja que o ramo esteja e saia do log git
Agora você tem um novo ramo do jeito que você deseja.
Se você também precisou manter um commit específico da ramificação incorreta que não está em sua nova ramificação, basta escolher a submissão específica de que precisa:
git checkout the_errant_branch
git log
Copie o hash de confirmação do que você precisa para entrar na ramificação válida e sair do log do git.
Respostas:
Você é
git reset --hard
sua filial local para remover as alterações da árvore e índice de trabalho egit push --force
sua filial local revisada para o controle remoto. ( outra solução aqui , envolvendo excluir a ramificação remota e pressioná-la novamente)Esta resposta do SO ilustra o perigo de um comando desse tipo, especialmente se as pessoas dependem do histórico remoto para seus próprios repositórios locais.
Você precisa estar preparado para apontar pessoas para a seção RECUPERANDO DO UPSTREAM REBASE da
git rebase
página de manualCom o Git 2.23 (agosto de 2019, nove anos depois), você usaria o novo comando
git switch
.Ou seja: (substitua
git switch -C mybranch origin/mybranch~n
n
pelo número de confirmações para remover)Isso restaurará o índice e a árvore de trabalho, como
git reset --hard
faria.fonte
push --force
afastadogit gc
nem sempre é executado o suficiente no lado remoto. Por exemplo, no GitHub: twitter.com/githubhelp/status/387926738161774592?lang=esApenas observe que
last_working_commit_id
, ao reverter um commit não ativoPortanto, não devemos redefinir para o
commit_id
que não queremos.Então, com certeza, devemos enviar para o ramo remoto:
fonte
git reset --hard
deveria fazer.Importante: Certifique-se de especificar quais ramificações no "git push -f" ou modificar inadvertidamente outras ramificações![*]
Existem três opções mostradas neste tutorial . Caso o link seja quebrado, deixarei as etapas principais aqui.
1 Reverta a consolidação completa
2 Exclua o último commit
ou, se a filial estiver disponível localmente
onde + dd61 ... é o seu commit hash e git interpreta x ^ como o pai de x e + como um push forçado não-rápido.
3 Exclua a confirmação de uma lista
Isso abrirá e o editor exibirá uma lista de todas as confirmações. Exclua o que você deseja se livrar. Conclua a rebase e pressione a força para repo.
fonte
Se você deseja excluir, por exemplo, as últimas
3
confirmações, execute o seguinte comando para remover as alterações do sistema de arquivos (árvore de trabalho) e confirmar o histórico (índice) em sua filial local:Em seguida, execute o seguinte comando (na máquina local) para forçar a ramificação remota a reescrever seu histórico:
Parabéns! Tudo feito!
Algumas notas:
Você pode recuperar o ID de confirmação desejado executando
Então você pode substituir
HEAD~N
com<desired-commit-id>
como esta:Se você deseja manter as alterações no sistema de arquivos e apenas modificar o índice (histórico de consolidação), use
--soft
sinalizador comogit reset --soft HEAD~3
. Então você tem a chance de verificar as alterações mais recentes e manter ou descartar todas ou parte delas. Neste último caso, runniggit status
mostra os arquivos alterados desde então<desired-commit-id>
. Se você usar a--hard
opção,git status
informará que sua filial local é exatamente igual à remota. Se você não usar--hard
nem--soft
, o modo padrão será usado--mixed
. Nesse modo,git help reset
diz:fonte
Isso pode ser tarde demais, mas o que me ajudou é a opção "nuclear" que soa legal. Basicamente usando o comando
filter-branch
você pode remover arquivos ou alterar algo em um grande número de arquivos ao longo de todo o seu histórico do git.É melhor explicado aqui .
fonte
Simplificando a partir da resposta do pctroll, similarmente com base nesta postagem do blog .
fonte
Às vezes, a maneira mais fácil de corrigir esse problema é criar uma nova ramificação no local em que você sabe que o código é bom. Em seguida, você pode deixar o histórico de ramificação incorreto sozinho, caso precise escolher outros commits posteriormente. Isso também garante que você não perdeu nenhum histórico de consolidação.
Do seu ramo local errante:
copie o hash de confirmação em que você deseja que o ramo esteja e saia do log git
Agora você tem um novo ramo do jeito que você deseja.
Se você também precisou manter um commit específico da ramificação incorreta que não está em sua nova ramificação, basta escolher a submissão específica de que precisa:
Copie o hash de confirmação do que você precisa para entrar na ramificação válida e sair do log do git.
Dê um tapinha nas costas.
fonte
fonte