Como posso desfazer um `git commit` localmente e em um controle remoto após o` git push`

242

Eu executei git commitseguido de a git push. Como posso reverter essa alteração nos repositórios local e remoto?

$ git log
commit 364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8
Author: Michael Silver <Michael [email protected]>
Date:   Tue Jun 11 12:24:23 2011 -0700
Michael
fonte

Respostas:

400
git reset --hard HEAD~1
git push -f <remote> <branch>

(Exemplo empurrar: git push -f origin bugfix/bug123)

Isso desfará a última confirmação e enviará o histórico atualizado para o controle remoto. Você precisa passar -fporque está substituindo o histórico upstream no controle remoto.

Alexander Groß
fonte
24
Como alternativa, use git reset --hard <the-sha-you-want-to-return-to>.
Alexander Groß
2
A referência é chamado CABEÇA (case sensitive)
dunni
26
Além disso, tenha cuidado - AFAIK você não deve fazer isso se outras pessoas tiverem retirado o repositório.
Amadan 15/08/13
1
@BipinVayalu Afeta o ramo em que você está atualmente. Mais precisamente, a cabeça. O HEAD geralmente é "anexado" a uma ramificação (apontando para um nome de ramificação em vez de apontar diretamente para uma confirmação). Então, de um modo geral, afetará o ramo apontado pelo HEAD. Use git log --decorate --onelinepara descobrir para onde seu HEAD aponta.
Alexander Groß
4
git reset HEAD~1se você não deseja que suas alterações ocorram (alterações sem estágio). Mudança, cometer e empurrar novamentegit push -f [origin] [branch]
softvar
161

Geralmente, faça um commit "inverso", usando:

git revert 364705c

em seguida, envie-o para o controle remoto, como de costume:

git push

Isso não excluirá o commit: ele cria um commit adicional que desfaz o que o primeiro commit fez. Qualquer outra coisa, não é realmente segura, especialmente quando as alterações já foram propagadas.

Amadan
fonte
9
Esta é uma resposta mais segura (portanto provavelmente melhor) do que a de Alexander Groß (a resposta escolhida).
Graeck 13/09
6
@Graeck Cada uma das soluções tem suas implicações e méritos.
Alexander Groß
5
Essa deve ser a resposta aceita, é uma prática recomendada nunca substituir o histórico, ainda mais se estiver colaborando com uma equipe. git resetserá aceito apenas se você ainda não tiver enviado as alterações ao servidor.
Josue Alexander Ibarra
17
@JosueIbarra Não concordo em todos os casos. Na maioria dos casos, sim, você não deve substituir o histórico. No entanto, acredito que há casos legítimos em que você absolutamente deveria. Por exemplo, você acidentalmente confirma e envia seu arquivo de segredos. Isso não deveria estar no repositório git. Portanto, você pode removê-lo rapidamente usando a resposta aceita aqui.
bfcoder
11
@bfcoder se você colocou um "segredo" em um repositório remoto, ele não é mais um segredo. E a solução correta é criar um novo segredo, não tentar esconder seu erro.
Erbsman
41

Primeiro de tudo, relaxe.

"Nada está sob nosso controle. Nosso controle é mera ilusão.", "Errar é humano"

Eu entendo que você acidentalmente empurrou seu código para remote-master. Isso vai ficar bem.

1. Primeiro, obtenha o SHA-1valor do commit que você está tentando retornar, por exemplo, commit no branch master. Rode isto:

git log

você verá várias seqüências de caracteres como 'f650a9e398ad9ca606b25513bd4af9fe ...' juntamente com cada um dos commits. copie esse número do commit que você deseja retornar .

2. Agora, digite o comando abaixo:

git reset --hard your_that_copied_string_but_without_quote_mark

você verá a mensagem "HEAD is now at". você está claro. O que acabou de fazer é refletir essa mudança localmente.

3. Agora, digite o comando abaixo:

git push -f

você deveria ver como

"aviso: push.default está desativado; seu valor implícito foi alterado em ..... ... Total 0 (delta 0), reutilizado 0 (delta 0) ... ... your_branch_name -> master (atualização forçada) . "

Agora, você está claro. Verifique o mestre com "git log" novamente, seu Fixed_destination_commit deve estar no topo da lista.

Você é bem-vindo (com antecedência;))

ATUALIZAR:

Agora, as alterações que você fez antes de tudo começar agora se foram. Se você quiser devolver esses trabalhos, é possível. Graças aos comandos git reflog e git cherry-pick .

Para isso, sugiro que você siga este blog ou este post .

kmonsoor
fonte
é uma boa medida para especificar o controle remoto e o ramo também quando fazendo "-f git push", mas "git push -f" irá funcionar de qualquer maneira na maioria das vezes
Robson
8

git reset HEAD~1se você não quiser que suas alterações ocorram (alterações sem estágio). Alterar, confirmar e pressionar novamentegit push -f [origin] [branch]

softvar
fonte
3

Você pode fazer uma nova análise interativa:

git rebase -i <commit>

Isso exibirá seu editor padrão. Apenas exclua a linha que contém o commit que você deseja remover para excluir esse commit.

Obviamente, você também precisará acessar o repositório remoto para aplicar essa alteração.

Veja esta pergunta: Git: removendo confirmações selecionadas do repositório

Jack Edmonds
fonte
3

Tente usar

git reset --hard <commit id> 

Observação: aqui o commit id será o id do commit que você deseja acessar, mas não o id que deseja redefinir. este foi o único ponto em que eu também fui preso.

então empurre

git push -f <remote> <branch>
Mohit Dhawan
fonte
2

Alternativamente:

git push origin +364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8^:master

Forçar a ramificação principal do repositório remoto de origem para o pai da última confirmação

MicRum
fonte