711 votes

Revenir à un commit par un hash SHA dans Git ?

Je ne suis pas sûr de savoir comment git revert fonctionne. Par exemple, je veux revenir à un commit situé six commits derrière le head, en annulant tous les changements dans les commits intermédiaires entre les deux.

Dites que son SHA Le hachage est 56e05fced214c44a37759efa2dfc25a65d8ae98d . Alors pourquoi je ne peux pas juste faire quelque chose comme :

git revert 56e05fced214c44a37759efa2dfc25a65d8ae98d

1 votes

Même si cette question est en fait plus ancienne que celle dont elle est maintenant marquée comme un doublon, celle-ci a une meilleure réponse. meta.stackexchange.com/questions/147643/

18 votes

Cette question et la réponse qui y figure peuvent prêter à confusion pour les utilisateurs de git. Pour aider à comprendre la terminologie, vous ne devez pas revenir à un engagement. Vous pouvez soit réinitialisé à un commit (ce qui revient à remonter le temps avec la machine à remonter le temps) ou revenir à un commit (ce qui revient à retirer un commit comme s'il n'avait jamais existé - cependant, cela préserve les informations de revert dans l'historique, vous permettant de revenir sur un revert si vous le souhaitez) Notez également que vous ne devriez pas utiliser le drapeau m et taper un message de commit si vous obtenez des conflits dans le processus. Le message automatique fourni par git est plus informatif lorsqu'on regarde dans l'historique.

1 votes

C'est un très bon retour d'information. Merci @alexrogins

1303voto

Charles Bailey Points 244082

Si vous voulez commiter par dessus le HEAD actuel avec l'état exact d'un autre commit, en annulant tous les commits intermédiaires, alors vous pouvez utiliser reset pour créer l'état correct de l'index pour faire le commit.

# Reset the index and working tree to the desired tree
# Ensure you have no uncommitted changes that you want to keep
git reset --hard 56e05fced

# Move the branch pointer back to the previous HEAD
git reset --soft "HEAD@{1}"

git commit -m "Revert to 56e05fced"

88 votes

Ne serait-il pas équivalent (et plus court d'une commande) de faire : git reset --hard 56e05fced comme première commande, et ensuite sauter la dernière commande git reset --hard ?

26 votes

Quand j'ai fait ça, je me suis retrouvé avec un tas de Untracked Files dans l'arbre de travail. Cependant, en regardant l'historique, j'ai pu voir que ces fichiers avaient un commit de suppression correspondant dans ce commit "Revert to SHA". Donc après git reset --hard à la fin, vous pouvez faire git clean -f -d pour nettoyer tous les fichiers non tracés qui traînent. Aussi, merci beaucoup, cela m'a aidé à résoudre une crise !

5 votes

Dois-je faire le git reset --soft HEAD@{1} sans condition ? Je veux dire toujours avec une valeur de 1 ?

176voto

Jakub Narębski Points 87537

Qué git-revert fait est de créer un commit qui annule les changements faits dans un commit donné, créant un commit qui est l'inverse (enfin, réciproque) d'un commit donné. Par conséquent,

git revert <SHA-1>

devrait fonctionner et fonctionne.

Si vous voulez revenir en arrière à un commit spécifié, et que vous pouvez le faire parce que cette partie de l'histoire n'a pas encore été publiée, vous devez utiliser git-reset et non git-revert :

git reset --hard <SHA-1>

(Notez que --hard vous ferait perdre toutes les modifications non validées dans le répertoire de travail).

Notes supplémentaires

D'ailleurs, ce n'est peut-être pas évident, mais partout où la documentation dit <commit> o <commit-ish> (ou <object> ), vous pouvez mettre un SHA-1 identifiant (complet ou abrégé) du commit.

9 votes

Dans le cas où votre historique a déjà été poussé vers une télécommande avant que vous ne fassiez le hard reset. vous devrez pousser la branche nouvellement réinitialisée avec git push -f mais Soyez prévenus que cela pourrait éventuellement supprimer involontairement les commits d'autres utilisateurs, et si ce n'est pas supprimer les nouveaux commits, alors cela obligera les autres utilisateurs à resynchroniser leur travail avec la branche réinitialisée, Assurez-vous donc d'abord que vos collaborateurs sont d'accord.

4 votes

Cela semble être la meilleure réponse. Elle indique aussi clairement la différence entre git revert et git reset.

91voto

Il annule le commit en question, c'est-à-dire qu'il ajoute le commit opposé. Si vous voulez extraire une révision antérieure, vous le faites :

git checkout 56e05fced214c44a37759efa2dfc25a65d8ae98d

1 votes

Alors je peux juste fusionner ça avec la tête ? Et si je prévois d'avoir des tonnes de conflits, puis-je simplement forcer ce commit à devenir la tête "telle quelle" et écraser tous les conflits ?

1 votes

Je ne suis pas sûr de la tête dont vous parlez. Vous pouvez juste déplacer votre tête à cet engagement. (par exemple en supprimant et en créant une branche). Si vous voulez faire un commit "merge" dans la tête, qui est effectivement l'inversion des commits intermédiaires, vous pouvez utiliser merge avec la stratégie "ours". Choisissez votre option et lisez les pages de manuel. Le pouvoir n'attend que vous pour l'utiliser ;-)

0 votes

C'est logique, la raison pour laquelle je demande est que git me dit maintenant que je ne suis sur aucune branche.

85voto

darshit khatri Points 227

La meilleure façon de revenir à un commit spécifique est :

git reset --hard <commit-id>

Ensuite :

git push <reponame> -f

41 votes

Les novices doivent savoir que push -f peut détruire l'histoire. Cependant, c'est parfois ce que vous voulez :)

1 votes

Parfois, on est vraiment content que l'historique soit effacé... je cherchais cette option -f, merci !

0 votes

Merci, pour être littéral, j'ai du taper -> git push origin master -f où <reponame> ne peut pas être simplement origin du moins pour moi

75voto

Flueras Bogdan Points 1838

Si vos modifications ont déjà été poussées vers un public, partagé et vous voulez inverser tous les commits entre HEAD y <sha-id> alors vous pouvez passer une plage de livraison à git revert ,

git revert 56e05f..HEAD

et il rétablira tous les commits entre 56e05f y HEAD (à l'exclusion du point de départ de la plage, 56e05f ).

2 votes

Notez que si vous rétablissez quelques centaines de commits, cela peut prendre un certain temps car vous devez commiter chaque revert individuellement.

9 votes

@splicer vous n'avez pas besoin de revenir en arrière sur chaque commit individuellement, vous pouvez soit passer l'attribut --no-edit pour éviter d'avoir à rédiger des messages de livraison individuels, ou vous pouvez utiliser l'option --no-commit pour engager les réversions en une seule fois.

0 votes

@Cupcake vous avez raison HEAD..56e05f ne fonctionne pas pour moi mais 56e05f..HEAD a fait l'affaire

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