Récupérer de git reset --hard?

457

Existe-t-il un moyen de récupérer les modifications non validées du répertoire de travail à partir d'un git reset --hard HEAD?

Jacob Lyles
la source
49
Je recommanderais de désapprendre git reset. Vous n'avez pas besoin de cette commande et c'est dangereux, alors ne l'utilisez pas. Pour ramener la branche au commit précédent git rebase -i, supprimez les commits que vous ne voulez pas ou git checkout(détache la tête), puis git branch -Mdéplacez la pointe de la branche. Le premier refusera de s'exécuter avec les modifications locales et le second ne fonctionnera que si les fichiers modifiés localement ne diffèrent pas entre les révisions.
Jan Hudec
11
@Jan, je n'y crois pas. Il existe des raisons parfaitement légitimes d'utiliser la réinitialisation.
spaaarky21
4
@ spaaarky21: Oui, il y en a. Mais git reset --hard somewherec'est l'une des rares commandes git vraiment dangereuses.
Jan Hudec
5
@Jan, je suis d'accord, mais le fait d'être dangereux ne signifie pas que vous ne devriez pas l'utiliser. Sachez simplement ce que vous faites et soyez prudent. :)
spaaarky21
3
Pas lié à l' annulation d'une réinitialisation de git --hard HEAD ~ 1 , car ici, l'affiche originale tente de récupérer les modifications non validées.

Réponses:

477

Vous ne pouvez pas récupérer les modifications non validées en général.

Les modifications précédemment mises en scène ( git add) devraient être récupérables à partir des objets d'index, donc si vous l'avez fait, utilisez git fsck --lost-foundpour localiser les objets qui y sont liés. (Cela écrit les objets dans le .git/lost-found/répertoire; à partir de là, vous pouvez utiliser git show <filename>pour voir le contenu de chaque fichier.)

Sinon, la réponse serait: regardez votre sauvegarde. Peut-être que votre éditeur / IDE stocke les copies temporaires sous / tmp ou C: \ TEMP et des choses comme ça. [1]

git reset HEAD@{1}

Cela restaurera à la tête précédente

[1] vim, par exemple, stocke éventuellement une annulation persistante, l' IDE éclipse stocke l'historique local ; de telles fonctionnalités pourraient vous faire économiser un **

sehe
la source
18
L'historique local d'Eclipse - et en plus, comme certains changements remontaient à plus de 6 jours, ma sauvegarde Time Machine de l'historique local d'Eclipse! Pour une raison quelconque, la sauvegarde Time Machine du dossier géré par git ne contenait pas mes modifications précédentes.
christianbrodbeck
2
Vous êtes vraiment un sauveur de vie sur l'indice! Le TextWrangler avait une sauvegarde de fichiers. Merci
Vivek Sampara
6
L'IDE (IntelliJ) a stocké les modifications localement, ce qui a sauvé la journée. Merci pour le conseil!
progonkpa
1
Wow c'est incroyable. Cela fonctionne même si vous n'avez jamais fait de commit.
Boudewijn Aasman
2
En effet, l'histoire locale dans Eclipse (Intellij dans mon cas) me sauve la journée en récupérant les modifications non structurées, doc ici pour Intellij: blog.jetbrains.com/idea/2008/01/…
Richard
449

réponse de ce 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}

Vous avez récupéré votre journée! :)

ken
la source
24
Juste pour ajouter à cette réponse, cela aiderait les personnes qui ont réellement commis des modifications qui ont été rejetées via une réinitialisation matérielle.
murki
9
Super - mais dans mon cas, les fichiers ont complètement disparu. L'utilisation git checkout HEAD@{19}m'a permis de vérifier les fichiers perdus dans un état détaché. Puis utilisé git checkout -b new-branch-namepour les ajouter au dépôt dans l'état "attaché".
NightOwl888
@ NightOwl888: Git newbie ici et j'ai eu le même problème que mes fichiers étaient toujours partis. Pourriez-vous expliquer plus en détail comment vous avez récupéré vos fichiers dans un état "attaché" (ou pourriez-vous expliquer ce que cela signifie réellement)? Merci beaucoup!
OhDaeSu du
3
@ user3385759 - Dans Git, lorsque vous utilisez la commande d'extraction sur tout ce qui n'est pas une branche, elle passe en mode spécial "tête détachée". Cela signifie que vous ne pointez pas réellement sur une branche, mais vous pouvez voir ce qui a été archivé à l'état de l'entité (dans ce cas, une entrée de reflog). À partir de cet état, vous pouvez le transformer en une "vraie" branche à laquelle vous pouvez revenir en utilisant git checkout -b new-branch-name. Le livre Pragmatic Version Control Using Git est bon pour expliquer Git en termes simples.
NightOwl888
2
Oui, ce que NomNomCameron et Jesse Adelman ont dit. J'ai pensé à tort que la réinitialisation reviendrait à mon dernier commit. Nan. Cela a tout effacé. Cette réponse m'a sauvé d'un jour ou deux de recréer mon travail.
VeteranCoder
308

J'ai accidentellement exécuté git reset --hardmon repo aujourd'hui aussi tout en ayant des changements non engagés aujourd'hui. Pour le récupérer, j'ai couru git fsck --lost-found, qui a écrit tous les blobs non référencés dans <path to repo>/.git/lost-found/. Comme les fichiers n'étaient pas validés, je les ai trouvés dans le otherrépertoire du <path to repo>/.git/lost-found/. De là, je peux voir les fichiers non validés en utilisant git show <filename>, copier les blobs et les renommer.

Remarque: cela ne fonctionne que si vous avez ajouté les fichiers que vous souhaitez enregistrer dans l'index (à l'aide git add .). Si les fichiers n'étaient pas dans l'index, ils sont perdus.

Justin
la source
4
J'ai juste des fichiers avec des références de commit dans lost-found. Mais je pourrais alors faire git showpour obtenir le contenu.
Mitar
6
Juste pour faire gagner du temps à n'importe qui#!/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

Oui, vous pouvez récupérer à partir d'une réinitialisation matérielle dans git.

Utilisation:

git reflog

pour obtenir l'identifiant de votre commit. Utilisez ensuite:

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

Cette astuce m'a sauvé la vie plusieurs fois.

Vous pouvez trouver la documentation de reflog ICI .

Gabe
la source
9
Jusqu'à présent, je pense que c'est la réponse la meilleure et la plus concise. Il peut sembler contre-intuitif de récupérer en git reset --hardutilisant un autre, git reset --hardmais si vous n'utilisez pas le --hardcommutateur, vous vous retrouverez avec des entrées dans votre espace de travail qui annuleraient efficacement le travail que vous venez de récupérer.
Ryan H.
2
Fonctionne comme un charme! La réponse précédente ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/… ) n'a pas fonctionné pour moi.
codemax
3
Cette réponse n'est pas correcte. Cette approche ne récupère que les modifications précédemment validées . Il ne pourra pas restaurer les modifications non validées (c'est le sujet de cette question).
Alderath
2
Cette solution fonctionne pour moi. J'ai fait une réinitialisation matérielle et puis quand j'utilise git logje n'ai pas vu l'id du commit. Avec git reflogje pouvais voir l'ID de validation
dboscanv
2
cela fonctionne pour moi. Merci!!!!!!
RedEyed
60

Pendant que je travaillais sur un projet local, je voulais le déplacer vers GitHub puis créer un nouveau référentiel. Pendant que j'essayais d'ajouter tous ces fichiers au nouveau référentiel avec .gitignore, j'ai accidentellement ajouté un mauvais fichier, puis j'ai essayé de le supprimer.

J'ai couru git reset --hard origin/master: P

Ensuite, tous mes fichiers locaux ont été supprimés car le dépôt était vide. Je pensais que tout était parti.

Cela m'a sauvé la vie:

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

J'espère que cela sauve une autre vie.

Orcun
la source
Pour moi, c'était git reset HEAD@\{27\} , merci!
4oby
1
J'ai 7 commits à réinitialiser, j'utilise git reflog showpour vérifier et à partir de ce premier commit j'utilisegit reset HEAD@{number}
Vishwas Nahar
38

Si vous utilisez quelque chose comme IntelliJ:

Dans le menu contextuel, choisissez Historique local, puis cliquez sur Afficher l'historique dans le sous-menu:

La vue historique locale d'un projet ou d'un dossier vous montre tout ce que vous avez fait au cours des derniers jours. Dans la colonne Action de la partie inférieure de la boîte de dialogue, sélectionnez l'action que vous souhaitez annuler. [...] Ce faisant, la partie supérieure de la boîte de dialogue affiche l'arborescence des fichiers modifiés. Si vous souhaitez restaurer uniquement le fichier supprimé, quelles que soient les autres modifications apportées depuis, vous pouvez sélectionner le fichier Lost.txt dans l'arborescence et cliquer sur le bouton Rétablir.

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

Cela vient de sortir mon cul du feu!

JonathanTien
la source
C'est de loin la meilleure réponse pour les utilisateurs d'IntelliJ! Merci beaucoup, cela a parfaitement fonctionné. J'ai essayé toutes les autres solutions et aucune d'entre elles n'a bien fonctionné. git reflogn'a pas fonctionné car je n'ai pas validé les modifications. git fsck --lost-foundtravaillé pour les fichiers intermédiaires mais pas tous. L'historique local d'IntelliJ a parfaitement récupéré mes fichiers non enregistrés, je suis tellement reconnaissant pour cette fonctionnalité
Denes Papp
30

Je viens de le faire git reset --hardet j'ai perdu tous mes changements non engagés. Heureusement, j'utilise un éditeur (IntelliJ) et j'ai pu récupérer les modifications de l'historique local. Eclipse devrait vous permettre de faire de même.

user1147827
la source
20

Par définition, git reset --hardsupprimera les modifications non validées sans aucun moyen pour Git de les récupérer (votre système de sauvegarde peut aider, mais pas Git).

En fait, il y a très peu de cas où git reset --hardc'est une bonne idée. Dans la plupart des cas, il existe une commande plus sûre pour faire la même chose:

  • Si vous souhaitez supprimer vos modifications non validées, utilisez git stash. Il conservera une sauvegarde de ces modifications, qui expirera après un certain temps si vous exécutez git gc. Si vous êtes sûr à 99,9% que vous n'aurez plus jamais besoin de ces modifications, git stashvotre ami sera toujours le cas à 0,1%. Si vous êtes sûr à 100%, git stashc'est toujours votre ami car ces 100% ont une erreur de mesure ;-).

  • Si vous voulez déplacer votre HEADet la pointe de la branche actuelle dans l'histoire, alors git reset --keepc'est votre ami. Il fera la même chose que git reset --hard, mais ne rejettera pas vos modifications locales.

  • Si vous voulez faire les deux, alors git stash && git reset --keepc'est votre ami.

Apprenez à vos doigts à ne pas l'utiliser git reset --hard, cela vous remboursera un jour.

Matthieu Moy
la source
donc si l'on fait git stash && git reset --hardcela effacer tout contenu caché est-ce pas?
jxramos
1
Non, git reset --hardne jette pas la cachette. git stashest un remplacement git reset --harddans le sens où il supprime les modifications non validées de votre arbre de travail, sauf qu'il les garde en sécurité au lieu de les supprimer définitivement.
Matthieu Moy
ou
validez
11

si vous réinitialisez accidentellement un commit, faites-le,

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

en supposant que HEAD@{2}vous souhaitez revenir à l'état

Edwin Ikechukwu Okonkwo
la source
cela a fonctionné parfaitement pour moi si vous faites cela sur PowerShell, assurez-vous de l'écrire comme ce git reset 'HEAD @ {2}' sinon ne fonctionnera pas dans
PowerShell
10

C'est ce que je fais habituellement si je perds certains changements.

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 ...

pour ramener le pointeur sur vos validations précédentes, mais en conservant les modifications que vous avez apportées jusqu'à présent lors de votre dernière validation des validations git reset --soft dadada

Chevalier Dragon
la source
8

L'information est perdue.

Puisque vous ne vous êtes pas engagé, votre .git n'a jamais stocké ces informations. Donc, fondamentalement, gitje ne peux pas le récupérer pour vous.

Mais, si vous venez de le faire git diff, il existe un moyen de récupérer en utilisant la sortie du terminal avec les 3 étapes simples suivantes.

  1. faites défiler votre terminal et recherchez le o / p de git diff. Enregistrez l'o / p dans un fichier appelé diff.patch
  2. Recherchez et remplacez les 7 espaces et les 8 espaces par un caractère de tabulation (\ t) et enregistrez les modifications.
  3. Allez dans votre dépôt git. Appliquer le diff.patch ( patch -p1 < diff.patch)

Vous êtes sauvé! :)

Remarque: Pendant que vous copiez les données du terminal vers un fichier, soyez prudent et voyez clairement que les données sont une sortie continue et ne contiennent aucune donnée redondante (en raison de l'appui sur les flèches haut et bas). Sinon, vous pourriez tout gâcher.

mk ..
la source
7

J'ai rencontré le même problème et j'étais presque devenu fou ... au début, j'ai commis le projet et j'ai fusionné ... plus tard, lorsque j'essaie de courir, git push --set-upstream origin master j'obtenais cette erreur

  fatal: refusing to merge unrelated histories

j'ai donc couru git reset --hard HEADet il a supprimé un projet de 3 semaines mais ces quelques commandes ci-dessous sauvent la mise:

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

J'espère que cela t'aides

Slycreator
la source
6

Vous pouvez récupérer un commit après avoir fait un reset --hard HEAD.

Utilisez " git reflog" pour vérifier l'historique de HEADla branche.

Vous verrez votre commit et son id ici.

Fait une

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

Si vous avez heureusement fait ouvrir les mêmes fichiers sur un autre éditeur (par exemple, Sublime Text), essayez un ctrl-z sur ceux-ci. Ça m'a sauvé ..

Gabe
la source
3

J'ai découvert à la dure que tous les fichiers non validés avant d' git reset --hard <commit>être supprimés de l'historique git. Cependant, j'ai eu la chance d'avoir gardé ma session d'éditeur de code ouverte pendant tout le temps que je me suis arraché les cheveux, que j'ai découvert qu'un simple control + zdans chacun des fichiers affectés renvoyait l'état du fichier à la version avant Git, donc réinitialiser obligatoirement tout ce que je ne lui ai pas demandé spécifiquement.Hooray!!

Friendly-Robot
la source
3

Si vous essayez d'utiliser le code ci-dessous:

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

et pour une raison quelconque obtiennent:

erreur: commutateur inconnu «e»

puis essayez HEAD@{1}de mettre des guillemets

git reset 'HEAD@{1}'
Rouille
la source
3
 git reset HEAD@{4}

4 est des changements avant il y a 4 étapes. si vous sélectionnez une étape correcte, elle devrait afficher la liste des fichiers que vous avez supprimés du disque dur. alors fais:

$ git reflog show

il va vous montrer l'historique des validations locales que nous avons déjà créées. maintenant:

$ git reset --hard 8c4d112

8c4d112 est un code que vous souhaitez réinitialiser votre disque dur. regardons https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history pour obtenir plus d'informations.

mohammad
la source
Merci beaucoup @mohammad, cela m'a sauvé. Je n'ai pas pu voir mes fichiers source plus tôt, mais en suivant les étapes ci-dessus, j'ai pu récupérer tous mes fichiers source.
Gaurav Bansal
2

Réponses correctes. OK, maintenant j'aime git. :-) Voici une recette plus simple.

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

Où "2" est le nombre de retour à l'endroit où vous avez validé vos modifications. Dans mon cas, interrompu par un collègue et un patron pour aider à déboguer un problème de build; donc, a fait un reset --hard deux fois; donc, HEAD et HEAD @ {1} ont été écrasés. Ouf, aurait perdu un notre de dur labeur.

TimJowers2
la source
2

J'ai fait git reset --hardle mauvais projet par erreur (je sais ...). Je venais de travailler sur un fichier et il était toujours ouvert pendant et après avoir exécuté la commande.

Même si je ne m'étais pas engagé, j'ai pu récupérer l'ancien fichier avec le simple COMMAND + Z.

Daniel Segura
la source
0

Réponse de référence de cet OS,

Après avoir exécuté git reflog show, dites que vous voulez valider 9300f9d

après avoir exécuté git reset 9300f9d

vous pouvez faire le statut git, puis vous devrez peut-être extraire votre fichier (s) pour restaurer vos modifications

git checkout - chemin / fichier

Daniel
la source
0

Si vous développez sur Netbeans, regardez entre les onglets de fichiers et la zone d'édition de fichiers. Il y a une "Source" et une "Histoire". Sur "Historique", vous verrez les modifications effectuées à l'aide du contrôle de version (git / other), mais également les modifications apportées localement. Dans ce cas, des modifications locales pourraient vous sauver.

Pedro Alvares
la source
0

( réponse adaptée à un sous-ensemble d'utilisateurs )

Si vous êtes sur (tout récent) macOS, et même si vous êtes loin de votre disque Time Machine, le système d'exploitation aura enregistré des sauvegardes horaires, appelées instantanés locaux .

Entrez dans Time Machine et accédez au fichier que vous avez perdu. L'OS vous demandera alors:

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?

Vous devriez pouvoir récupérer le ou les fichiers que vous avez perdus.

Calaf
la source
0

Si vous aviez un IDE ouvert avec le même code, essayez de faire un ctrl + z sur chaque fichier individuel auquel vous avez apporté des modifications. Cela m'a aidé à récupérer mes modifications non validées après avoir effectué la réinitialisation de git --hard.

dwarakesh tp
la source
-3

Lorsque nous git reset --hard et toutes les modifications locales non validées sont supprimées. Pour récupérer les modifications - dans IDE, cliquez sur le fichier, comparez le fichier avec l'historique local qui répertorie les modifications par date et nous pouvons récupérer les données. Votre journée est sauvée!

Roopa
la source
1
Cette réponse répète deux précédentes.
isherwood