Annuler une validation particulière dans Git qui a été poussée vers des dépôts distants

789

Quelle est la façon la plus simple d'annuler une validation particulière:

  • pas dans la tête ou la tête
  • A été poussé vers la télécommande.

Parce que si ce n'est pas le dernier commit,

git reset HEAD

ne fonctionne pas. Et parce qu'il a été poussé vers une télécommande,

git rebase -i

et

git rebase --onto

causera un problème dans les télécommandes.

Plus encore, je ne veux pas vraiment modifier l'histoire. S'il y avait un mauvais code, il était là dans l'histoire et peut être vu. Je le veux juste dans la copie de travail, et cela ne me dérange pas un commit de fusion inverse.

En d'autres termes, quel est l' équivalent Git des commandes svn suivantes:

svn merge -r 303:295 http://svn.example.com/repos/calc/trunk

qui supprime toutes les modifications de 295 à 302 en fusionnant toutes les modifications de ces révisions, comme un nouveau commit.

svn merge -c -302 ^/trunk

qui annule le commit 302, bien sûr en ajoutant un autre commit qui inverse fusionne les modifications de ce commit respectif.

Je pensais que cela devrait être une opération assez simple dans Git et un cas d'utilisation assez courant. À quoi d'autre sert la validation atomique?

Nous avons un stashing de mise en scène et tout pour garantir que les validations sont parfaitement atomiques, ne devriez-vous pas être en mesure d'annuler facilement une ou plusieurs de ces validations atomiques?

Lakshman Prasad
la source

Réponses:

1211

Identifiez le hachage de la validation, en utilisant git log, puis utilisez git revert <commit>pour créer une nouvelle validation qui supprime ces modifications. D'une certaine manière, git revertc'est l'inverse de git cherry-pick- ce dernier applique le patch à une branche qui le manque, le premier le supprime d'une branche qui en a.

Andrew Aylett
la source
237
Et utilisez le commutateur -n si vous souhaitez récupérer le code, mais pas automatiquement
validé
17
Que fait l'option "m"? J'ai essayé git revert 8213f7d mais j'ai obtenu ceci à la place: erreur: Commit 8213f7dad1ed546b434a0d8a64cb783b530a5a30 est une fusion mais aucune option -m n'a été donnée. fatal: échec du retour
Malcolm
10
Pour annuler une fusion: git revert -m 1 <hash>
brunozrk
31
Un avertissement à quiconque souhaite annuler une fusion: git revert annulera toutes les modifications de données (c'est-à-dire que les modifications du fichier seront annulées), mais la fusion reste dans l'historique. Pour cette raison, si vous essayez de fusionner à nouveau cette même branche plus tard, elle n'inclura aucun commit de la branche fusionnée avant la fusion annulée. Ce n'est probablement pas ce que vous voulez. Afin de fusionner à nouveau complètement la branche, vous devrez d'abord rétablir la validation à l'endroit où vous avez annulé la fusion d'origine. En savoir plus ici: kernel.mirrors.pair.com/pub/software/scm/git/docs/howto/…
etreworgy
3
Le lien dans le commentaire de @etreworgy est 404. Je soupçonne qu'il s'agit d'une version à jour du lien: kernel.org/pub/software/scm/git/docs/howto/…
Tim Smith
368

Je n'aime pas la validation automatique qui le git revertfait, donc cela pourrait être utile pour certains.

Si vous voulez juste que les fichiers modifiés ne soient pas la validation automatique , vous pouvez utiliser--no-commit

% git revert --no-commit <commit hash>

qui est le même que le -n

% git revert -n <commit hash>
Je vous remercie
la source
9
Vous pouvez également le faire git reset HEAD~1 --softsi vous êtes déjà revenu sans-n
Daniel
1
Mais git reset HEAD~nne résoudra pas l'annulation de tout commit qui n'est pas accessible en continu depuis la tête. La requête consiste à annuler tout commit particulier.
sangeethkumarp
J'ai utilisé cette solution mais j'ai heurté un conflit au milieu du retour. Après avoir résolu le conflit, j'ai fait git revert --continuece qui m'avait été demandé. Cela a fonctionné, mais malheureusement, les résultats ont été engagés. Peut-être que je devais le faire git revert --no-commit --continue.
mareoraft le
1
@sangeethkumarp le commentaire de Daniel est une étape supplémentaire que vous pouvez prendre après le git revert, si vous avez oublié le -n; car à ce stade, le dernier commit est la réversion, donc la réinitialisation logicielle annulera ce commit mais pas les modifications de code associées du retour
Oliver
@Daniel a fourni des solutions en commentant le travail pour moi Merci beaucoup '' git reset HEAD ~ 1 --soft ''
Md. Abu Sayed
41

Parce qu'il a déjà été poussé, vous ne devez pas manipuler directement l'historique. git revertva annuler les modifications spécifiques d'une validation en utilisant une nouvelle validation, afin de ne pas manipuler l'historique des validations.

moatPylon
la source
1

Si la validation que vous souhaitez annuler est une validation fusionnée (a déjà été fusionnée), vous devez choisir l'option -m 1ou -m 2, comme indiqué ci-dessous. Cela permettra à git de savoir quel commit parent du commit fusionné utiliser. Plus de détails peuvent être trouvés ICI .

  • git revert <commit> -m 1
  • git revert <commit> -m 2
Meysam Sadeghi
la source