7615 votes

Revenir à un commit Git précédent

Comment puis-je revenir de mon état actuel à un instantané réalisé lors d'un certain commit ?

Si je le fais git log j'obtiens le résultat suivant :

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Comment revenir au commit du 3 novembre, c'est-à-dire le commit 0d1d7fc ?

10 votes

116 votes

Voici un billet très clair et complet sur le fait d'annuler des choses dans git, directement depuis Github.

58 votes

J'adore git, mais le fait qu'il y ait 35 réponses à quelque chose qui devrait être incroyablement simple expose un énorme problème avec git. Ou est-ce la documentation ?

11772voto

Jefromi Points 127932

Cela dépend beaucoup de ce que vous entendez par "retour en arrière".

Passer temporairement à un autre commit

Si vous voulez y retourner temporairement, faire des folies, puis revenir là où vous êtes, il vous suffit de vérifier le commit souhaité :

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

Ou si vous voulez faire des commits pendant que vous êtes là, allez-y et créez une nouvelle branche pendant que vous y êtes :

git checkout -b old-state 0d1d7fc32

Supprimer définitivement les commits non publiés

Si, par contre, vous voulez vraiment vous débarrasser de tout ce que vous avez fait depuis, il y a deux possibilités. La première, si vous n'avez publié aucun de ces commits, il suffit de réinitialiser :

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

Annuler les commits publiés avec les nouveaux commits

D'un autre côté, si vous avez publié le travail, vous ne voulez probablement pas réinitialiser la branche, car cela revient à réécrire l'histoire. Dans ce cas, vous pouvez effectivement inverser les commits. Avec Git, revert a une signification très spécifique : créer un commit avec le patch inverse pour l'annuler. De cette façon, vous ne réécrivez pas l'histoire.

# This will create three separate revert commits:
git revert 0766c053 25eee4ca a867b4af

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

Le site git-revert page d'accueil couvre en fait beaucoup de ces aspects dans sa description. Un autre lien utile est cet article du blog de git-scm.com discutant de git-revert .

178 votes

Commentaire de @Rod sur git revert HEAD~3 comme le meilleur moyen de revenir en arrière 3 commits est une convention importante.

32 votes

Tu peux écrire le nombre entier ? Comme : git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

20 votes

@MathiasMadsenStav Oui, vous pouvez bien sûr spécifier les commits par le SHA1 complet. J'ai utilisé des hachages abrégés pour rendre la réponse plus lisible, et vous avez également tendance à les utiliser si vous tapez. Si vous copiez et collez, utilisez le hachage complet. Voir Spécifier les révisions dans man git rev-parse pour une description complète de la façon dont vous pouvez nommer les commits.

3217voto

Yarin Points 18186

Beaucoup de réponses compliquées et dangereuses ici, mais c'est en fait facile :

git revert --no-commit 0766c053..HEAD
git commit

Cela rétablira tout depuis le HEAD vers le hash commit, ce qui signifie que cela recréera l'état du commit dans l'arbre de travail. comme si tous les engagements pris depuis ont été annulés. Vous pouvez alors commiter l'arbre actuel, et il créera un tout nouveau commit essentiellement équivalent au commit sur lequel vous avez fait marche arrière.

(Le --no-commit permet à git de rétablir tous les commits en une seule fois - sinon, un message vous sera demandé pour chaque commit de la plage, ce qui jonchera votre historique de nouveaux commits inutiles).

Il s'agit d'un un moyen sûr et facile de revenir à un état antérieur . Aucun historique n'est détruit, il peut donc être utilisé pour des commits qui ont déjà été rendus publics.

41 votes

Si vous voulez vraiment avoir des commits individuels (au lieu de tout rétablir avec un seul gros commit), vous pouvez passer la commande --no-edit au lieu de --no-commit de sorte que vous n'ayez pas à éditer un message commit pour chaque réversion.

162 votes

Si l'un des commits entre 0766c053..HEAD est une fusion, alors il y aura une erreur qui apparaîtra (à faire avec aucun -m spécifié). Ceci peut aider ceux qui rencontrent ce problème : stackoverflow.com/questions/5970889/

40 votes

$ git revert --no-commit 53742ae..HEAD renvoie à fatal: empty commit set passed

1984voto

boulder_ruby Points 6257

Rétablissement de la copie de travail à la version la plus récente

Pour revenir au commit précédent, en ignorant tous les changements :

git reset --hard HEAD

où HEAD est le dernier commit dans votre branche actuelle

Rétablissement de la copie de travail à une version antérieure de l'engagement

Pour revenir à un commit qui est plus ancien que le commit le plus récent :

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Crédits pour question similaire @ Revenir à un commit par hachage SHA ? .

53 votes

Je l'ai fait, mais ensuite je n'ai pas été capable de commiter et de pousser vers le dépôt distant. Je veux qu'un ancien commit spécifique devienne HEAD...

13 votes

@Lennon. Disons que vous avez fait une modification, l'avez validée et l'avez poussée. Vous voulez que le local et le distant apparaissent comme si cela n'était jamais arrivé. D'abord git reset --hard HEAD^ Vous avez maintenant effacé toutes les modifications locales du dernier commit. Alors : git push --force origin HEAD Cela prend le commit HEAD actuel dans le local et écrase le HEAD dans le distant, en supprimant le dernier commit. Note : Ce n'est pas un moyen sûr d'effacer les secrets accidentellement poussés sur un serveur distant. Supposez que tous les secrets sont compromis, alors voyez les avertissements pour '--force' : evilmartians.com/chronicles/

0 votes

Après la réinitialisation, vous devez faire git push -f . Faites TRÈS attention car cela effacera les commits qui précèdent celui que vous réinitialisez à partir de votre branche distante !

290voto

Pogrindis Points 1247

La meilleure option pour moi et probablement pour d'autres est l'option de réinitialisation de Git :

git reset --hard <commidId> && git clean -f

C'est la meilleure option pour moi ! C'est simple, rapide et efficace !

58 votes

Avertissement obligatoire : ne faites pas ça si vous partagez votre branche avec d'autres personnes qui ont des copies des anciens commits, parce que l'utilisation d'un hard reset comme celui-ci les obligera à resynchroniser leur travail avec la branche nouvellement réinitialisée. Pour une solution qui explique en détail comment rétablir les commits en toute sécurité sans perdre le travail avec une réinitialisation dure, voir cette réponse .

1 votes

Il est important de noter que cela supprimera définitivement tous les fichiers non validés dans votre répertoire source :/.

125voto

Roman Minenok Points 2075

J'ai essayé de nombreuses façons de revenir sur des modifications locales dans Git, et il semble que cette méthode soit la plus efficace si vous souhaitez simplement revenir au dernier état de la livraison.

git add . && git checkout master -f

Brève description :

  • Il ne créera PAS de commits en tant que git revert fait.
  • Il ne détachera pas votre tête comme git checkout <commithashcode> fait.
  • Il remplacera toutes vos modifications locales et SUPPRIMERa tous les fichiers ajoutés depuis le dernier commit de la branche.
  • Cela ne fonctionne qu'avec les noms de branches, donc vous ne pouvez revenir qu'au dernier commit de la branche de cette façon.

J'ai trouvé un moyen beaucoup plus pratique et simple d'obtenir les résultats ci-dessus :

git add . && git reset --hard HEAD

où HEAD pointe vers le dernier commit de votre branche actuelle.

C'est le même code que celui proposé par boulder_ruby, mais j'ai ajouté git add . avant git reset --hard HEAD pour effacer tous les nouveaux fichiers créés depuis la dernière livraison, puisque c'est ce que la plupart des gens attendent, je crois, lorsqu'ils reviennent à la dernière livraison.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X