web-dev-qa-db-fra.com

Rechercher et restaurer un fichier supprimé dans un référentiel Git

Dites que je suis dans un référentiel Git. Je supprime un fichier et commets ce changement. Je continue à travailler et à faire d'autres engagements. Ensuite, je trouve que je dois restaurer ce fichier.

Je sais que je peux extraire 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 le commit qui a supprimé un nom de fichier donné?
  2. Quel serait le moyen le plus simple de récupérer ce fichier dans ma copie de travail?

J'espère ne pas devoir parcourir manuellement mes journaux, extraire le projet entier pour un SHA donné, puis copier manuellement ce fichier dans l'extraction de projet d'origine.

2657
avdgaag

Trouver le dernier commit qui a affecté le chemin donné. Le fichier n'étant pas dans la validation HEAD, cette validation doit l'avoir supprimé.

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

Puis vérifiez la version à la validation 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 l'option EXTENDED_GLOB est activée, le symbole caret ne fonctionnera pas. Vous pouvez utiliser ~1 à la place.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
3001
CB Bailey
  1. Utilisez git log --diff-filter=D --summary pour obtenir tous les commits contenant des fichiers supprimés et les fichiers supprimés.
  2. Utilisez git checkout $commit~1 path/to/file.ext pour restaurer le fichier supprimé.

$commit est la valeur du commit que vous avez trouvé à l'étape 1, par exemple. e4cf499627

821
Robert Munteanu

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

git ls-files -d | xargs git checkout --
310
Manu

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

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

119
Brett

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

Il est maintenant temps de lancer le test automatisé. La commande Shell _'[ -e foo.bar ]'_ renverra 0 si _foo.bar_ existe et 1 sinon. La commande "run" de _git-bisect_ utilisera la recherche binaire pour trouver automatiquement le premier commit où le test échoue. Il commence à mi-chemin de la plage donnée (de bon à mauvais) et le réduit de moitié en fonction du résultat du test spécifié.

_git bisect run '[ -e foo.bar ]'
_

Maintenant vous en êtes au commit qui l'a supprimé. À partir de là, vous pouvez revenir au futur et utiliser git-revert pour annuler le changement,

_git bisect reset
git revert <the offending commit>
_

ou vous pouvez revenir en arrière d’un commit et inspecter manuellement les dégâts:

_git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .
_
89
Josh Lee

Mon nouvel alias préféré, basé sur bonyiiiréponse (voté), et ma propre réponse à propos de " Passer un argument à une commande d'alias Git ":

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

J'ai perdu un fichier, supprimé par erreur il y a quelques instants?
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 -- "$1")^ -- "$1"

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\"" 
71
VonC

Si vous connaissez le nom de fichier, il s'agit d'un moyen simple d'utiliser des commandes de base:

Répertoriez tous les commits pour ce fichier.

git log -- path/to/file

Le dernier commit (en haut) est celui qui a supprimé le fichier. Donc, vous devez restaurer l'avant-dernier commit.

git checkout {second to last commit} -- path/to/file
47
wisbucky

Pour restaurer un fichier supprimé et validé:

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

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

29
Fedir RYKHTIK

Si vous avez seulement apporté des modifications et supprimé un fichier, mais ne l'avez pas validé, vous avez maintenant rompu avec vos modifications

git checkout -- .

mais vos fichiers supprimés ne sont pas revenus, vous devez simplement exécuter la commande suivante:

git checkout <file_path>

Et hop, votre dossier est de retour.

J'ai cette solution .

  1. Obtenez l'identifiant de la validation 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 ne vous souvenez plus de rien
  2. Vous devriez obtenir quelque chose comme:

commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Auteur: Alexander Orlov Date: jeu 12 mai 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 12 mai 22:10:22 2011 +0200

3 . Maintenant, en utilisant l'id de commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.Java

Comme l'ID de validation fait référence à la validation dans laquelle le fichier a déjà été supprimé, vous devez référencer la validation juste avant bfe68b, ce que vous pouvez faire en ajoutant ^1. Cela signifie: donnez-moi le commit juste avant bfe68b.

23
Alex
git checkout /path/to/deleted.file
15
user1528493

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 -- $1)^ -- $1" -'
    
  2. Alors utilisez:

    git undelete path/to/file.ext
    

Cet alias vérifie d'abord de trouver le dernier commit où ce fichier a existé, puis effectue une extraction git de ce chemin d'accès du dernier commit où ce fichier existait. source

12
Beau Smith

Dans de nombreux cas, il peut être utile d’utiliser coreutils (grep, sed, etc.) avec Git. Je connais déjà très bien ces outils, mais Git moins. Si je souhaitais rechercher un fichier supprimé, je procéderais comme 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 déclaré avant moi.

Le fichier va maintenant être restauré dans l'état où il se trouvait avant la suppression. Pensez à le réengager dans l’arbre de travail si vous souhaitez le conserver.

11
Thomas E

J'ai donc dû restaurer un tas de fichiers supprimés à partir d'un commit 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 

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

Les fichiers avaient été ajoutés au fichier .gitignore, puis effacés avec git rm. J'avais besoin de restaurer les fichiers, puis de les décomposer. J'avais des centaines de fichiers à restaurer, taper manuellement les choses pour chaque fichier, comme dans les autres exemples, serait beaucoup trop lent.

7
kzar

En fait, cette question concerne directement Git, mais quelqu'un comme moi fonctionne avec des outils graphiques tels que WebStorm VCS, autres que connaître les commandes git cli.

Je clique avec le bouton droit sur le chemin qui contient le fichier supprimé, puis je passe à Git, puis je clique sur Show History.

enter image description here

Les outils VCS montrent toutes les révisions et je peux voir tous les validations et modifications de chacune d’elles.

enter image description here

Ensuite, je sélectionne les commits que mon ami supprime le fichier PostAd.js. maintenant voir ci-dessous:

enter image description here

Et maintenant, je peux voir mon fichier supprimé du désir. Je viens de double-cliquer sur le nom du fichier et il récupère.

enter image description here

Je sais que ma réponse n’est pas Git commandes, mais elle est rapide, fiable et simple pour les développeurs débutants et professionnels. Webstorm Les outils VCS sont géniaux et parfaits pour travailler avec Git et ne nécessitent aucun autre plugin ou outil.

6
AmerllicA

J'ai eu la même question. Sans le savoir, j'avais créé une pendaison commit .

Liste des commits en suspens

git fsck --lost-found

Inspecter chaque commet en suspens

git reset --hard <commit id>

Mes fichiers ont réapparu lorsque je suis passé au commit valide.

git status pour la raison:

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

5
rustyMagnet
user@bsd:~/work/git$ rm slides.tex
user@bsd:~/work/git$ git pull 
Already up-to-date.
user@bsd:~/work/git$ ls slides.tex
ls: slides.tex: No such file or directory

Restaurez le fichier supprimé:

user@bsd:~/work/git$ git checkout
D       .slides.tex.swp
D       slides.tex
user@bsd:~/work/git$ git checkout slides.tex 
user@bsd:~/work/git$ ls slides.tex
slides.tex
5
user1797498

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

Sur la base de l'excellente réponse de Charles Bailey, voici mon 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)
4
bonyiii

Si vous connaissez la validation qui a supprimé le ou les fichiers, exécutez cette commande où <SHA1_deletion> est la validation 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 le canal répertorie tous les fichiers supprimés dans la validation; elles sont toutes extraites du commit précédent pour les restaurer.

4
Tony Wickham

Simple et précis

Tout d’abord, obtenez un dernier commit stable dans lequel vous avez ce fichier -

git log 

Disons que vous trouvez $ commitid 1234567 ..., alors

git checkout <$commitid> $fileName

Cela restaurera la version du fichier qui était dans cette validation.

2
Sudhanshu Jain

Je sais que c'est un ancien fil de discussion, mais vous pouvez toujours utiliser git revert votre commit pour supprimer le fichier. (Cela suppose que la suppression était le seul changement dans la validation.)

> git log 
commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3
Author: Dave <[email protected]>
Date:   Thu May 9 11:11:06 2019 -0700

    deleted readme.md

Et si vous avez poursuivi votre travail et réalisé plus tard que vous ne vouliez pas valider cette validation de suppression, vous pouvez l'annuler à l'aide de.

> git revert 2994bd

Maintenant, git log montre:

> git log
Author: Dave <[email protected]>
Date:   Thu May 9 11:17:41 2019 -0700

    Revert "deleted readme"

    This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.

Et readme.md a été restauré dans le référentiel.

0
Dave Baghdanov
$ git log --diff-filter=D --summary  | grep "delete" | sort
0
kujiy