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é.
29 réponses
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).
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>
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]
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.
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
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.
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.
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.
cela a fonctionné pour moi:
git checkout <commit hash> file
puis commit le changement:
git commit -a
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.
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
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>
git-alias, awk et shell-fonctions à la rescousse!
git prevision <N> <filename>
où <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
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
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.
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.
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
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
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
git checkout ref / commihash -- filePath
p.ex.
git checkout HEAD~5 -- foo.bar
or
git checkout 048ee28 -- foo.bar
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.
-
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
.
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.
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
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).
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.
si vous commettez un faux fichier dans votre dernier commit, suivez l'instruction:
- open source arbre, changement à ce commit
- changez les lignes et trouvez votre commit que le mauvais fichier envoyé comme commit
- vous pouvez voir la liste de vos changements qui s'engagent
- sélectionnez-le puis cliquez sur ... les boutons de droite ... cliquez sur Fichier inversé
- alors vous pouvez le voir sur l'onglet État du fichier en bas à gauche puis cliquez sur unstage:
- ouvrez votre visuel Code studio et revenir en arrière en commettant vos dossiers supprimés
- après eux tous, vous pouvez voir les résultats dans votre dernier commit dans l'arbre source
vous pouvez le faire en 4 étapes:
- 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
- soft reset that commit-supprime la propagation et déplace les changements dans la zone de travail
- sélectionner les fichiers à revenir et à s'engager
- déposer tous les autres fichiers dans votre zone de travail
ce que vous devez taper dans votre terminal :
-
git revert <commit_hash>
-
git reset HEAD~1
-
git add <file_i_want_to_revert>
&&git commit -m 'reverting file'
-
git checkout .
bonne chance
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
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)