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

j'ai fait quelques modifications à un fichier qui a été engagé à quelques reprises dans un groupe de fichiers, mais je veux maintenant réinitialiser/retourner les modifications à une version précédente.

j'ai fait un git log avec un git diff pour trouver la révision dont j'ai besoin, mais je n'ai tout simplement aucune idée de la façon de ramener le fichier à son état antérieur dans le passé.

3591
demandé sur ROMANIA_engineer 2008-10-19 03:34:02
la source

29 ответов

en supposant que le hachage du commit que vous voulez est c5f567 :

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

Le git checkout l'homme page donne plus d'informations.

si vous voulez revenir à la propagation avant c5f567 , ajoutez ~1 (fonctionne avec n'importe quel nombre):

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

comme note secondaire, j'ai toujours été mal à l'aise avec cette commande parce qu'elle est utilisée pour les deux choses ordinaires (changer entre branches) et des choses inhabituelles, destructrices (élimination des changements dans le répertoire de travail).

4843
répondu Greg Hewgill 2018-01-19 13:35:41
la source

vous pouvez rapidement passer en revue les modifications apportées à un fichier en utilisant la commande diff:

git diff <commit hash> <filename>

ensuite, pour retourner un fichier spécifique à cette propagation, 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 est d'utiliser des tags pour marquer proprement les points dans votre ligne de temps. Je ne peux pas tout à fait comprendre votre dernière phrase mais ce qui vous pouvez vouloir est diverger une branche d'un point précédent dans le temps. Pour ce faire, utilisez la commande caisse pratique:

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

vous pouvez alors rebaser que contre votre ligne principale lorsque vous êtes prêt à fusionner ces changements:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>
521
répondu Chris Lloyd 2008-12-17 09:59:33
la source

vous pouvez utiliser n'importe quelle référence à un git commit, y compris le SHA-1 si c'est le plus pratique. Le point est que la commande ressemble à ceci:

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

311
répondu foxxtrot 2014-04-29 16:22:45
la source
git checkout -- foo

qui réinitialisera foo à la tête. Vous pouvez aussi:

git checkout HEAD^ foo

pour une révision précédente, etc.

252
répondu Greg Hewgill 2013-03-18 11:47:14
la source

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

git checkout HEAD file/to/restore
108
répondu CDR 2012-01-14 10:15:35
la source

j'ai eu le même problème tout à l'heure et j'ai trouvé cette réponse plus facile à comprendre ( commit-ref est la valeur SHA du changement dans le log que vous voulez retourner à):

git checkout [commit-ref] [filename]

cela va mettre cette ancienne version dans votre répertoire de travail et de là vous pouvez la propager si vous voulez.

101
répondu bbrown 2017-05-23 14:47:31
la source

si vous savez combien de propagations vous devez retourner, Vous pouvez utiliser:

git checkout master~5 image.png

cela suppose que vous êtes sur la branche master , et la version que vous voulez est 5 commits back.

87
répondu Ron DeVera 2012-06-01 11:06:19
la source

je crois que je l'ai trouvé....de http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

parfois vous voulez juste revenir en arrière et oublier chaque changement passé un certain point parce qu'ils sont tous faux.

commence par:

$ git log

qui vous montre une liste de commits récents, et leurs hachures SHA1.

suivant, type:

$ git reset --hard SHA1_HASH

pour restaurer l'état d'un commit et effacer tous les nouveaux commits de la permanence.

77
répondu jdee 2011-11-20 04:55:15
la source

cela a fonctionné pour moi:

git checkout <commit hash> file

puis commit le changement:

git commit -a
61
répondu v2k 2011-08-26 02:12:22
la source

Vous devez être prudent lorsque vous dites "rollback". Si vous aviez l'habitude d'avoir une version d'un fichier dans commit $A, et que vous avez ensuite fait deux changements en deux propagations séparées $B et $C (donc ce que vous voyez est la troisième itération du fichier), et si vous dites "je veux revenir à la première", le pensez-vous vraiment?

si vous voulez vous débarrasser des changements à la fois la deuxième et la troisième itération, il est très simple:

$ git checkout $A file

et puis vous validez la suite. La commande demande "je veux vérifier le fichier à partir de l'état enregistré par le commit $".

d'un autre côté, ce que vous vouliez dire est de se débarrasser du changement la deuxième itération (i.e. commit $B) apporté, tout en gardant ce que commit $C a fait au fichier, vous voudriez revenir $b

$ git revert $B

notez que celui qui a créé commit $B peut ne pas avoir été très discipliné et peut avoir commis des changements totalement sans rapport dans le même commit, et ce revert peut toucher des fichiers autres que file vous voyez des modifications offensives, vous pouvez donc vérifier le résultat avec soin après avoir fait cela.

54
répondu 2009-01-11 11:13:39
la source

de façon amusante, "git checkout foo" ne fonctionnera pas si la copie de travail est dans un répertoire nommé foo; cependant, à la fois "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
répondu Aaron Maenpaa 2014-04-29 16:22:01
la source

Voici comment rebase fonctionne:

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

supposons que vous avez

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

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

... consultez la branche des changements que vous voulez appliquer à la branche master . La commande rebase prend les commits de <my branch> (qui sont non trouvé dans master ) et les réappose sur 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'histoire master , mais la tête actuelle de master . Les deux commandes sont les mêmes que:

git rebase master <my branch>

il pourrait être plus facile de se souvenir de cette commande car les branches" base "et" modifier " sont toutes deux 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>

... faites une fusion accélérée pour appliquer tous les changements de <my branch> à master . Sans cette étape, la propagation de rebase ne sera pas ajoutée à master . Le résultat final est:

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

master et <my branch> référence B' . Aussi, à partir de ce point il est sans danger de supprimer la référence <my branch> .

git branch -d <my branch>
32
répondu cmcginty 2014-04-29 16:21:47
la source

git-alias, awk et shell-fonctions à la rescousse!

git prevision <N> <filename>

<N> est le nombre de révisions du fichier pour le fichier <filename> .

Par exemple, pour vérifier la révision précédente immédiate d'un fichier unique x/y/z.c , Lancez

git prevision -1 x/y/z.c

comment git prevision fonctionne-t-il?

ajouter ce qui suit à votre gitconfig

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

la commande essentiellement

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

essentiellement, tout ce que l'on ferait manuellement dans cette situation,
1519150920" enveloppé dans une belle, efficace git-alias - git-prévision

21
répondu TheCodeArtist 2016-01-22 11:14:18
la source

je dois brancher EasyGit ici, qui est un wrapper pour faire git plus accessible pour les novices, sans confusion des utilisateurs expérimentés. Une des choses qu'il fait est donner plus de sens à git revert . Dans ce cas, vous diriez simplement:

eg revert foo/bar foo/baz

20
répondu Aristotle Pagaltzis 2013-11-10 21:59:56
la source

dans le cas où vous voulez retourner un fichier à une propagation précédente (et le fichier que vous voulez inverser déjà engagé), vous pouvez utiliser

git checkout HEAD^1 path/to/file

ou

git checkout HEAD~1 path/to/file

alors il suffit de mettre en scène et de commettre la "nouvelle" version.

armé de la connaissance qu'un commit peut avoir deux parents dans le cas d'une fusion, vous devriez savoir que HEAD^1 est le premier parent et HEAD~1 est le second parent.

Les deux marchent si il y a un seul parent dans l'arbre.

20
répondu ModernIncantations 2014-01-11 04:29:50
la source

noter, cependant, que git checkout ./foo et git checkout HEAD ./foo ne sont pas exactement la même chose; cas en point:

$ 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

(le deuxième add étapes le fichier dans l'index, mais il ne pas obtenir engager.)

Git checkout ./foo signifie revenir chemin ./foo de la index ; l'ajout de HEAD demande à Git de retourner ce chemin dans l'index à son HEAD révision avant de le faire.

18
répondu Damien Diederen 2014-04-29 16:21:11
la source

Tout D'Abord Rétablir La Tête Pour Le Fichier Cible

git reset HEAD path_to_file

Deuxième Caisse Fichier

git checkout -- path_to_file
17
répondu Gulshan Maurya 2017-04-04 13:25:08
la source

beaucoup de suggestions ici, la plupart dans le sens de git checkout $revision -- $file . Un couple d'obscurs alternatives:

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é avec ./ si c'est un chemin relatif pour git show $revision:$file travailler)

Et encore plus bizarre:

git archive $revision $file | tar -x0 > $file
13
répondu Peter V. Mørch 2018-02-18 02:05:02
la source

pour accéder à une version de propagation précédente du fichier, obtenir le numéro de propagation, par exemple eb917a1 puis

git checkout eb917a1 YourFileName

si vous avez juste besoin de revenir à la dernière version commitée

git reset HEAD YourFileName
git checkout YourFileName

cela vous mènera simplement au dernier état engagé du dossier

11
répondu shah1988 2014-02-25 18:01:20
la source

git checkout ref / commihash -- filePath

p.ex.

git checkout HEAD~5 -- foo.bar
or 
git checkout 048ee28 -- foo.bar
10
répondu Amos Folarin 2013-09-26 21:04:32
la source

pour moi aucune de la réponse ne semblait vraiment claire et donc je voudrais ajouter la mienne qui semble super facile.

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

Maintenant dire que j'ai foiré quelque chose dans le fichier file.txt et je veux revenir à une précédente livraison abc1 .

1. git checkout file.txt : ce sera supprimer les modifications locales, si vous n'en avez pas besoin

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

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

  1. git push : cela poussera tout sur le dépôt distant

entre l'étape 2 et l'étape 3, Bien sûr, vous pouvez faire git status pour comprendre ce qui se passe. Habituellement, vous devriez voir le file.txt déjà ajouté et c'est pourquoi il n'est pas besoin d'un git add .

10
répondu kalmanIsAGameChanger 2017-03-23 00:33:50
la source

utiliser git log pour obtenir la clé de hachage pour une version spécifique et ensuite utiliser git checkout <hashkey>

Note: n'oubliez pas de taper le hachage avant le dernier. Le dernier hachage pointe votre position actuelle (tête) et ne change rien.

8
répondu mustafakyr 2012-11-05 08:25:28
la source

de toute Évidence quelqu'un doit écrire un intelligible livre sur git, ou git 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, ce qui semble être le cas.

Ian

7
répondu Ian Davis 2011-12-16 07:40:53
la source

beaucoup de réponses prétendent utiliser git reset ... <file> ou git checkout ... <file> mais en faisant cela, vous perdrez toutes les modifications sur <file> commis après la propagation que vous voulez revenir.

si vous voulez revenir sur les changements d'une propagation sur un seul fichier, tout comme git revert ne le ferait que pour un seul fichier( ou disons un sous-ensemble des fichiers de propagation), je suggère d'utiliser à la fois git diff et git apply comme cela (avec <sha> = le hachage de la propagation vous vouloir revenir) :

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

en gros, il générera d'abord un patch correspondant aux changements que vous voulez revenir en arrière, et ensuite inverser-appliquer le patch pour supprimer ces changements.

bien sûr, il ne fonctionnera pas si les lignes renversées ont été modifiées par une commit entre <sha1> et HEAD (conflit).

6
répondu Vince 2016-12-07 17:43:49
la source
git revert <hash>

renverra une propagation donnée. On dirait que vous pensez que git revert n'affecte que la propagation la plus récente.

cela ne résout pas votre problème, si vous voulez revenir sur une modification dans un fichier spécifique et que commit a changé plus que ce fichier.

4
répondu Otto 2008-12-17 21:56:14
la source

si vous commettez un faux fichier dans votre dernier commit, suivez l'instruction:

  1. open source arbre, changement à ce commit

open source tree

  1. changez les lignes et trouvez votre commit que le mauvais fichier envoyé comme commit

enter image description here

  1. vous pouvez voir la liste de vos changements qui s'engagent list of files in the source tree
  2. sélectionnez-le puis cliquez sur ... les boutons de droite ... cliquez sur Fichier inversé
  3. alors vous pouvez le voir sur l'onglet État du fichier en bas à gauche puis cliquez sur unstage:

file status tab

  1. ouvrez votre visuel Code studio et revenir en arrière en commettant vos dossiers supprimés
  2. après eux tous, vous pouvez voir les résultats dans votre dernier commit dans l'arbre source

enter image description here

4
répondu saber tabatabaee yazdi 2018-08-23 12:53:27
la source

vous pouvez le faire en 4 étapes:

  1. renvoie l'intégralité de la propagation avec le fichier que vous voulez inverser spécifiquement - il créera une nouvelle propagation sur votre branche
  2. soft reset that commit-supprime la propagation et déplace les changements dans la zone de travail
  3. sélectionner les fichiers à revenir et à s'engager
  4. déposer tous les autres fichiers dans votre zone 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
répondu Nir M. 2018-05-08 13:26:21
la source

voici ma façon.

a) dans Android Studio, ouvrir le fichier.

b) git -> Afficher l'Historique, de trouver de la précédente livraison, je veux revenir. Obtenir le commit_id (c'est à dire s'engager de hachage).

c) git checkout commit_id file_path

1
répondu Francis Bacon 2017-03-13 11:15:36
la source

si vous utilisez des Extensions Git et que vous voulez seulement revenir à la propagation mère pour le fichier, vous pouvez sélectionner la propagation qui contient les changements que vous voulez inverser, puis sélectionnez l'onglet "Diff" dans le volet Détails, droit-cliquez sur le fichier que vous voulez inverser, puis "Réinitialiser le(S) fichier (s) à"...., puis 'A' (le parent)

1
répondu Chris Halcrow 2017-09-26 04:48:14
la source

Autres questions sur git version-control