Après la dernière validation, j'ai modifié un groupe de fichiers dans ma copie de travail, mais je souhaite annuler les modifications apportées à l'un de ces fichiers, en le réinitialisant au même état que la dernière validation.
Cependant, je veux seulement annuler les modifications de la copie de travail d'un seul fichier, rien d'autre.
Comment je fais ça?
Vous pouvez utiliser
git checkout -- file
Vous pouvez le faire sans le --
(comme suggéré par nimrodm), mais si le nom du fichier ressemble à une branche ou à une balise (ou à un autre identifiant de révision), il risque d’être confus. Il est donc préférable d’utiliser --
.
Vous pouvez également extraire une version particulière d'un fichier:
git checkout v1.2.3 -- file # tag v1.2.3
git checkout stable -- file # stable branch
git checkout Origin/master -- file # upstream master
git checkout HEAD -- file # the version from the most recent commit
git checkout HEAD^ -- file # the version before the most recent commit
git checkout <commit> <filename>
Je l'ai utilisé aujourd'hui parce que je me suis rendu compte que mon favicon avait été écrasé il y a quelques modifications lorsque je suis passé à la version 6.10 drupal. Voici ce que j'ai fait:
git checkout 088ecd favicon.ico
Juste utiliser
git checkout filename
Cela remplacera le nom de fichier par la dernière version de la branche actuelle.
AVERTISSEMENT: vos modifications seront ignorées - aucune sauvegarde n'est conservée.
Si votre fichier est déjà en cours de traitement (cela se produit lorsque vous effectuez une addition git, etc. après la modification du fichier), annulez vos modifications.
Utilisation
git reset HEAD <file>
Ensuite
git checkout <file>
Si ce n'est déjà fait, utilisez simplement
git checkout <file>
Si vous voulez simplement annuler les modifications du commit précédent dans ce fichier, vous pouvez essayer ceci:
git checkout branchname^ filename
Cela va extraire le fichier tel qu'il était avant la dernière validation. Si vous voulez récupérer quelques commits de plus, utilisez la notation branchname~n
.
Je suis toujours confus avec cela, alors voici un cas de test de rappel; Disons que nous avons ce script bash
pour tester git
:
set -x
rm -rf test
mkdir test
cd test
git init
git config user.name test
git config user.email [email protected]
echo 1 > a.txt
echo 1 > b.txt
git add *
git commit -m "initial commit"
echo 2 >> b.txt
git add b.txt
git commit -m "second commit"
echo 3 >> b.txt
À ce stade, le changement n'est pas mis en scène dans le cache, donc git status
est:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
Si à partir de ce moment, nous faisons git checkout
, le résultat est le suivant:
$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean
Si à la place nous faisons git reset
, le résultat est:
$ git reset HEAD -- b.txt
Unstaged changes after reset:
M b.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
Donc, dans ce cas, si les modifications ne sont pas effectuées par étapes, git reset
ne fait aucune différence, alors que git checkout
écrase les modifications.
Maintenant, supposons que le dernier changement du script ci-dessus soit mis en cache/mis en cache, c'est-à-dire que nous avons également fait git add b.txt
à la fin.
Dans ce cas, git status
à ce stade est:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: b.txt
Si à partir de ce moment, nous faisons git checkout
, le résultat est le suivant:
$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean
Si à la place nous faisons git reset
, le résultat est:
$ git reset HEAD -- b.txt
Unstaged changes after reset:
M b.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
Ainsi, dans ce cas - si les modifications sont programmées, git reset
les transforme en modifications non mises en scène - alors que git checkout
écrase complètement les modifications.
Je restaure mes fichiers en utilisant l'identifiant SHA, ce que je fais est git checkout <sha hash id> <file name>
Cette réponse concerne la commande nécessaire pour annuler les modifications locales qui se trouvent dans plusieurs fichiers spécifiques dans un ou plusieurs dossiers (ou répertoires). Cette réponse répond spécifiquement à la question où un utilisateur a plus d'un fichier mais l'utilisateur ne veut pas annuler toutes les modifications locales:
si vous avez un ou plusieurs fichiers, vous pouvez appliquer la même commande (
git checkout -- file
) à chacun de ces fichiers en répertoriant chacun de leurs emplacements séparés par espace comme dans:
git checkout -- name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext
gardez l'esprit de l'espace ci-dessus entre name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext
Pour plusieurs fichiers dans le même dossier:
Si vous devez ignorer les modifications pour tous les fichiers d’un fichier certain répertoire, utilisez le git checkout comme suit:
git checkout -- name1/name2/*
L'astérisque dans ce qui précède annule tous les fichiers de cet emplacement sous nom1/nom2.
De même, les éléments suivants peuvent annuler les modifications apportées à tous les fichiers pour plusieurs dossiers:
git checkout -- name1/name2/* nameA/subFolder/*
de nouveau, faites attention à l’espace entre name1/name2/* nameA/subFolder/* dans le fichier au dessus de.
Remarque: nom1, nom2, nomA, sous-dossier - tous ces exemples de noms de dossiers indiquent le dossier ou le package dans lequel le ou les fichiers en question peuvent résider.
Si vous n'avez pas encore poussé ou partagé votre commit:
git diff --stat HEAD^...HEAD | \
fgrep filename_snippet_to_revert | cut -d' ' -f2 | xargs git checkout HEAD^ --
git commit -a --amend
S'il est déjà validé, vous pouvez annuler la modification pour le fichier et le commettre à nouveau, puis écraser le nouveau commit avec le dernier commit.