Recuperar do git reset --hard?

457

Existe alguma maneira de recuperar alterações não confirmadas no diretório de trabalho de um diretório git reset --hard HEAD?

Jacob Lyles
fonte
49
Eu recomendo desaprender git reset. Você não precisa desse comando e é perigoso, portanto, não o use. Para retornar a ramificação para a confirmação anterior git rebase -ie soltar as confirmações que você não deseja ou git checkout(desanexa a cabeça), seguida por git branch -Mpara mover a ponta da ramificação. O primeiro se recusará a executar com alterações locais e o posterior somente será executado se os arquivos modificados localmente não diferirem entre as revisões.
Jan Hudec
11
@ Jan Eu não acredito nisso. Existem razões perfeitamente legítimas para usar a redefinição.
spaaarky21
4
@ spaaarky21: Sim, existem. Mas git reset --hard somewhereé um dos poucos comandos git realmente perigosos.
Jan Hudec
5
@ Jan, eu concordo, mas ser perigoso não significa que você não deve usá-lo. Apenas saiba o que está fazendo e tenha cuidado. :)
spaaarky21
3
Não está relacionado a Desfazer uma redefinição do git --hard HEAD ~ 1 , porque aqui o pôster original está tentando recuperar alterações não confirmadas.

Respostas:

475

Você não pode receber alterações não confirmadas em geral.

As alterações preparadas anteriormente ( git add) devem ser recuperáveis ​​dos objetos de índice; portanto, se você o fez, use git fsck --lost-foundpara localizar os objetos relacionados a ele. (Isso grava os objetos no .git/lost-found/diretório; de lá você pode usar git show <filename>para ver o conteúdo de cada arquivo.)

Caso contrário, a resposta aqui seria: olhe para o seu backup. Talvez o seu editor / IDE armazene cópias temporárias em / tmp ou C: \ TEMP e coisas assim. [1]

git reset HEAD@{1}

Isso restaurará para o HEAD anterior

[1] vim, por exemplo, opcionalmente armazena desfazer persistente, o eclipse IDE armazena o histórico local ; esses recursos podem salvar seu a **

ver
fonte
18
Histórico local do Eclipse - e, além disso, como algumas alterações tinham mais de 6 dias, meu backup do Time Machine do histórico local do Eclipse! Por alguma razão, o backup do Time Machine da pasta gerenciada pelo git não contém minhas alterações anteriores.
christianbrodbeck
2
Você é um salva-vidas sério na dica! O TextWrangler tinha um backup de arquivos. Obrigado
Vivek Sampara
6
O IDE (IntelliJ) armazenou as alterações localmente, o que salvou o dia. Obrigado pela dica!
progonkpa
1
Uau isso é incrível. Funciona mesmo se você nunca fez um commit.
Boudewijn Aasman
2
De fato, a história local no Eclipse (Intellij no meu caso) salva meu dia na recuperação de alterações não-estratificadas, doc aqui para Intellij: blog.jetbrains.com/idea/2008/01/…
Richard
449

responder a partir deste SO

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Você conseguiu seu dia de volta! :)

ken
fonte
24
Só para adicionar essa resposta, isso ajudaria as pessoas que realmente haviam cometido alterações que foram descartadas por meio de redefinição física.
murki
9
Ótimo - mas, no meu caso, os arquivos sumiram completamente. Usar git checkout HEAD@{19}me permitiu verificar os arquivos perdidos em um estado desanexado. Em seguida, é usado git checkout -b new-branch-namepara adicioná-los novamente ao repositório no estado "anexado".
NightOwl888
@ NightOwl888: Git novato aqui e eu tive o mesmo problema que meus arquivos ainda estavam perdidos. Você poderia explicar com mais detalhes como recuperou seus arquivos em um estado "anexado" (ou poderia explicar o que isso realmente significa)? Muito obrigado!
precisa saber é o seguinte
3
@ user3385759 - No Git, quando você usa o comando checkout em qualquer coisa que não seja uma ramificação, ele entra em um modo especial "desanexado". Isso significa que você não está realmente apontando para uma filial, mas pode ver o que foi registrado no estado da entidade (neste caso, uma entrada de reflog). A partir desse estado, você pode transformá-lo em uma ramificação "real" para a qual você pode voltar usando novamente git checkout -b new-branch-name. O livro Controle Pragmático de Versão Usando Git é bom em explicar o Git em termos simples.
precisa
2
Sim, o que NomNomCameron e Jesse Adelman disseram. Eu pensei erroneamente que a redefinição seria redefinida para meu último commit. Não. Isso acabou com tudo. Essa resposta me salvou de um dia ou dois de recriar meu trabalho.
VeteranCoder
308

Eu acidentalmente corri git reset --hardno meu repositório hoje também, tendo alterações não confirmadas também hoje. Para recuperá-lo, corri git fsck --lost-found, que escreveu todos os blobs não referenciados <path to repo>/.git/lost-found/. Como os arquivos não foram confirmados, eu os encontrei no otherdiretório dentro do <path to repo>/.git/lost-found/. A partir daí, posso ver os arquivos não confirmados usandogit show <filename> , copiar os blobs e renomeá-los.

Nota: Isso funciona apenas se você adicionou os arquivos que deseja salvar no índice (usando git add .). Se os arquivos não estavam no índice, eles são perdidos.

Justin
fonte
4
Eu tenho apenas arquivos com referências de confirmação no lost-found. Mas eu poderia fazer git showpara obter o conteúdo.
Mitar
6
Só para economizar tempo ninguém#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
rwolst
209

Sim, você pode se recuperar de uma reinicialização total no git.

Usar:

git reflog

para obter o identificador do seu commit. Então use:

git reset --hard <commit-id-retrieved-using-reflog>

Esse truque salvou minha vida algumas vezes.

Você pode encontrar a documentação do reflog AQUI .

Gabe
fonte
9
Até agora, acho que essa é a resposta melhor e mais concisa. Pode parecer contra-intuitivo se recuperar do git reset --harduso de outro, git reset --hardmas se você não usar a --hardopção, você ficará com entradas no seu espaço de trabalho que reverteriam efetivamente o trabalho que você acabou de recuperar.
Ryan H.
2
Funciona como um encanto! A resposta anterior ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/… ) não funcionou para mim.
codemax
3
Esta resposta não está correta. Essa abordagem recupera apenas alterações confirmadas anteriormente . Não será capaz de restaurar alterações não confirmadas (que é essa a questão).
Alderath 21/05/19
2
Esta solução funciona para mim. Fiz uma reinicialização completa e, quando uso git log, não vi o ID do commit. Com git reflogeu podia ver o ID comprometer
dboscanv
2
isso funciona para mim. obrigado!!!!!!
RedEyed 22/01
60

Enquanto trabalhava em um projeto local, quis movê-lo para o GitHub e, em seguida, criei um novo repositório. Enquanto tentava adicionar todos esses arquivos ao novo repositório com .gitignore, acidentalmente adicionei um arquivo errado e tentei limpá-lo.

Eu corri git reset --hard origin/master: P

Todos os meus arquivos locais foram excluídos porque o repositório estava vazio. Eu pensei que tudo tinha acabado.

Isso salvou minha vida:

git reflog show
git reset HEAD@{1} 
git push 

Espero que salve outra vida.

Orcun
fonte
Para mim foi git reset HEAD@\{27\} , obrigado!
4oby
1
Eu tenho 7 compromete a repor, eu uso git reflog showpara verificar e desde aquele primeiro cometer eu usogit reset HEAD@{number}
Vishwas Nahar
38

Se você usa algo como IntelliJ:

No menu de contexto, escolha Histórico local e clique em Mostrar histórico no submenu:

A exibição do histórico local de um projeto ou pasta mostra tudo o que você fez nos últimos dias. Na coluna Ação da parte inferior da caixa de diálogo, selecione a ação que você deseja reverter. [...] Assim, a parte superior da caixa de diálogo mostra a visualização em árvore dos arquivos alterados. Se você deseja restaurar apenas o arquivo excluído, independentemente das outras alterações realizadas desde então, é possível selecionar o arquivo Lost.txt na visualização em árvore e clicar no botão Reverter.

http://blog.jetbrains.com/idea/2008/01/using-local-history-to-restore-deleted-files/

Isso acabou com minha bunda do fogo!

JonathanTien
fonte
Essa é de longe a melhor resposta para os usuários do IntelliJ! Muito obrigado, isso funcionou perfeitamente. Tentei todas as outras soluções e nenhuma delas funcionou bem. git reflognão funcionou porque não fiz as alterações. git fsck --lost-foundtrabalhou para arquivos em etapas, mas nem todas elas foram em etapas. O histórico local do IntelliJ recuperou perfeitamente meus arquivos não salvos, estou muito agradecido por esse recurso
Denes Papp
30

Acabei de fazer git reset --harde perdi todas as minhas alterações não confirmadas. Felizmente, eu uso um editor (IntelliJ) e consegui recuperar as alterações do Histórico local. O Eclipse deve permitir que você faça o mesmo.

user1147827
fonte
20

Por definição, git reset --harddescartará alterações não confirmadas sem que o Git possa recuperá-las (seu sistema de backup pode ajudar, mas não o Git).

Na verdade, existem muito poucos casos em que git reset --hardé uma boa ideia. Na maioria dos casos, há um comando mais seguro para fazer a mesma coisa:

  • Se você quiser jogar fora as alterações não confirmadas, use git stash. Ele manterá um backup dessas alterações, que expirarão após algum tempo, se você executar git gc. Se você tem 99,9% de certeza de que nunca precisará dessas alterações, git stashainda será seu amigo no caso de 0,1%. Se você tem 100% de certeza, git stashainda é seu amigo, porque esses 100% têm um erro de medição ;-).

  • Se você deseja mudar sua HEADe a ponta do ramo atual da história, então git reset --keepé seu amigo. Ele fará o mesmo git reset --hard, mas não descartará as alterações locais.

  • Se você quer fazer as duas coisas, então git stash && git reset --keepé seu amigo.

Ensine seus dedos a não usar git reset --hard, ele pagará um dia.

Matthieu Moy
fonte
então, se alguém fizer git stash && git reset --hardisso, acabaria com qualquer conteúdo oculto, certo?
jxramos
1
Não, git reset --hardnão descarta o estoque. git stashé um substituto git reset --hardno sentido em que remove alterações não confirmadas da sua árvore de trabalho, exceto que as mantém em segurança em vez de descartá-las permanentemente.
Matthieu Moy 9/10
ou apenas confirmar as alterações antes de hard reset e eles ainda estarão em seu repo locais
ThaJay
11

se você acidentalmente redefinir uma confirmação, faça isso,

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

assumindo HEAD@{2}é o estado que você deseja voltar para

Edwin Ikechukwu Okonkwo
fonte
isso funcionou perfeito para mim se você fizer isso no PowerShell, certifique-se de escrevê-lo como esta redefinição git 'HEAD @ {2}', caso contrário não funcionará no powershell
VectorX
10

É o que eu costumo fazer se perder algumas alterações.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

para mover o ponteiro de volta para as confirmações anteriores, mas mantendo as alterações feitas até o momento em sua última confirmação de confirmação git reset --soft dadada

Cavaleiro Dragão
fonte
8

A informação está perdida.

Como você não confirmou, seu .git nunca armazenou essas informações. Então, basicamente, gitnão é possível recuperá-lo para você.

Mas, se você acabou de fazer git diff, há uma maneira de se recuperar usando a saída do terminal com as 3 etapas simples a seguir.

  1. role seu terminal e procure o o / p de git diff. Salve o / p em um arquivo chamado diff.patch
  2. Pesquise e substitua todos os 7 espaços e 8 espaços pelo caractere de tabulação (\ t) e salve as alterações.
  3. Entre no seu repositório git. Aplique o diff.patch ( patch -p1 < diff.patch)

Você está salvo! :)

Nota: Enquanto estiver copiando os dados do terminal para um arquivo, tenha cuidado e veja claramente que os dados são de saída contínua e não continham dados redundantes (devido ao pressionamento das setas para cima e para baixo). Caso contrário, você pode estragar tudo.

mk ..
fonte
7

Corri para o mesmo problema e estava quase enlouquecendo .... inicialmente comprometi o projeto e me fundi .. depois, quando tento executar, git push --set-upstream origin master estava recebendo esse erro

  fatal: refusing to merge unrelated histories

então eu corri git reset --hard HEADe excluí um projeto de 3 semanas, mas esses poucos comandos abaixo salvam o dia:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

espero que isto ajude

Slycreator
fonte
6

Você pode recuperar um commit depois de fazer um reset --hard HEAD .

Utilize " git reflog" para verificar o histórico doHEAD na ramificação.

Você verá seu commit e seu ID aqui.

Faça um

git reset {commit Id of the commit you want to bring back}
rachana acharya
fonte
5

Se você teve os mesmos arquivos abertos em outro editor (por exemplo, Sublime Text), tente pressionar Ctrl-z. Apenas me salvou ..

Gabe
fonte
3

Eu descobri da maneira mais difícil que qualquer arquivo não confirmado antes de um git reset --hard <commit>é removido do histórico do git. No entanto, tive a sorte de ter mantido minha sessão do editor de código aberta durante todo o tempo em que estiquei os cabelos, e descobri que um simples control + zem cada um dos arquivos afetados retornava o estado do arquivo de volta à versão anterior ao Git. redefinir obrigatoriamente tudo o que não pedi especificamente.Hooray!!

Robô amigável
fonte
3

Se você está tentando usar o código abaixo:

git reflog show
# head to recover to
git reset HEAD@{1} 

e por algum motivo estão recebendo:

erro: interruptor desconhecido `e '

então tente colocar HEAD@{1}aspas

git reset 'HEAD@{1}'
Ferrugem
fonte
3
 git reset HEAD@{4}

4 é alterado antes de 4 etapas atrás. se você selecionar uma etapa correta, ela deverá mostrar a lista de arquivos que você removeu do disco. então faça:

$ git reflog show

mostrará o histórico de consolidação local que já criamos. agora faça:

$ git reset --hard 8c4d112

8c4d112 é um código que você deseja redefinir seu disco rígido lá. vamos ver https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history para obter mais informações.

mohammad
fonte
Muito obrigado @mohammad, me salvou. Não consegui ver meus arquivos de origem anteriormente, mas, seguindo as etapas acima, consegui recuperar todos os meus arquivos de origem.
Gaurav Bansal 25/01
2

Respostas corretas. OK, agora eu gosto de git. :-) Aqui está uma receita mais simples.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Onde "2" é o número de volta para onde você confirmou suas alterações. No meu caso, interrompido pelo colega e chefe para ajudar a depurar algum problema de compilação; assim, fez um reset - duas vezes difícil; portanto, HEAD e HEAD @ {1} foram substituídos. Uau, teria perdido um nosso trabalho duro.

TimJowers2
fonte
2

eu fiz git reset --hard no projeto errado por engano (eu sei ...). Eu tinha acabado de trabalhar em um arquivo e ele ainda estava aberto durante e depois de executar o comando.

Mesmo não tendo confirmado, consegui recuperar o arquivo antigo com o simples COMMAND + Z.

Daniel Segura
fonte
0

Resposta de referência deste SO,

Depois de executar o git reflog show, diga que deseja ir para o commit 9300f9d

depois de executar o git reset 9300f9d

você pode fazer o status git e, em seguida, pode precisar fazer check-out dos seus arquivos para restaurar suas alterações

git checkout - caminho do arquivo / nome

Daniel
fonte
0

Se você estiver desenvolvendo no Netbeans, procure entre as guias e a área de edição de arquivos. Há uma "Fonte" e "História". Em "Histórico", você verá as alterações feitas usando o controle de versão (git / other), mas também as alterações feitas localmente. Nesse caso, alterações locais podem salvar você.

Pedro Alvares
fonte
0

( resposta adequada para um subconjunto de usuários )

Se você estiver no macOS (recente), e mesmo longe do disco do Time Machine, o sistema operacional salvará backups de hora em hora, chamados instantâneos locais .

Digite Time Machine e navegue até o arquivo que você perdeu. O sistema operacional perguntará:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Você poderá recuperar os arquivos perdidos.

Calaf
fonte
0

Se você tinha um IDE aberto com o mesmo código, tente fazer um ctrl + z em cada arquivo individual no qual você fez alterações. Isso me ajudou a recuperar minhas alterações não confirmadas depois de fazer o git reset --hard.

dwarakesh tp
fonte
-3

Quando fazemos o git reset --hard e todas as alterações locais não confirmadas são excluídas. Para recuperar as alterações - no IDE, clique no arquivo, compare o arquivo com o Histórico local, que listará as alterações conforme a data e podemos recuperar os dados. Seu dia está salvo!

Roopa
fonte
1
Esta resposta repete duas anteriores.
Isherwood 20/08/19