reverter - revert git reset head 1




Como posso desfazer o git reset--hard HEAD ~ 1? (10)

Na maioria dos casos, sim.

Dependendo do estado em que seu repositório estava quando você executou o comando, os efeitos do git reset --hard podem variar de trivial a desfazer, a basicamente impossível.

Abaixo, listei uma variedade de diferentes cenários possíveis e como você pode se recuperar deles.

Todas as minhas alterações foram confirmadas, mas agora as confirmações acabaram!

Essa situação geralmente ocorre quando você executa o git reset com um argumento, como no git reset --hard HEAD~ . Não se preocupe, é fácil recuperar isso!

Se você acabou de rodar o git reset e não fez mais nada desde então, pode voltar para onde estava com este recurso:

git reset --hard @{1}

Isso redefine sua ramificação atual em qualquer estado em que se encontrava antes da última vez em que foi modificada (no seu caso, a modificação mais recente na ramificação seria a redefinição definitiva que você está tentando desfazer).

Se, no entanto, você tiver feito outras modificações em sua ramificação desde a redefinição, o one-liner acima não funcionará. Em vez disso, você deve executar o git reflog <branchname> para ver uma lista de todas as alterações recentes feitas em sua ramificação (incluindo redefinições). Essa lista será mais ou menos assim:

7c169bd [email protected]{0}: reset: moving to HEAD~
3ae5027 [email protected]{1}: commit: Changed file2
7c169bd [email protected]{2}: commit: Some change
5eb37ca [email protected]{3}: commit (initial): Initial commit

Encontre a operação nesta lista que deseja "desfazer". No exemplo acima, seria a primeira linha, a que diz "redefinir: movendo para HEAD ~". Em seguida, copie a representação da confirmação antes (abaixo) dessa operação. No nosso caso, isso seria [email protected]{1} (ou 3ae5027 , ambos representam o mesmo commit) e execute git reset --hard <commit> para redefinir sua ramificação atual de volta para esse commit.

Organizei minhas alterações com o git add , mas nunca fiz o commit. Agora minhas mudanças se foram!

Isso é um pouco mais difícil de recuperar. O git tem cópias dos arquivos que você adicionou, mas como essas cópias nunca foram vinculadas a nenhum commit específico, você não pode restaurar as alterações de uma só vez. Em vez disso, você precisa localizar os arquivos individuais no banco de dados do git e restaurá-los manualmente. Você pode fazer isso usando o git fsck .

Para obter detalhes sobre isso, consulte Desfazer git reset --hard com arquivos não confirmados na área de preparação .

Tive alterações nos arquivos do meu diretório de trabalho que nunca fiz com o git add e nunca cometei. Agora minhas mudanças se foram!

Ah, oh. Eu odeio te dizer isso, mas você provavelmente está sem sorte. O git não armazena alterações que você não adiciona ou confirma, e de acordo com a documentação para git reset :

--Difícil

Redefine o índice e a árvore de trabalho. Quaisquer alterações nos arquivos rastreados na árvore de trabalho desde que <commit> sejam descartadas.

É possível que você consiga recuperar suas alterações com algum tipo de utilitário de recuperação de disco ou com um serviço profissional de recuperação de dados, mas neste momento isso provavelmente é mais problemático do que vale a pena.

É possível desfazer as alterações causadas pelo seguinte comando? Se sim, como?

git reset --hard HEAD~1

Exemplo de caso de IRL:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <[email protected]>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.

A resposta está oculta na resposta detalhada acima, você pode simplesmente fazer:

$> git reset --hard [email protected]{1}

(Veja a saída do git reflog show )



Criou um script minúsculo para facilitar a localização do commit que você está procurando:

git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'

Sim, pode ser consideravelmente mais bonito com awk ou algo parecido, mas é simples e eu só precisava. Pode salvar alguém mais 30 segundos.


O que você deseja fazer é especificar o sha1 da confirmação para a qual você deseja restaurar. Você pode obter o sha1 examinando o reflog ( git reflog ) e fazendo

git reset --hard <sha1 of desired commit>

Mas não espere muito ... depois de algumas semanas, o git acabará vendo esse commit como não referenciado e excluirá todos os blobs.


Se você ainda não coletou lixo no seu repositório (por exemplo, usando git repack -d ou git gc , mas observe que a coleta de lixo também pode ocorrer automaticamente), seu commit ainda está lá - ele não está mais acessível através do HEAD.

Você pode tentar encontrar seu commit procurando na saída do git fsck --lost-found .

As versões mais recentes do Git têm algo chamado "reflog", que é um log de todas as alterações feitas nas refs (em oposição às alterações feitas no conteúdo do repositório). Então, por exemplo, toda vez que você alternar seu HEAD (ou seja, toda vez que você fizer um git checkout para alternar ramificações), isso será registrado. E, é claro, o seu git reset também manipulou o HEAD, por isso também foi registrado. Você pode acessar estados mais antigos de suas referências de maneira semelhante ao acesso a estados mais antigos de seu repositório, usando um sinal @ vez de um ~ , como git reset [email protected]{1} .

Demorei um pouco para entender qual a diferença entre HEAD @ {1} e HEAD ~ 1, então aqui está uma pequena explicação:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show [email protected]{1} # => Three
git reflog

Portanto, HEAD~1 significa "ir para o commit antes do commit que HEAD atualmente aponta", enquanto [email protected]{1} significa "ir para o commit que HEAD apontou antes de apontar para onde aponta atualmente".

Isso permitirá que você encontre com facilidade o seu commit perdido e o recupere.


Se você estiver usando um JetBrains IDE (qualquer coisa baseada no IntelliJ), poderá recuperar até suas alterações não confirmadas através do recurso "Histórico local".

Clique com o botão direito do mouse no diretório de nível superior da árvore de arquivos, encontre "Local History" no menu de contexto e escolha "Show History". Isso abrirá uma visualização onde suas edições recentes podem ser encontradas e, depois de encontrar a revisão para a qual você deseja voltar, clique com o botão direito do mouse e clique em "Reverter".


Sei que esse é um tópico antigo ... mas, como muitas pessoas estão procurando maneiras de desfazer coisas no Git, ainda acho que pode ser uma boa ideia continuar dando dicas aqui.

Quando você faz um "git add" ou move qualquer coisa do canto superior esquerdo para o canto inferior esquerdo no guit do git, o conteúdo do arquivo é armazenado em um blob e é possível recuperar o conteúdo do arquivo.

Portanto, é possível recuperar um arquivo, mesmo que não tenha sido confirmado, mas tenha que ter sido adicionado.

git init  
echo hello >> test.txt  
git add test.txt  

Agora, o blob é criado, mas é referenciado pelo índice, portanto não será listado com o git fsck até que seja redefinida. Então, redefinimos ...

git reset --hard  
git fsck  

você receberá um blob pendente ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

retornará o conteúdo do arquivo "olá" de volta

Para encontrar commits não referenciados, encontrei uma dica em algum lugar sugerindo isso.

gitk --all $(git log -g --pretty=format:%h)  

Eu o tenho como uma ferramenta no git gui e é muito útil.


até onde eu sei, --hard descartará alterações não confirmadas. Como esses não são rastreados pelo git. mas você pode desfazer o discarded commit .

$ git reflog

lista:

b0d059c [email protected]{0}: reset: moving to HEAD~1
4bac331 [email protected]{1}: commit: added level introduction....
....

onde 4bac331 é o discarded commit .

Agora basta mover a cabeça para esse commit:

$ git reset --hard 4bac331




git-reset