Trouver et restaurer un fichier supprimé dans un dépôt Git

dis que je suis dans un dépôt Git. Je supprime un fichier et je commets ce changement. Je continue à travailler et à faire d'autres commits. Ensuite, je trouve que j'ai besoin de restaurer ce fichier.

je sais que je peux vérifier un fichier en utilisant git checkout HEAD^ foo.bar , mais je ne sais pas vraiment quand ce fichier a été supprimé.

  1. quel serait le moyen le plus rapide de trouver la propagation qui supprime un nom de fichier donné?
  2. quelle serait la meilleure façon d'obtenir ce fichier de retour dans ma copie de travail?

j'espère que je n'aurai pas à parcourir manuellement mes journaux, à vérifier l'ensemble du projet pour un SHA donné, puis à copier manuellement ce fichier dans ma caisse de projet originale.

2428
demandé sur 7ochem 2009-06-05 02:40:34
la source

19 ответов

trouver la dernière propagation qui a affecté le chemin donné. Comme le fichier n'est pas dans la propagation principale, cette propagation a dû le supprimer.

git rev-list -n 1 HEAD -- <file_path>

puis vérifier la version à la propagation avant, en utilisant le symbole caret ( ^ ):

git checkout <deleting_commit>^ -- <file_path>

Ou dans une commande, si $file est le fichier en question.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

si vous utilisez zsh et que vous avez L'option EXTENDED_GLOB activée, l'accent circonflexe ne fonctionne pas. Vous pouvez utiliser ~1 à la place.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
2768
répondu CB Bailey 2018-04-03 20:11:57
la source
  1. utilisez git log --diff-filter=D --summary pour obtenir toutes les propagations qui ont supprimé des fichiers et les fichiers supprimés;
  2. Utiliser git checkout $commit~1 filename pour restaurer le fichier supprimé.

$commit est la valeur de la propagation que vous avez trouvée à l'étape 1, par exemple e4cf499627

736
répondu Robert Munteanu 2018-05-23 17:58:03
la source

Pour restaurer tous les fichiers supprimés dans un dossier, entrez la commande suivante.

git ls-files -d | xargs git checkout --
306
répondu Manu 2014-12-21 00:49:17
la source

je suis venu à cette question en cherchant à restaurer un fichier que je viens de supprimer mais je n'avais pas encore commis le changement. Juste au cas où vous vous trouvez dans cette situation, tout ce que vous devez faire est la suivante:

git checkout HEAD -- path/to/file.ext

105
répondu Brett 2014-04-10 04:03:18
la source

si vous êtes fou, utilisez git-bisect . Voici ce qu'il faut faire:

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

maintenant il est temps d'exécuter le test automatisé. La commande shell '[ -e foo.bar ]' renvoie 0 si foo.bar existe, et 1 autrement. La commande " run "de git-bisect utilisera la recherche binaire pour trouver automatiquement la première propagation lorsque le test échoue. Il commence à la moitié de la fourchette donnée (du bon au mauvais) et le coupe en deux sur la base du résultat de la test spécifié.

git bisect run '[ -e foo.bar ]'

Maintenant vous êtes à la commit qui l'a supprimé. De là, vous pouvez revenir à l'avenir et utiliser git-revert pour annuler le changement,

git bisect reset
git revert <the offending commit>

ou vous pouvez revenir en arrière une commit et inspecter manuellement les dommages:

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .
84
répondu Josh Lee 2011-03-28 23:10:53
la source

Ma nouvelle préférée alias, basé sur bonyiii 's réponse (upvoted), et de ma propre réponse sur " Passer un argument à un Git commande alias ":

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- )~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- )~1 | grep '^D' | cut -f 2); }; f'

j'ai perdu un fichier supprimé par erreur quelques engage dans le passé?

Rapide:

git restore my_deleted_file

crise évitée.


Robert Dailey propose dans les commentaires l'alias suivant:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "")^ -- ""

et jegan ajoute dans les commentaires :

pour définir l'alias à partir de la ligne de commande, j'ai utilisé cette commande:

git config --global alias.restore "\!git checkout $(git rev-list -n 1 HEAD -- \"$1\")^ -- \"$1\"" 
63
répondu VonC 2017-10-10 09:03:55
la source

Si vous connaissez le nom, c'est un moyen facile avec les commandes de base:

liste Toutes les propagations pour ce fichier.

git log -- path/to/file

le dernier commit (le plus haut) est celui qui a supprimé le fichier. Donc vous devez restaurer la seconde à la dernière commit.

git checkout {second to last commit} -- path/to/file
43
répondu wisbucky 2017-04-15 14:48:31
la source

pour restaurer un fichier supprimé et Commité:

git reset HEAD some/path
git checkout -- some/path

il a été testé sur la version 1.7.5.4 de Git.

28
répondu Fedir RYKHTIK 2015-10-14 23:26:38
la source

Si vous faites des modifications et supprimé un fichier, mais pas le commettre, et maintenant que vous avez rompu vos modifications

git checkout -- .

mais vos fichiers supprimés ne sont pas retournés, vous faites simplement la commande suivante:

git checkout <file_path>

et presto, votre dossier est de retour.

22
répondu Paulo Linhares - Packapps 2016-09-02 18:30:19
la source

j'ai cette solution .

  1. récupérez l'id de la propagation où le fichier a été supprimé en utilisant l'une des méthodes ci-dessous.

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* # recommandé si vous avez à peine se souvenir de n'importe quoi
  2. vous devriez obtenir quelque chose comme:

commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 auteur: Alexander Orlov Date: Jeu Mai 12 23: 44: 27 2011 +0200

replaced deprecated GWT class
- gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 auteur: Alexander Orlov Date: Jeu Mai 12 22: 10: 22 2011 +0200

3 . Maintenant, en utilisant la validation id bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

comme l'id de propagation renvoie à la propagation où le fichier a déjà été supprimé, vous devez renvoyer à la propagation juste avant bfe68b ce que vous pouvez faire en ajoutant ^1 . Cela signifie: Donnez-moi le commit juste avant bfe68b.

21
répondu Alex 2014-08-25 22:07:17
la source
git checkout /path/to/deleted.file
14
répondu user1528493 2014-08-25 22:05:51
la source

dans de nombreux cas, il peut être utile d'utiliser coreutils (grep, sed, etc.) en conjonction avec Git. Je connais déjà assez bien ces outils, mais pas autant. Si je voulais faire une recherche pour un fichier supprimé, je ferais ce qui suit:

git log --raw | grep -B 30 $'D\t.*deleted_file.c'

quand je trouve la révision / commit:

git checkout <rev>^ -- path/to/refound/deleted_file.c

tout comme d'autres l'ont dit avant moi.

Le fichier sera restauré à l'état qu'il avait avant de les enlever. N'oubliez pas de ré-engager pour l'arbre de travail si vous souhaitez le garder.

10
répondu Thomas E 2015-10-14 23:27:59
la source

git undelete path/to/file.ext

  1. mettez ceci dans votre .bash_profile (ou tout autre fichier pertinent qui se charge lorsque vous ouvrez un shell de commande):

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- )^ -- " -'
    
  2. ensuite utiliser:

    git undelete path/to/file.ext
    

cet alias vérifie d'abord pour trouver le dernier commit où ce fichier existait, puis fait une vérification git de ce chemin de fichier à partir de ce dernier commit où ce fichier existait. source

9
répondu Beau Smith 2017-06-08 04:13:40
la source

donc j'ai dû restaurer un tas de fichiers supprimés à partir d'une propagation spécifique et je l'ai géré avec deux commandes:

git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ -- 
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD 

(noter l'espace de fuite à la fin de chaque commande.)

les fichiers avaient été ajoutés à la .gitignore fichier et ensuite effacé avec git rm, j'avais besoin de restaurer les fichiers mais alors unstage. J'ai eu des centaines de fichiers à restaurer, tapant des choses manuellement pour chaque fichier, comme dans les autres exemples allait être beaucoup trop lent.

6
répondu kzar 2017-04-15 14:49:46
la source
[email protected]:~/work/git$ rm slides.tex
[email protected]:~/work/git$ git pull 
Already up-to-date.
[email protected]:~/work/git$ ls slides.tex
ls: slides.tex: No such file or directory

restaurer le fichier supprimé:

[email protected]:~/work/git$ git checkout
D       .slides.tex.swp
D       slides.tex
[email protected]:~/work/git$ git checkout slides.tex 
[email protected]:~/work/git$ ls slides.tex
slides.tex
4
répondu user1797498 2012-11-29 20:35:45
la source

j'avais la même question. Sans le savoir, j'avais créé un bancales commettre .

Liste balançant s'engage

git fsck --lost-found

Inspecter chaque balançant commettre

git reset --hard <commit id>

Mes fichiers sont réapparus quand je suis passé à la commit pendante.

git status pour la raison:

“HEAD detached from <commit id where it detached>”

4
répondu rustyMagnet 2018-01-04 20:08:40
la source

dans notre cas nous avons accidentellement supprimé des fichiers dans un commit et certains commit plus tard nous avons réalisé notre erreur et avons voulu récupérer tous les fichiers qui ont été supprimés mais pas ceux qui ont été modifiés.

basé sur L'excellente réponse de Charles Bailey voici mon un liner:

git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)
3
répondu bonyiii 2012-07-03 00:52:39
la source

si vous connaissez la propagation qui a supprimé le(S) fichier (s), lancez cette commande où <SHA1_deletion> est la propagation qui a supprimé le fichier:

git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --

la partie avant la pipe liste tous les fichiers qui ont été supprimés dans la propagation; ils sont tous des checkout de la propagation précédente pour les restaurer.

3
répondu Tony Wickham 2016-01-08 22:27:52
la source
$ git log --diff-filter=D --summary  | grep "delete" | sort
-1
répondu kujiy 2018-02-05 04:01:30
la source

Autres questions sur git git-checkout file-io