2012-07-23 2 views
9

Normalement, vous pouvez faire:mis en scène, mais non engagés, les fichiers supprimés après l'émission: git reset HEAD --hard

$ echo "Stanley, you must beware of the Drive bee" > file-a 
$ echo "What's a Drive bee?" > file-b 
$ git init . 
$ git add file-b 
$ git commit file-b -m "We don't know, but whatever error you make with it could be fatal." 
$ git reset --hard HEAD 
$ ls 
file-a file-b 

Je pense que je l'ai fait quelque chose de vraiment mauvais:

$ echo "What are you doing, you darn ?" > file-a 
$ echo "Can't you see I'm trying to drive?" > file- 
$ git init . 
$ git add -A 
$ git commit file- -m "Oh, my God! [It's] the Drive !" 
$ git reset --hard HEAD 
$ ls 
file- 

Résultat: tous mis en scène, mais non engagés, les fichiers supprimés 0_o

git reset --hard HEAD\^ 
fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree. 

Est-ce que je peux faire pour récupérer le fichier que je viens de supprimer? En d'autres termes, est-il possible de restaurer un dépôt git dans l'état où il était avant (ou quand) la commande git add -A a été émise?

Répondre

20

Oui, vous êtes vraiment chanceux. Ce que vous avez ajouté à l'index de Git est là, d'une manière ou d'une autre. En fait, Git crée des objets blob pour chaque fichier déjà lorsqu'il est ajouté à l'index. L'index lui-même ne stocke que les objets de l'arbre.

Alors oui, il y avait des objets blob créés pour vos fichiers mis en scène. Tout ce que vous perdez sont les informations sur l'arborescence, c'est-à-dire le chemin et le nom de fichier, mais vous pouvez récupérer le contenu.

Essayez d'exécuter git fsck et vous devriez obtenir une liste des blobs ballants:

Checking object directories: 100% (256/256), done. 
dangling blob ac28af8d84fc71eb247ccf665c6d0f4bf1822520 
dangling blob 2d152ff9f09cb08ebc495f453da63eddaa9e249f 
dangling blob cd9567427762cd8066b4e802e5c170a31a026100 

Vous pouvez alors récupérer le contenu en faisant git cat-file -p ac28af8d. Par exemple, vous pouvez le transférer dans un fichier:

git cat-file -p ac28af8d > recovered-file 

Faites-le pour tous et vous les récupérez.

+2

Juste une note pour la plupart hors de propos que vous pouvez utiliser 'git show' comme alternative à' git cat-file -p'. Très bonne réponse. Je ne m'en suis pas rendu compte moi-même. –

+0

@MichaelMior Vraiment, j'utilise généralement 'cat-file -p' car il me donne la même sortie pour tout type d'objet;) – poke

+0

Merci! Je ne le savais pas non plus. La réalité un peu triste est qu'il sera plus facile de recréer tous les fichiers car il s'agissait d'un projet Android relativement nouveau et beaucoup de fichiers ont été supprimés, ce qui signifie qu'un arbre relativement grand est perdu. Mais, je devrais être capable d'obtenir le code que j'ai écrit des blobs en utilisant votre solution et juste le rajouter. (= – dcow

2

Le script suivant restaurer tous les blobs ballants de git fsck sortie en fichiers:

i=0; for x in `git fsck | grep "dangling blob [0-9a-f]" | cut -d ' ' -f 3`; do git cat-file -p $x > /tmp/test${i}; i=$((i+1)) ; done 

Comme vous pouvez le voir, la sortie de chaque fichier d'origine est restauré dans le nom de fichier générique/tmp/test $ {i} .. . Je ne l'ai pas trouvé un moyen de restaurer le nom du fichier encore ... la commande que j'ai essayé est git ls-tree:

d'abord, je l'ai pris des objets possibles:

./.git/objects/37 
./.git/objects/37/5187f5882593f7e52c8efef602d98f1f049c5d 
./.git/objects/37/98be05fcbd7c79e08703aead800529b362332b 

Puis, j'ai essayé de faire le tour ls-tree, mais il n'a pas réussi à l'identifier comme un objet valide.

/<myproj>/.git/objects/37 ]$ git ls-tree 5187f5882593f7e52c8efef602d98f1f049c5d 
fatal: Not a valid object name 5187f5882593f7e52c8efef602d98f1f049c5d 
0

Je aime vraiment la solution suivante de ce answer à une associée Stack Overflow question:

  1. Utilisez git log --diff-filter=D --summary pour obtenir tous les commits qui ont supprimé les fichiers et les fichiers supprimés
  2. Utilisez git checkout $commit~1 filename pour restaurer le fichier supprimé.

Il est concis et intuitif.

+0

Veuillez ne pas poster de lien uniquement les réponses à d'autres questions de débordement de pile. Au lieu de cela, votez/marquez pour fermer comme doublon, ou, si la question n'est pas un doublon, * adaptez la réponse à cette question spécifique. * – Rizier123

+0

@ red-goblin le commit était toast. Vous ne pouvez pas extraire d'un index qui n'existe pas S = (c'est-à-dire que ce n'est pas une copie de la question que vous avez liée, et donc ses réponses ne s'appliquent pas correctement ici, merci bien) – dcow

Questions connexes