Desfazer git pull, como trazer repositórios para o estado antigo

1006

Existe alguma maneira de reverter ou desfazer o git pull para que minhas fontes / repositórios cheguem ao estado antigo que era antes de executar o git pull? Eu quero fazer isso porque ele mesclou alguns arquivos que não queria, mas apenas mesclou outros arquivos restantes. Então, eu quero recuperar esses arquivos, isso é possível?

Edição: Eu quero desfazer git mesclar para esclarecimentos. Depois de ver algumas respostas, eu fiz isso

git reflog
bb3139b... HEAD@{0}: pull : Fast forward
01b34fa... HEAD@{1}: clone: from ...name...

Agora, o que devo fazer? Está tudo git reset --hard bem? Não quero estragar tudo de novo, pedindo etapas detalhadas?

seg.server.fault
fonte
23
Parece que você só tem duas coisas na sua história: um clone e uma busca. Basta redefinir o clone:, git reset --hard 01b34faneste caso, você poderia ter feito o git reset --hard HEAD^que redefine para um commit antes do HEAD.
Jkp 03/08/2009
2
--hard é necessário se você deseja modificar arquivos em seu diretório de trabalho
William Pursell
3
@ seg.server.fault: se funcionou, você sempre pode aceitar a resposta;)
jkp
7
git reset --hard HEAD ^
funroll 16/09
7
git reflogmostrará tudo o que foi feito com o git. Existe uma preocupação que git reset --hard [sha1 of something from reflog]reverterá tudo o que é mostrado reflog, que às vezes não é objetivo, por exemplo. você deseja reverter a mesclagem na ramificação principal extraída da origem com dados incorretos (acontece) e, depois disso, você trabalhou em outras ramificações. reflogmostrará todas as alterações em outros ramos. Mas git checkout mastere git reset --hard [SH1 of commit on master branch just before merge]redefinirá apenas a ramificação principal atual, removendo a mesclagem puxada da origem.
Vladimir Vukanac

Respostas:

1427

A execução git pullexecuta as seguintes tarefas, em ordem:

  1. git fetch
  2. git merge

A etapa de mesclagem combina ramificações que foram configuradas para serem mescladas na sua configuração. Você deseja desfazer a etapa de mesclagem , mas provavelmente não a busca (não faz muito sentido e não deve ser necessário).

Para desfazer a mesclagem , use git reset --hardpara redefinir o repositório local para um estado anterior; use git-reflog para encontrar o SHA-1 do estado anterior e, em seguida, redefinir para ele.

Atenção

Os comandos listados nesta seção removem todas as alterações não confirmadas, levando potencialmente a uma perda de trabalho:

git reset --hard

Como alternativa, redefina para um momento específico, como:

git reset --hard master@{"10 minutes ago"}
jkp
fonte
325
Uma excelente maneira de escolher o estado anterior, em vez de usar git-reflog e guisados copiadoras, é a utilização de um atalho como master@{1}, que é a posição anterior de master, master@{"5 minutes ago"}ou master@{14:30}. Detalhes completos sobre a especificação de revisões dessa maneira podem ser encontrados em man git-rev-parse, na seção chamada "especificação de revisões".
Cascabel
38
Neste caso ORIG_HEAD também deve trabalho ( "git reset ORIG_HEAD --hard")
Jakub Narębski
@ Jelfromi: obrigado por essa dica, eu não sabia que você poderia ser tão detalhado sobre as revisões. Eu sabia sobre escolher revisões em relação ao HEAD, mas quando a pergunta foi feita, eu não sabia há quanto tempo ele queria ir.
Jkp #
Quando eu puxei, diz Updating d2c90a3..035ac4d. Aqui, você também pode usar d2c90a3como parâmetro para redefinir.
Thai
Você não precisa digitar hashes quando usa reflog. Você também pode usar HEAD @ {1} ou qualquer número anterior, conforme definido no reflog.
Simon The Cat
338

O mesmo que a resposta do jkp, mas aqui está o comando completo:

git reset --hard a0d3fe6

onde a0d3fe6 é encontrado fazendo

git reflog

e olhando para o ponto em que você deseja desfazer.

Jeffrey Sun
fonte
Por que não posso simplesmente fazer git reset HEAD --hard, por exemplo?
Sung Cho
9
@MikeC Esta abordagem permite-lhe voltar várias puxa, por exemplo
XJI
2
Eu não era capaz de usar os IDs do lado esquerdo, mas git reset --hard HEAD@{n}funcionava #
E. Sundin
1
Você deveria ter sugerido uma edição da resposta do jkp em vez de quase replicá-la aqui depois de tantos anos.
Abhishek Anand
Se eu tiver isso em git reflog: dab04ec HEAD @ {0}, aaaaaaa HEAD @ {1} e bbbbbbb HEAD @ {2}. Se o fizer git reset --hard bbbbbbb, perderei o HEAD 0 e 1?
Pmiranda
115

Uma maneira mais moderna de desfazer uma mesclagem é:

git merge --abort

E a maneira um pouco mais antiga:

git reset --merge

A maneira antiga descrita nas respostas anteriores (aviso: descartará todas as alterações locais):

git reset --hard

Mas, na verdade, vale a pena notar que isso git merge --aborté apenas equivalente ao git reset --mergeque MERGE_HEADestá presente. Isso pode ser lido na ajuda do git para o comando mesclar.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

Após uma mesclagem com falha, quando não há MERGE_HEAD, a mesclagem com falha pode ser desfeita, git reset --mergemas não necessariamente com git merge --abort, portanto , elas não são apenas uma sintaxe antiga e nova para a mesma coisa . É por isso git reset --mergeque considero muito mais útil no trabalho diário.

Martin G
fonte
20
git merge --abortfunciona durante uma mesclagem, não após a git pullconclusão. Portanto, essa resposta parece irrelevante para a pergunta.
Abhishek Anand
1
git reset --mergeexclui todas as alterações não preparadas para confirmação. Descobri isso da maneira mais difícil.
theadriangreen 19/03
62

funciona primeiro uso: git reflog

encontre seu SHA do seu estado anterior e faça (HEAD @ {1} é um exemplo)

git reset --hard HEAD@{1}
Ezequiel García
fonte
40

Se você possui o gitk (tente executar "gitk --all a partir da linha de comando do git"), é simples. Basta executá-lo, selecione a confirmação para a qual você deseja reverter (clique com o botão direito do mouse) e selecione "Redefinir ramificação principal para aqui". Se você não tiver alterações não confirmadas, escolha a opção "hard".

Samuel Carrijo
fonte
8
Vale a pena correr se você ainda não viu. Aparece uma GUI louca.
Evan Moran
35

Suponha que $COMMITfoi o último ID de confirmação antes de você executar git pull. O que você precisa para desfazer a última atração é

git reset --hard $COMMIT

.

Bônus:

Ao falar de puxar, gostaria de compartilhar um truque interessante,

git pull --rebase

Este comando acima é o comando mais útil na minha vida git, que economizou muito tempo.

Antes de enviar o commit recentemente ao servidor, tente este comando e ele sincronizará automaticamente as alterações mais recentes do servidor (com uma busca + mesclagem) e colocará o commit no topo do log do git. Não precisa se preocupar com puxar / mesclar manualmente.

Encontre detalhes em: http://gitolite.com/git-pull--rebase

Sazzad Hissain Khan
fonte
17

Essa é a maneira mais fácil de reverter as alterações.

** Warning **

Faça backup dos seus arquivos alterados, pois eles excluirão os arquivos e pastas recém-criados .

git reset --hard 9573e3e0

Onde 9573e3e0está seu {ID de confirmação}

Manish Goswami
fonte
essa resposta é muito útil, porque se fizermos um ramo de origem git pull com algo parecido com isto Updating ffce65bd..e929e884, o façagit reset --hard ffce65bd
Ernesto Alfonso
15

você pode fazer git reset --hard ORIG_HEAD

já que "pull" ou "merge" definem ORIG_HEAD como o estado atual antes de executar essas ações.

Orlando
fonte
5

git pull do abaixo da operação.

Eu. git fetch

ii. git merge

Para desfazer o pull, execute qualquer operação:

Eu. git reset --hard --- reverter toda mudança local também

ou

ii. git reset --hard master@{5.days.ago} (como 10.minutes.ago, 1.hours.ago, 1.days.ago..) para obter mudanças locais.

ou

iii. git reset --hard commitid

Melhoria:

Da próxima vez que usar, em git pull --rebasevez de git pull... seu servidor de sincronização mudará executando (buscar e mesclar).

GolamMazid Sajib
fonte
4

Se houver uma falha na mesclagem, que é o motivo mais comum para querer desfazer uma git pull, a execução git reset --mergefaz exatamente o que seria de esperar: mantenha os arquivos buscados, mas desfaça a mesclagem que git pulltentou mesclar. Então, pode-se decidir o que fazer sem a desordem que git mergeàs vezes gera. E não é necessário encontrar o ID exato de confirmação --hardmencionado em todas as outras respostas.

Davide
fonte