Comment supprimer les validations git non poussées?

949

Je me suis accidentellement engagé dans la mauvaise branche. Comment supprimer ce commit?

NullVoxPopuli
la source

Réponses:

1812

Supprimez le commit le plus récent, en conservant le travail que vous avez effectué:

git reset --soft HEAD~1

Supprimez le commit le plus récent, détruisant le travail que vous avez effectué:

git reset --hard HEAD~1
dbyrne
la source
13
assurez-vous que HEAD pointe vers la branche .. (vérifiez d'abord)
Frank Schwieterman
128
Et assurez-vous que HEAD ~ 1 est le commit ... Vous pouvez également le fairegit reset --hard origin
Daenyth
13
Les git remotelistes de pensée me git reset --hard origindisent l'origine fatal: ambiguous argument 'origin': unknown revision or path not in the working tree.. Pourquoi?
trss
7
C'est génial. Je viens de me sauver la vie.
NinjaBoy
2
git reset HEAD~1conservera également toutes vos modifications mais vous laissera un index vide plutôt que de tout garder (comme le --softferait l' option).
Holloway
139

Je me demande pourquoi la meilleure réponse que j'ai trouvée n'est que dans les commentaires! ( par Daenyth avec 86 voix contre )

git reset --hard origin

Cette commande synchronisera le référentiel local avec le référentiel distant en supprimant toutes les modifications que vous avez apportées à votre local. Vous pouvez également effectuer les opérations suivantes pour récupérer la branche exacte que vous avez dans l'origine.

git reset --hard origin/<branch>
Ashkan Sirous
la source
16
Merci pour cela, développant légèrement l'explication: pour une branche spécifique:git reset --hard origin/<branch>
cleary
4
Ou git reset --soft origin/<branch>, si vous voulez vous débarrasser du commit mais garder le travail local.
riverhorse
1
je reçois fatal: ambiguous argument 'origin': unknown revision or path not in the working tree., vous devez spécifier la branche comme:git reset --hard origin/feature/my-cool-stuff
Kip
Brillant! Cela fonctionne réellement, contrairement à la réponse "acceptée" qui détache simplement la tête et vous laisse accroché.
mae
55

Ne le supprimez pas: un seul commit git cherry-picksuffit.

Mais si vous avez eu plusieurs commits sur la mauvaise branche, c'est là que git rebase --ontobrille:

Supposons que vous ayez ceci:

 x--x--x--x <-- master
           \
            -y--y--m--m <- y branch, with commits which should have been on master

, vous pouvez ensuite le marquer masteret le déplacer où vous le souhaitez:

 git checkout master
 git branch tmp
 git checkout y
 git branch -f master

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- y branch, master branch

, réinitialisez la branche y où elle aurait dû être:

 git checkout y
 git reset --hard HEAD~2 # ~1 in your case, 
                         # or ~n, n = number of commits to cancel

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- master branch
                ^
                |
                -- y branch

, et enfin déplacez vos validations (réappliquez-les, en faisant de nouvelles validations)

 git rebase --onto tmp y master
 git branch -D tmp


 x--x--x--x--m'--m' <-- master
           \
            -y--y <- y branch
VonC
la source
malheureusement, ce n'était pas la question.
KatariaA
1
@KatariaA C'est une alternative valable à la suppression de la validation effectuée sur la mauvaise branche et aidera les autres dans la même situation (bonne validation effectuée sur la mauvaise branche).
VonC
14

Faites un git rebase -i FAR_ENOUGH_BACKet laissez tomber la ligne pour le commit que vous ne voulez pas.

Hank Gay
la source
6

Si vous souhaitez déplacer ce commit vers une autre branche, obtenez le SHA du commit en question

git rev-parse HEAD

Ensuite, changez la branche actuelle

git checkout other-branch

Et cherry-pickl'engagement deother-branch

git cherry-pick <sha-of-the-commit>
Alexander Groß
la source
D'après mon expérience, cela n'annule pas le commit de la branche d'origine, ce qui nécessite la git reset --hard HEAD~1suite. Je pense qu'utiliser reset --softpuis changer de branche et recommencer aurait permis d'économiser du travail supplémentaire. Là encore, j'utilisais SourceTree pour faire la plupart de mes trucs de base, seulement en le commandant en ligne avec ceci après mon erreur.
jusopi
3

Pour votre référence, je pense que vous pouvez "hard cut" commits hors de votre branche actuelle non seulement avec git reset --hard, mais aussi avec la commande suivante:

git checkout -B <branch-name> <SHA>

En fait, si vous ne vous souciez pas de vérifier, vous pouvez définir la branche sur ce que vous voulez avec:

git branch -f <branch-name> <SHA>

Ce serait une manière programmatique de supprimer les validations d'une branche, par exemple, afin de copier de nouvelles validations dans celle-ci (en utilisant le rebase).

Supposons que vous ayez une branche qui est déconnectée du maître car vous avez pris des sources à partir d'un autre emplacement et les avez transférées dans la branche.

Vous avez maintenant une branche dans laquelle vous avez appliqué des modifications, appelons-la "sujet".

Vous allez maintenant créer un doublon de votre branche de sujet, puis le rebaser sur le vidage de code source qui se trouve dans la branche "dump":

git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate

Vos modifications sont maintenant réappliquées dans la branche topic_duplicate en fonction du point de départ de "dump" mais uniquement des validations qui se sont produites depuis "master". Ainsi, vos modifications depuis master sont maintenant réappliquées en plus de "dump" mais le résultat se retrouve dans "topic_duplicate".

Vous pouvez alors remplacer "dump" par "topic_duplicate" en faisant:

git branch -f dump topic_duplicate
git branch -D topic_duplicate

Ou avec

git branch -M topic_duplicate dump

Ou tout simplement en jetant le dépotoir

git branch -D dump

Peut-être pourriez-vous également choisir simplement après avoir effacé le "topic_duplicate" actuel.

Ce que j'essaie de dire, c'est que si vous voulez mettre à jour la branche "en double" actuelle basée sur un ancêtre différent, vous devez d'abord supprimer les commits précédemment "sélectionnés" en faisant un git reset --hard <last-commit-to-retain>ou git branch -f topic_duplicate <last-commit-to-retain>puis en copiant les autres commits (à partir du principal branche thématique) soit par rebasage, soit par sélection.

Le rebasage ne fonctionne que sur une branche qui a déjà les validations, vous devez donc dupliquer votre branche de sujet chaque fois que vous voulez le faire.

La sélection des cerises est beaucoup plus facile:

git cherry-pick master..topic

Ainsi, la séquence entière se résumera à:

git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic

Lorsque votre branche de sujet en double a été extraite. Cela supprimerait les validations précédemment sélectionnées du doublon actuel, et réappliquerait simplement toutes les modifications qui se produisent dans "topic" au-dessus de votre "dump" actuel (ancêtre différent). Cela semble un moyen raisonnablement pratique de baser votre développement sur le "vrai" maître en amont tout en utilisant un autre maître "en aval" pour vérifier si vos modifications locales s'appliquent également à cela. Alternativement, vous pouvez simplement générer un diff, puis l'appliquer en dehors de n'importe quel arbre source Git. Mais de cette façon, vous pouvez conserver une version modifiée (corrigée) à jour qui est basée sur la version de votre distribution tandis que votre développement réel est contre le vrai maître en amont.

Il suffit donc de démontrer:

  • reset fera pointer votre branche vers un commit différent (--hard vérifie également le commit précédent, --soft conserve les fichiers ajoutés dans l'index (qui seraient validés si vous recommençiez) et la valeur par défaut (--mixed) ne sera pas consultez le commit précédent (en effaçant vos modifications locales) mais il effacera l'index (rien n'a encore été ajouté pour le commit)
  • vous pouvez simplement forcer une branche à pointer vers un autre commit
  • vous pouvez le faire tout en vérifiant immédiatement cet engagement
  • le rebasage fonctionne sur les commits présents dans votre branche actuelle
  • cueillette de cerises signifie copier depuis une autre branche

J'espère que cela aide quelqu'un. Je voulais réécrire cela, mais je ne peux pas gérer maintenant. Cordialement.

Xennex81
la source
0

La commande suivante a fonctionné pour moi, toutes les modifications locales validées sont supprimées et local est réinitialisé comme la branche d'origine / maître distante.

git reset --hard origin

Atul Sureka
la source