Git - Annuler les validations poussées

610

J'ai un projet dans un référentiel distant, synchronisé avec un référentiel local (développement) et un serveur (prod). J'ai apporté des modifications validées déjà poussées vers la télécommande et retirées du serveur. Maintenant, je veux annuler ces modifications. Je pouvais donc juste git checkoutvalider la validation avant les modifications et valider les nouvelles modifications, mais je suppose qu'il y aura des problèmes pour les repousser à distance. Une suggestion sur la façon de procéder?

Manolo
la source
5
Duplication possible de Comment restaurer le référentiel Git à un commit précédent?
Trevor Boyd Smith

Réponses:

735

Vous pouvez annuler les validations individuelles avec:

git revert <commit_hash>

Cela va créer un nouveau commit qui annule les modifications du commit que vous avez spécifié. Notez qu'il ne rétablit que cette validation spécifique, et non la validation après cela. Si vous souhaitez annuler une série de validations, vous pouvez le faire comme ceci:

git revert <oldest_commit_hash>..<latest_commit_hash>

Il annule les validations entre et incluant les validations spécifiées.

Consultez la page de manuel git-revert pour plus d'informations sur la git revertcommande. Consultez également cette réponse pour plus d'informations sur la restauration des validations.

gitaarik
la source
22
En d'autres termes, il revient à <oldest_commit_hash>;)
David
7
@mr_jigsaw Usegit log
gitaarik
2
Dans la documentation de git, il indique que la commande revert annule les validations entre la première et la dernière validation (la première et la dernière incluses). Voir Documentation
Onur Demir
4
@aod est correct, cette réponse doit être mise à jour. L'API git actuelle pour revert a <oldest_commit_hash>été incluse dans la liste des
reverts
4
avec git 2.17.2 revert <old> .. <new> n'inclut pas old mais inclut <new>
chingis
353

Une solution qui ne garde aucune trace de "l'annulation".

REMARQUE: ne faites pas cela si quelqu'un a déjà retiré votre monnaie (je n'utiliserais cela que sur mon dépôt personnel)

faire:

git reset <previous label or sha1>

cela récupérera toutes les mises à jour localement (donc git status listera tous les fichiers mis à jour)

puis vous "faites votre travail" et réengagez vos modifications (Remarque: cette étape est facultative)

git commit -am "blabla"

En ce moment, votre arbre local diffère de la télécommande

git push -f <remote-name> <branch-name>

poussera et forcera la télécommande à considérer cette poussée et à supprimer la précédente (la spécification du nom à distance et du nom de la branche n'est pas obligatoire mais est recommandée pour éviter de mettre à jour toutes les branches avec l'indicateur de mise à jour).

!! attention certaines balises peuvent encore pointer supprimées commit !! comment-supprimer-une-balise distante

jo_
la source
4
-a tous les fichiers suivis seront validés -m le message de validation suit
jo_
3
Exactement ce que j'ai recherché. Quelqu'un a commis un commit erroné et a poussé et est revenu à nouveau par la suite. Les branches n'ont pas pu être fusionnées à cause de cela et je voulais que le référentiel soit à nouveau dans l'état correct (et supprimer le commit de l'historique car ils étaient de toute façon défectueux)
byemute
1
Quelle "étiquette ou sha1 précédente" dois-je utiliser?. Dois-je saisir le dernier "bon" ou le précédent et refaire toutes les modifications effectuées par le dernier correct?
elysch
3
celui juste avant le commit
eroneous
1
Exactement ce dont j'ai besoin. J'ai poussé une branche à maîtriser par erreur. Et par conséquent, j'ai eu de nombreux commits de déchets pendant toute l'histoire des commits. Je viens de faire git push -fpour le dernier commit correct et l'historique à distance nettoyé! Merci!
Anton Rybalko
193

Ce que je fais dans ces cas, c'est:

  • Dans le serveur, ramenez le curseur sur le dernier bon commit connu:

    git push -f origin <last_known_good_commit>:<branch_name>
    
  • Localement, faites de même:

    git reset --hard <last_known_good_commit>
    #         ^^^^^^
    #         optional
    



Voir un exemple complet sur une branche my_new_branchque j'ai créée à cet effet:

$ git branch
my_new_branch

Voici l'histoire récente après avoir ajouté quelques éléments à myfile.py:

$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date:   Wed Mar 23 12:48:03 2016 +0100

    Adding new stuff in myfile.py

commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

Je veux me débarrasser du dernier commit, qui a déjà été poussé, alors je lance:

$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To [email protected]:me/myrepo.git
 + 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)

Agréable! Maintenant, je vois le fichier qui a été modifié sur ce commit ( myfile.py) s'affiche dans "non organisé pour la validation":

$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   myfile.py

no changes added to commit (use "git add" and/or "git commit -a")

Étant donné que je ne souhaite pas ces modifications, je déplace simplement le curseur localement:

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit

Alors maintenant, HEAD est dans le commit précédent, à la fois local et distant:

$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit
fedorqui 'SO arrête de nuire'
la source
10
Ceci est la bonne réponse! c'est exactement ce qui devait être fait dans mon cas, merci d'avoir appris quelque chose de nouveau aujourd'hui :)
Egli Becerra
2
Ceci est la bonne réponse! Il s'agit de commits poussés (!)!
powtac
3
Si vous voulez vraiment annuler les changements (comme si vous ne les aviez jamais poussés), c'est la bonne réponse.
Jacob
1
Réponse parfaite. A bien fonctionné comme prévu!
RafiAlhamd
2
Quelqu'un achète une bière à cet homme!
Jay Nebhwani
72

Vous pouvez RÉVERVER (ou vous pouvez également l'appeler SUPPRIMER ) le Git Commit à la fois localement et à distance si vous suivez les étapes indiquées ci-dessous via la ligne de commande git.

Exécutez la commande suivante pour voir l'ID de validation que vous souhaitez rétablir

git log --oneline --decorate --graph

Vous obtiendrez comme une capture d'écran suivante entrez la description de l'image ici

Si vous vérifiez également à distance (via l'interface Web), vous pouvez voir que ce serait la même chose que ci-dessous

entrez la description de l'image ici

Comme par capture d' écran actuellement vous engager sur id e110322 mais vous voulez revenir à 030bbf6 DEUX LOCALEMENT et à distance .

Effectuez les étapes suivantes pour SUPPRIMER / RÉVERTIR Commit localement + à distance


Première restauration locale pour valider l'ID 030bbf6

git reset --hard 030bbf6

suivi par

git clean -f -d

Ces deux commandes nettoient la réinitialisation de la force pour valider l'étape 030bbf6 comme illustré ci-dessous dans l'instantané

entrez la description de l'image ici

maintenant, si vous exécutez git status, vous verrez que vous êtes DEUX commits DERRIÈRE à partir de la branche distante comme indiqué ci-dessous entrez la description de l'image ici

Exécutez la commande suivante pour mettre à jour vos index (s'il y a des mises à jour). Il est recommandé de demander à tous les développeurs de n'accepter aucune demande d'extraction sur la branche distante principale.

git fetch --all

Une fois que vous avez terminé, vous devez pousser ce commit avec force en utilisant le symbole + devant la branche, comme indiqué ci-dessous. Je l' ai utilisé ici comme maître branche, vous pouvez le remplacer par tout

entrez la description de l'image ici Code

git push -u origin +master

maintenant, si vous voyez l'interface web de remote, alors commit devrait également être annulé.

entrez la description de l'image ici

vibs2006
la source
61

Cela supprimera vos commits poussés

git reset --hard 'xxxxx'

git clean -f -d

git push -f
Mo D Genesis
la source
7
Cette méthode réécrit correctement l'historique pour supprimer la validation. Génial
Jesse Reza Khorasanee
2
cette réponse est el magnifeco!
truthadjustr
3
Aimez la réponse, merci :)
Dzenis H.
1
Juste pour être clair (je n'étais pas sûr): le commit sera le commit actuel après l'opération. Pas le dernier à supprimer.
Maik639
21
git revert HEAD -m 1

Dans la ligne de code ci-dessus. "Le dernier argument représente"

  • 1 - annule une validation.

  • 2 - annule les deux derniers commits.

  • n - annule les n derniers validations.

Vous devez appuyer sur après cette commande pour prendre effet sur la télécommande. Vous avez d'autres options comme spécifier la plage de validations à annuler. C'est l'une des options.


Utilisation ultérieure git commit -am "COMMIT_MESSAGE" alors git pushougit push -f

Sireesh Yarlagadda
la source
8
Ce n'est pas vrai - le paramètre -m spécifie le nombre de parents vers lesquels revenir (généralement 1 si vous souhaitez annuler les modifications entrantes, "les leurs", par opposition à 2 pour les modifications fusionnées, "les nôtres" - pour la fusion 2 s'engage). Cela n'a rien à voir avec le nombre de validations annulées - si vous souhaitez annuler une plage de validations, utilisezgit revert ref1..ref2
Référence nulle
1
N'a pas eu l'effet souhaité
Sam Tuke
4

2020 Simple:

git reset <commit_hash>

(Le hachage du dernier commit que vous souhaitez conserver).

Vous conserverez localement les modifications non validées.

Si vous voulez pousser à nouveau, vous devez faire:

git push -f
Xys
la source
0

Voici ma voie:

Disons que le nom de la branche est develop.

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp
backslash112
la source
0

Vous pouvez faire quelque chose comme

git push origin +<short_commit_sha>^:<branch_name>
avrsanjay
la source