Comment rétablir un "git rm -r."?

378

Ai-je accidentellement dit git rm -r .. Comment puis-je m'en remettre?

Je ne me suis pas engagé.

Je pense que tous les fichiers ont été marqués pour suppression et ont également été physiquement supprimés de ma caisse locale.

EDIT: je pourrais (si je connaissais la commande) revenir au dernier commit. Mais ce serait beaucoup mieux si je pouvais juste annuler la git rm -r .. Parce que je ne suis pas vraiment sûr de ce que j'ai fait après le dernier commit et avant le git rm -r ..

user89021
la source
3
Pour cette question particulière, reset --hard est une bonne solution ... il est déjà répertorié, je vais donc mentionner dans ce commentaire que vous voudrez peut-être vérifier la documentation de git-reflog.
William Pursell
8
Notez que parce que vous n'avez pas fourni -fà git rmgit, vous n'aurez supprimé aucun fichier contenant des modifications intermédiaires ou non, donc il git reset; git checkout .devrait tout récupérer.
CB Bailey
Faites juste attention - git checkout. effacera toutes les modifications non programmées.
PeterB
1
Je viens de faire quelque chose comme ça, et je ne comprends pas pourquoi mes fichiers locaux ont été supprimés (et, comme l'OP, je ne me suis pas encore engagé.)
Xonatron
Avec Git 2.23+ (Août 2019), vous restaurer des fichiers avec git restore: git restore -s@ -SW -- .. Voir ma réponse ci-dessous .
VonC

Réponses:

468
git reset HEAD

Devrait le faire. Si vous n'avez aucune modification non validée dont vous vous souciez, alors

git reset --hard HEAD

devrait forcer tout réinitialiser à votre dernier commit. Si vous avez des modifications non validées, mais que la première commande ne fonctionne pas, enregistrez vos modifications non validées avec git stash:

git stash
git reset --hard HEAD
git stash pop
Brian Campbell
la source
22
Notez que git reset --hard HEADdétruit toutes les modifications utiles que vous avez apportées dans les répertoires parents du répertoire de travail actuel.
Alex Brown
10
@Mild: Je porte toujours une sueur froide!
hoipolloi
6
Je n'ai pas rejeté le vote, mais j'ai juste essayé de cacher, réinitialiser dur, pop et perdu toutes mes modifications récentes. J'ai peut-être mal lu la réponse.
Greg M. Krsak
1
Cela fonctionne rarement pour moi, et je suis tellement content de travailler dans un dossier Dropbox. Mauvaise forme, mais me sauve à chaque fois ...
Nuby
3
Quand j'ai fait git stash pop, il a juste supprimé à nouveau les fichiers, bien sûr parce qu'il cache le fait que j'ai accidentellement supprimé certains fichiers. Cette réponse ne fonctionne pas si vous souhaitez conserver des modifications non validées.
sudo
252

J'ai git-rm'd quelques fichiers et j'ai continué à faire des changements avant mon prochain commit quand j'ai réalisé que j'avais besoin de certains de ces fichiers. Plutôt que de cacher et de réinitialiser, vous pouvez simplement extraire les fichiers individuels que vous avez manqués / supprimés si vous le souhaitez:

git checkout HEAD path/to/file path/to/another_file

Cela laisse vos autres modifications non validées intactes sans solution de contournement.

Jaime Bellmyer
la source
6
Cela m'a aidé car j'avais d'autres changements non validés.
Dan
4
Cette réponse aide ceux d'entre nous qui sont tombés sur cette question qui cherchent à revenir sur un seul git rmplutôt que sur un récursif entier git rm -r. Pour une suppression récursive complète, les autres solutions peuvent être meilleures, selon la quantité de fichiers supprimés.
tresf
Vous, mon homme, méritez un prix.
Salamit
Si je pouvais, je cliquerais dessus 100 fois !!!
Wagner Braga
57

Pour récupérer certains fichiers ou dossiers, on peut utiliser ce qui suit

git reset -- path/to/file
git checkout -- path/to/file

Cela va d'abord recréer les entrées d'index pour path/to/fileet recréer le fichier tel qu'il était dans le dernier commit, c'est-à-dire HEAD.

Astuce: on peut passer un hachage de validation aux deux commandes pour recréer des fichiers à partir d'un commit plus ancien. Voir git reset --helpet git checkout --helppour plus de détails.

Arne L.
la source
Meilleure réponse. Annulation chirurgicale facile d'une seule git rmopération sans effacer les autres modifications non validées.
wberry
M'a aidé! meilleure réponse.
Akram
28

Mise à jour:

Puisque git rm .supprime tous les fichiers de ce répertoire et des répertoires enfants dans la caisse de travail ainsi que dans l'index, vous devez annuler chacune de ces modifications:

git reset HEAD . # This undoes the index changes
git checkout .   # This checks out files in this and child directories from the HEAD

Cela devrait faire ce que vous voulez. Il n'affecte pas les dossiers parents de votre code ou index extrait.


Ancienne réponse qui n'était pas:

reset HEAD

fera l'affaire et n'effacera pas les modifications non validées que vous avez apportées à vos fichiers.

après cela, vous devez répéter toutes les git addcommandes que vous aviez mises en file d'attente.

Alex Brown
la source
1
désolé, j'ai toujours configuré git alias.co="checkout"pour que git cocela passe à la caisse.
Alex Brown
25

Si vous vous retrouvez avec rien de ce qui précède, vous pourriez être en mesure de récupérer des données en utilisant la suggestion d'ici: http://www.spinics.net/lists/git/msg62499.html

git prune -n
git cat-file -p <blob #>
Skippy VonDrake
la source
4 ans plus tard, toujours une bouée de sauvetage!
ThievingSix
J'ai écrit un programme c ++ pour concaténer les résultats (j'avais environ 100 objets pendant dans mon dépôt, ce qui rend cela nécessaire). Compilez et exécutez simplement, puis passez dans votre répertoire local git repo. raw.githubusercontent.com/bluuman/git-recover-files/master/…
James Meas
15

annuler git rm

git rm file             # delete file & update index
git checkout HEAD file  # restore file & index from HEAD

annuler git rm -r

git rm -r dir          # delete tracked files in dir & update index
git checkout HEAD dir  # restore file & index from HEAD

annuler git rm -rf

git rm -r dir          # delete tracked files & delete uncommitted changes
not possible           # `uncommitted changes` can not be restored.

Uncommitted changes comprend not staged changes , staged changes but not committed.

chanson xu
la source
Bien sûr, rien ne peut être annulé git rm -rf, car cela peut également supprimer les fichiers non suivis ou intermédiaires (uniquement).
jpaugh
git rm -rf fileet git rm -rf dirne supprimera aucun fichier non suivi.
chanson xu
10

Si vous avez validé et poussé les modifications, vous pouvez le faire pour récupérer le fichier

// Replace 2 with the # of commits back before the file was deleted.
git checkout HEAD~2 path/to/file
Cory Danielson
la source
Cela a fonctionné pour les `` modifications à valider: '' où un fichier a été supprimé d'un ancien git cherry-pick dont j'avais encore besoin.J'ai essayé git reset HEAD ~ <number> <file> qui n'a pas fonctionné.
mushcraft
7

Il y a déjà de bonnes réponses, mais je pourrais suggérer une syntaxe peu utilisée qui non seulement fonctionne très bien, mais est très explicite dans ce que vous voulez (donc pas effrayante ou mystérieuse)

git checkout <branch>@{"20 minutes ago"} <filename>
mehtunguh
la source
3

Obtenir la validation de la liste

git log  --oneline

Par exemple, Stable commit hash: 45ff319c360cd7bd5442c0fbbe14202d20ccdf81

git reset --hard 45ff319c360cd7bd5442c0fbbe14202d20ccdf81
git push -ff origin master
Do Nhu Vy
la source
1

J'avais une situation identique. Dans mon cas, la solution était:

git checkout -- .
Artur
la source
0

Avec Git 2.23+ (août 2019), la commande appropriée pour restaurer les fichiers (et l'index) serait à utiliser ... git restore(pas reset --hardou la commande confusegit checkout )

C'est:

git restore -s=HEAD --staged --worktree -- .

Ou sa forme abrégée:

git restore -s@ -SW -- .
VonC
la source
-1

J'avais exactement le même problème: nettoyer mes dossiers, réorganiser et déplacer des fichiers. Je suis entré: git rm .et appuyez sur Entrée; puis j'ai senti mes entrailles se desserrer un peu. Heureusement, je n'ai pas tout de suite tapé git commit -m "".

Cependant, la commande suivante

git checkout .

tout restauré et sauvé ma vie.

Wai-Ming Lee
la source