Comment puis-je annuler un `git commit` localement et sur une télécommande après` git push`

242

J'ai joué git commitsuivi d'un git push. Comment puis-je annuler cette modification sur les référentiels locaux et distants?

$ git log
commit 364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8
Author: Michael Silver <Michael [email protected]>
Date:   Tue Jun 11 12:24:23 2011 -0700
Michael
la source

Réponses:

400
git reset --hard HEAD~1
git push -f <remote> <branch>

(Exemple pousser: git push -f origin bugfix/bug123)

Cela annulera le dernier commit et poussera l'historique mis à jour vers la télécommande. Vous devez passer le -fcar vous remplacez l'historique en amont dans la télécommande.

Alexander Groß
la source
24
Vous pouvez également utiliser git reset --hard <the-sha-you-want-to-return-to>.
Alexander Groß
2
La référence est appelée HEAD (sensible à la casse)
dunni
26
Aussi, soyez prudent - AFAIK vous ne devriez pas faire cela si d'autres personnes se sont retirées du repo.
Amadan
1
@BipinVayalu Cela affecte la branche sur laquelle vous vous trouvez actuellement. Plus précisément, la HEAD. Le HEAD est le plus souvent "attaché" à une branche (pointant vers un nom de branche au lieu de pointer directement vers une validation). Donc, d'une manière générale, cela affectera la branche vers laquelle pointe HEAD. Utilisez git log --decorate --onelinepour savoir où pointe votre HEAD.
Alexander Groß
4
git reset HEAD~1si vous ne voulez pas que vos modifications disparaissent (modifications non mises en scène). Changer, valider et pousser à nouveaugit push -f [origin] [branch]
softvar
161

Généralement, faites un commit "inverse", en utilisant:

git revert 364705c

puis envoyez-le à la télécommande comme d'habitude:

git push

Cela ne supprimera pas le commit: il crée un commit supplémentaire qui annule ce que le premier commit a fait. Autre chose, pas vraiment sûr, surtout quand les changements ont déjà été propagés.

Amadan
la source
9
C'est une réponse plus sûre (donc probablement meilleure) que celle d'Alexander Groß (la réponse choisie).
Graeck
6
@Graeck Chacune des solutions a ses implications et ses mérites.
Alexander Groß
5
Cela devrait être la réponse acceptée, il est préférable de ne jamais écraser l'histoire, encore plus si vous collaborez avec une équipe. git resetn'est accepté que si vous n'avez toujours pas transmis les modifications au serveur.
Josue Alexander Ibarra
17
@JosueIbarra Je ne suis pas d'accord pour tous les cas. Dans la plupart des cas, oui, vous ne devez pas écraser l'historique. Cependant, je pense qu'il y a des cas légitimes où vous devriez absolument le faire. Par exemple, vous commettez et poussez accidentellement votre fichier de secrets. Cela ne devrait pas être dans le dépôt git. Vous pouvez donc le supprimer rapidement en utilisant la réponse acceptée ici.
bfcoder
11
@bfcoder si vous avez poussé un "secret" vers un dépôt distant, ce n'est plus un secret. Et la bonne solution est de créer un nouveau secret, pas d'essayer de cacher votre erreur.
erbsman
41

Tout d'abord, détendez-vous.

"Rien n'est sous notre contrôle. Notre contrôle n'est qu'une illusion.", "L'erreur est humaine"

Je comprends que vous avez involontairement poussé votre code vers remote-master. Ça va aller.

1. Dans un premier temps, obtenez la SHA-1valeur du commit que vous essayez de renvoyer, par exemple, commit sur la branche master. lance ça:

git log

vous verrez un tas de 'f650a9e398ad9ca606b25513bd4af9fe ...' comme des chaînes avec chacun des commits. copiez ce numéro à partir du commit que vous souhaitez retourner .

2. Maintenant, saisissez la commande ci-dessous:

git reset --hard your_that_copied_string_but_without_quote_mark

vous devriez voir un message comme "HEAD is now at". vous êtes clair. Ce qu'il vient de faire, c'est de refléter ce changement localement.

3. Maintenant, saisissez la commande ci-dessous:

git push -f

tu devrais voir comme

"avertissement: push.default n'est pas défini; sa valeur implicite a changé dans ..... ... Total 0 (delta 0), réutilisé 0 (delta 0) ... ... your_branch_name -> master (mise à jour forcée) . "

Maintenant, vous êtes tous clairs. Vérifiez à nouveau le maître avec "git log", votre fixed_destination_commit devrait être en haut de la liste.

Vous êtes les bienvenus (à l'avance;))

METTRE À JOUR:

Maintenant, les changements que vous aviez faits avant que tout cela ne commence, ont maintenant disparu. Si vous voulez ramener ces travaux à nouveau, c'est possible. Merci à git reflog et aux commandes git cherry-pick .

Pour cela, je suggère de suivre ce blog ou cet article .

kmonsoor
la source
c'est une bonne mesure de spécifier la télécommande et la branche aussi lorsque vous faites "git push -f", mais "git push -f" fonctionnera de toute façon la plupart du temps
Robson
8

git reset HEAD~1si vous ne voulez pas que vos modifications disparaissent (modifications non mises en scène). Changez, engagez et repoussezgit push -f [origin] [branch]

softvar
la source
3

Vous pouvez faire un rebase interactif:

git rebase -i <commit>

Cela fera apparaître votre éditeur par défaut. Supprimez simplement la ligne contenant le commit que vous souhaitez supprimer pour supprimer ce commit.

Vous aurez bien sûr besoin d'accéder au référentiel distant pour y appliquer également cette modification.

Voir cette question: Git: supprimer les validations sélectionnées du référentiel

Jack Edmonds
la source
3

Essayez d'utiliser

git reset --hard <commit id> 

Remarque: ici, l'ID de validation sera l'ID de la validation à laquelle vous souhaitez accéder, mais pas l'ID que vous souhaitez réinitialiser. ce fut le seul point où je me suis également retrouvé coincé.

puis poussez

git push -f <remote> <branch>
Mohit Dhawan
la source
2

Alternativement:

git push origin +364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8^:master

Forcer la branche principale du référentiel distant d'origine au parent du dernier commit

MicRum
la source