web-dev-qa-db-fra.com

Réinitialiser ou rétablir un fichier spécifique à une révision spécifique en utilisant Git?

J'ai apporté des modifications à un fichier qui a été validé à plusieurs reprises en tant que partie d'un groupe de fichiers, mais je souhaite maintenant réinitialiser/rétablir les modifications qui y sont apportées sur une version antérieure. 

J'ai fait un git log avec un git diff pour trouver la révision dont j'ai besoin, mais je ne sais tout simplement pas comment rétablir le fichier dans son état antérieur par le passé.

3806
Hates_

En supposant que le hash du commit que vous voulez est c5f567:

git checkout c5f567 -- file1/to/restore file2/to/restore

La page de manuel git checkout donne plus d’informations.

Si vous souhaitez revenir à la validation avant c5f567, ajoutez ~1 (fonctionne avec n’importe quel nombre):

git checkout c5f567~1 -- file1/to/restore file2/to/restore

En passant, cette commande a toujours été inconfortable car elle est utilisée à la fois pour des tâches ordinaires (changement de branche) et des tâches inhabituelles et destructrices (suppression des modifications dans le répertoire de travail).

5187
Greg Hewgill

Vous pouvez rapidement passer en revue les modifications apportées à un fichier à l'aide de la commande diff:

git diff <commit hash> <filename>

Ensuite, pour rétablir un fichier spécifique sur cette validation, utilisez la commande reset:

git reset <commit hash> <filename>

Vous devrez peut-être utiliser l'option --hard si vous avez des modifications locales.

Un bon flux de travail pour la gestion des points de cheminement consiste à utiliser des balises pour marquer proprement des points dans votre chronologie. Je ne comprends pas très bien votre dernière phrase, mais vous voudrez peut-être diviser une branche par rapport à un moment antérieur. Pour ce faire, utilisez la commande d'extraction pratique:

git checkout <commit hash>
git checkout -b <new branch name>

Vous pouvez ensuite baser cela sur votre ligne principale lorsque vous êtes prêt à fusionner ces modifications:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>
545
Chris Lloyd

Vous pouvez utiliser n'importe quelle référence à un commit git, y compris SHA-1 si cela vous convient le mieux. Le fait est que la commande ressemble à ceci:

git checkout [commit-ref] -- [filename]

323
foxxtrot
git checkout -- foo

Cela réinitialisera foo à HEAD. Vous pouvez également:

git checkout HEAD^ foo

pour une révision en arrière, etc.

258
Greg Hewgill

Et pour revenir à la dernière version validée, qui est le plus souvent nécessaire, vous pouvez utiliser cette commande plus simple.

git checkout HEAD file/to/restore
114
CDR

J'avais le même problème tout à l'heure et j'ai trouvé cette réponse le plus facile à comprendre (commit-ref est la valeur SHA de la modification dans le journal vers lequel vous souhaitez revenir):

git checkout [commit-ref] [filename]

Cela mettra cette ancienne version dans votre répertoire de travail et à partir de là, vous pourrez la commettre si vous le souhaitez.

103
bbrown

Si vous savez combien d’engagements vous devez revenir en arrière, vous pouvez utiliser:

git checkout master~5 image.png

Cela suppose que vous êtes sur la branche master et que la version souhaitée est de 5 commits.

88
Ron DeVera

Je pense l'avoir trouvé .... de http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

Parfois, vous voulez simplement revenir en arrière et oublier chaque changement passé un certain point, car ils sont tous faux. 

Commencer avec:

$ git log

qui vous montre une liste des commits récents, ainsi que leurs hachages SHA1. 

Ensuite, tapez:

$ git reset --hard SHA1_HASH

restaurer l'état à un commit donné et effacer définitivement tous les nouveaux commits de l'enregistrement.

78
jdee

Cela a fonctionné pour moi:

git checkout <commit hash> file

Puis commettez le changement:

git commit -a
61
v2k

Vous devez faire attention quand vous dites "rollback". Si vous utilisiez une version d’un fichier dans commit $ A, puis que vous apportiez ensuite deux modifications dans deux commits distincts $ B et $ C (vous voyez donc la troisième itération du fichier), et si vous dites " Je veux revenir à la première ", tu le penses vraiment? 

Si vous voulez vous débarrasser des modifications à la fois de la deuxième et de la troisième itérations, c'est très simple:

$ git checkout $A file

et ensuite vous commettez le résultat. La commande demande "Je veux extraire le fichier de l'état enregistré par le commit $ A".

De l’autre côté, vous vouliez supprimer le changement apporté par la deuxième itération (c’est-à-dire commit $ B), tout en conservant ce que commit $ C avait fait pour le fichier, vous voudriez revenir en arrière $ B

$ git revert $B

Notez que celui qui a créé commit $ B n’est peut-être pas très discipliné et a peut-être commis des modifications totalement non liées dans le même commit, et cette annulation peut toucher des fichiers autres que file vous voyez des modifications offensantes. résultat soigneusement après l'avoir fait.

54
gitster

Curieusement, 'git checkout foo' ne fonctionnera pas si la copie de travail se trouve dans un répertoire nommé foo; Cependant, 'git checkout HEAD foo' et 'git checkout ./foo':

$ pwd
/Users/aaron/Documents/work/foo
$ git checkout foo
D   foo
Already on "foo"
$ git checkout ./foo
$ git checkout HEAD foo
36
Aaron Maenpaa

Voici comment fonctionne rebase:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>

Suppose que tu as

---o----o----o----o  master
    \---A----B       <my branch>

Les deux premières commandes ... Commit git checkout maître git rebase

... consultez la branche des modifications que vous souhaitez appliquer à la branche master. La commande rebase prend les commits de <my branch> (qui ne se trouvent pas dans master) et les réapplique à la tête de master. En d'autres termes, le parent du premier commit dans <my branch> n'est plus un commit précédent dans l'historique master, mais la tête actuelle de master. Les deux commandes sont les mêmes que:

git rebase master <my branch>

Il peut être plus facile de se souvenir de cette commande car les branches "base" et "modify" sont explicites.

. Le résultat final de l'histoire est:

---o----o----o----o   master
                   \----A'----B'  <my branch>

Les deux dernières commandes ...

git checkout master
git merge <my branch>

... effectuez une fusion rapide pour appliquer toutes les modifications <my branch> à master. Sans cette étape, la validation de la base ne sera pas ajoutée à master. Le résultat final est:

---o----o----o----o----A'----B'  master, <my branch>

master et <my branch> font tous deux référence B'. En outre, à partir de ce point, il est prudent de supprimer la référence <my branch>.

git branch -d <my branch>
32
cmcginty

git-aliases, awk et Shell-fonctions à la rescousse!

git prevision <N> <filename>

<N> est le nombre de révisions du fichier à restaurer pour le fichier <filename>.
Par exemple, pour extraire la révision précédente immédiate d’un seul fichier x/y/z.c, exécutez

git prevision -1 x/y/z.c

Comment fonctionne la prévision git?

Ajoutez ce qui suit à votre gitconfig

[alias]
        prevision = "!f() { git checkout `git log --oneline $2 |  awk -v commit="$1" 'FNR == -commit+1 {print $1}'` $2;} ;f"

La commande essentiellement

  • effectue un git log sur le fichier spécifié et 
  • choisit le commit-id approprié dans l'historique du fichier et 
  • exécute un git checkout dans le commit-id pour le fichier spécifié.

Essentiellement, tout ce que l'on ferait manuellement dans cette situation,
enveloppé dans un beau et efficace git-alias - git-prevision

21
TheCodeArtist

Première tête de réinitialisation pour le fichier cible

git reset HEAD path_to_file

Deuxième extraction de ce fichier

git checkout -- path_to_file
21
Gulshan Maurya

Dans le cas où vous souhaitez rétablir un fichier dans une validation précédente (et le fichier que vous souhaitez restaurer déjà validé), vous pouvez utiliser

git checkout HEAD^1 path/to/file

ou

git checkout HEAD~1 path/to/file

Ensuite, mettez en scène et validez la "nouvelle" version.

Sachant qu’un commit peut avoir deux parents en cas de fusion, vous devez savoir que HEAD ^ 1 est le premier parent et HEAD ~ 1 est le deuxième parent.

L'un ou l'autre fonctionnera s'il n'y a qu'un seul parent dans l'arbre.

20
ModernIncantations

Je dois brancher EasyGit ici, qui est un wrapper pour rendre git plus accessible aux novices sans dérouter les utilisateurs chevronnés. Une des choses qu'il fait est donne plus de significations à git revert . Dans ce cas, vous diriez simplement:

eg revertfoo/bar foo/baz

20

Notez cependant que git checkout ./foo et git checkout HEAD ./foo Ne sont pas exactement la même chose; Exemple:

$ echo A > foo
$ git add foo
$ git commit -m 'A' foo
Created commit a1f085f: A
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
$ echo B >> foo
$ git add foo
$ echo C >> foo
$ cat foo
A
B
C
$ git checkout ./foo
$ cat foo
A
B
$ git checkout HEAD ./foo
$ cat foo
A

(La seconde add met le fichier dans l'index, mais il ne n'est pas récupéré Commit.)

Git checkout ./foo signifie rétablir le chemin ./foo à partir de index ; ajouter HEAD demande à Git de rétablir ce chemin dans l'index en sa révision .__HEAD avant de le faire.

19
Damien Diederen

Beaucoup de suggestions ici, la plupart allant dans le sens de git checkout $revision -- $file. Quelques alternatives obscures:

git show $revision:$file > $file

Et aussi, je l’utilise beaucoup juste pour voir une version particulière temporairement:

git show $revision:$file

ou

git show $revision:$file | vim -R -

(OBS: $file doit être préfixé par ./ s'il s'agit d'un chemin relatif pour que git show $revision:$file fonctionne)

Et le plus étrange encore:

git archive $revision $file | tar -x0 > $file
14
Peter V. Mørch

Pour moi, aucune des réponses ne m'a semblé très claire et par conséquent, j'aimerais ajouter la mienne, ce qui semble super facile. 

J'ai un commit abc1 et après j'ai effectué plusieurs modifications (ou une modification) dans un fichier file.txt.

Maintenant, dis que j'ai foiré quelque chose dans le fichier file.txt et que je veux revenir à un commit précédent abc1.

1 .git checkout file.txt: cela supprimera les modifications locales, si vous n'en avez pas besoin

2 .git checkout abc1 file.txt: cela amènera votre fichier à votre version wanted

3 .git commit -m "Restored file.txt to version abc1": cela va valider votre réversion.

  1. git Push: cela poussera tout sur le référentiel distant 

Entre l'étape 2 et l'étape 3, vous pouvez bien sûr faire git status pour comprendre ce qui se passe. Généralement, vous devriez voir le file.txt déjà ajouté et c’est pourquoi il n’est pas nécessaire de disposer d’un git add.

11

Pour accéder à une version de validation précédente du fichier, obtenez le numéro de validation, dites eb917a1 .__ 

git checkout eb917a1 YourFileName

Si vous avez juste besoin de revenir à la dernière version validée

git reset HEAD YourFileName
git checkout YourFileName

Cela vous mènera simplement au dernier état de fichier validé

11
shah1988

git checkout réf | commitHash - cheminFichier

par exemple. 

git checkout HEAD~5 -- foo.bar
or 
git checkout 048ee28 -- foo.bar
10
Amos Folarin

Utilisez git log pour obtenir la clé de hachage pour une version spécifique, puis utilisez git checkout <hashkey>

Remarque: N'oubliez pas de taper le hachage avant le dernier. Le dernier hash indique votre position actuelle (HEAD) et ne change rien.

8
mustafakyr

Beaucoup de réponses ici prétendent utiliser git reset ... <file> ou git checkout ... <file> mais, ce faisant, vous perdrez toutes les modifications sur <file> validées après le commit que vous souhaitez annuler.

Si vous souhaitez annuler les modifications d'une validation sur un seul fichier, comme le ferait git revert mais uniquement pour un fichier (ou un sous-ensemble des fichiers de validation), je suggère d'utiliser à la fois git diff et git apply comme cela (avec <sha> = le hachage du commit que vous voulez annuler):

git diff <sha>^ <sha> path/to/file.ext | git apply -R

Fondamentalement, il générera d’abord un correctif correspondant aux modifications que vous souhaitez annuler, puis inversez-le pour appliquer ces modifications.

Bien sûr, cela ne fonctionnera pas si les lignes annulées ont été modifiées par un commit entre <sha1> et HEAD (conflit).

8
Vince

Il est évident que quelqu'un doit écrire un livre intelligible sur git ou qu'il doit être mieux expliqué dans la documentation. Face à ce même problème, j'ai deviné que 

cd <working copy>
git revert master

annulerait le dernier commit qui semble avoir été fait.

Ian

7
Ian Davis

si vous commettez un mauvais fichier lors de vos derniers commits, suivez les instructions:

  1. arborescence open source, passez à ce commit

 open source tree

  1. changer les lignes et trouver votre commit que le mauvais fichier envoyé en commit

 enter image description here

  1. vous pouvez voir la liste de vos modifications dans ce commit  list of files in the source tree
  2. sélectionnez-le puis cliquez sur ... boutons à droite ... cliquez sur le fichier inversé
  3. puis vous pouvez le voir sur l'onglet statut du fichier en bas à gauche puis cliquez sur unstage:

 file status tab

  1. ouvrez votre code visual studio et revenez en arrière en validant les fichiers supprimés
  2. après tout, vous pouvez voir les résultats dans votre dernier commit dans l'arbre source

 enter image description here

5
git revert <hash>

Reviendra sur un commit donné. On dirait que vous pensez que git revert n'affecte que le dernier commit.

Cela ne résout pas votre problème si vous souhaitez annuler une modification dans un fichier spécifique et que la validation a changé plus que ce fichier.

4
Otto

Vous pouvez le faire en 4 étapes:

  1. rétablir le commit complet avec le fichier que vous voulez spécifiquement restaurer - cela créera un nouveau commit sur votre branche
  2. réinitialisation logicielle qui valide - supprime la validation et déplace les modifications vers la zone de travail
  3. triez les fichiers à la main pour les récupérer et les valider
  4. déposer tous les autres fichiers dans votre espace de travail

Ce que vous devez taper dans votre terminal :

  1. git revert <commit_hash>
  2. git reset HEAD~1
  3. git add <file_i_want_to_revert> && git commit -m 'reverting file'
  4. git checkout .

bonne chance

3
Nir M.

C'est une étape très simple. Vérifier le fichier avec l'identifiant de validation que nous voulons, ici un identifiant de validation avant, puis git commit amend et nous avons terminé.

# git checkout <previous commit_id> <file_name>
# git commit --amend

C'est très pratique. Si nous voulons apporter n'importe quel fichier à n'importe quel identifiant de commit précédent en haut du commit, nous pouvons le faire facilement.

2
Abhishek Dwivedi
  1. Git rétablit le fichier sur un commit spécifique

git checkout Last_Stable_commit_Number - NomFichier

2.Git restaurer le fichier dans une branche spécifique

git checkout branchName_Which_Has_stable_Commit fileName
1
ireshika piyumalie

Voici mon chemin.

a) Dans Android Studio, ouvrez le fichier.

b) git -> Show History, trouvez le commit précédent auquel je veux revenir. Obtenez le commit_id (c'est-à-dire un hachage de commit).

c) git checkout commit_id file_path

1
Francis Bacon

Si vous utilisez Git Extensions et que vous souhaitez uniquement rétablir la validation parent pour le fichier, vous pouvez sélectionner la validation qui contient les modifications à restaurer, puis sélectionnez l'onglet "Diff" dans le volet d'informations, puis cliquez avec le bouton droit de la souris. le fichier que vous voulez rétablir, puis 'Réinitialiser le (s) fichier (s) à' ...., puis 'A' (le parent)

1
Chris Halcrow

A partir de git v2.23.0, il existe une nouvelle méthode git restore qui est supposée assumer une partie de ce que git checkout était responsable (même la réponse acceptée indique que git checkout est assez déroutant. ). Voir les points saillants des changements sur blog github .

Le comportement par défaut de cette commande est de restaurer l'état d'un arbre de travail avec le contenu provenant du paramètre source (qui dans votre cas sera un hachage de validation).

Donc, basé sur la réponse de Greg Hewgill (en supposant que le hachage de validation est c5f567), la commande ressemblerait à ceci:

git restore --source=c5f567 file1/to/restore file2/to/restore

Ou si vous souhaitez restaurer le contenu d'un commit avant c5f567:

git restore --source=c5f567~1 file1/to/restore file2/to/restore
0
mjarosie