1776 votes

Comment défaire "git commit --amend" fait au lieu de "git commit" ?

J'ai accidentellement modifié mon précédent commit. Le commit aurait dû être séparé pour conserver l'historique des modifications que j'ai apportées à un fichier particulier.

Y a-t-il un moyen d'annuler cette dernière livraison ? Si je fais quelque chose comme git reset --hard HEAD^ le premier commit est également annulé.

(je n'ai pas encore poussé vers des répertoires distants)

0 votes

si vous voulez confirmer les effets de chacune des étapes que vous avez suivies (soit avant d'essayer les réponses ci-dessous, soit si votre tête commence à tourner pendant l'exécution de l'une d'entre elles) essayez git log --reflog -p -- {{name-of-the-dir-or-file-in-question}} . Il montre à la fois les changements réels et les messages de validation pour chaque action.

3140voto

Charles Bailey Points 244082

Ce que vous devez faire est de créer un nouveau commit avec les mêmes détails que le commit actuel. HEAD mais avec le parent comme la version précédente de HEAD . git reset --soft déplacera le pointeur de branche de façon à ce que le prochain commit se fasse au-dessus d'un commit différent de celui où se trouve la tête de branche actuelle.

# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit
git reset --soft HEAD@{1}

# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
git commit -C HEAD@{1}

49 votes

Très cool, +1. Je l'ai même fait avec l'avant-dernière vue amendée en git reflog pour trouver le bon nombre, par exemple {2} .

243 votes

Pour être clair, la première commande est un véritable "undo". Elle produit le HEAD, le répertoire de travail (inchangé), et l'état de l'index avant la commande git commit --amend . Le second est un "redo" dans un nouveau commit. Cela fonctionne pour tout git commit pas seulement --amend .

78 votes

Donc, si vous n'avez pas modifié un nouveau message de validation que vous devez récupérer, la deuxième partie peut simplement être un simple git commit .

178voto

knittl Points 64110

Utiliser le ref-log :

git branch fixing-things HEAD@{1}
git reset fixing-things

vous devriez alors avoir tous vos changements précédemment modifiés uniquement dans votre copie de travail et vous pouvez valider à nouveau

pour voir la liste complète des indices précédents git reflog

7 votes

Cela efface aussi l'index -- toujours utile, mais va au-delà d'une simple "annulation".

6 votes

Y a-t-il une différence entre HEAD@{1} et HEAD~1 ?

23 votes

@neaumusic : oui ! HEAD~1 est exactement la même chose que HEAD^ et les identifiants les parent de la livraison en cours. HEAD@{1} d'autre part se réfère au commit que HEAD a pointé avant celui-ci, c'est-à-dire qu'ils signifient des commits différents lorsque vous checkout une branche différente ou modifiez un commit.

130voto

kenorb Points 2464

Trouvez vos commits modifiés par :

git log --reflog

Note : Vous pouvez ajouter --patch pour voir le corps des commits pour plus de clarté. Identique à git reflog .

puis réinitialiser votre HEAD à n'importe quel commit précédent au point où il était fin par :

git reset SHA1 --hard

Note : Remplacer SHA1 avec le hachage réel de votre commit. Notez également que cette commande perdre les changements non validés, vous pouvez donc les cacher avant. C'est une alternative, utiliser --soft au lieu de conserver les dernières modifications et ensuite les commettre.

Ensuite, vous pouvez choisir les autres engagements dont vous avez besoin par-dessus :

git cherry-pick SHA1

45 votes

Si vous le faites git reset SHA1 --soft vous pouvez conserver les dernières modifications et les valider.

0 votes

Et une autre astuce pratique : si Avant de vous lancer dans l'aventure, vous voulez confirmer les effets de chaque étape que vous avez franchie. git log --reflog -p -- {{name-of-the-dir-or-file-in-question}} . Il montre à la fois les changements réels et les messages de validation.

0 votes

Il suffit d'utiliser git reset SHA1 qui, par défaut, est le mode --mixed qui ne réinitialise pas l'arbre de travail, ce qui vous permet de valider immédiatement. git reset SHA1 && git commit -m "abc"

129voto

Oisín Foley Points 129

Aucune de ces réponses avec l'utilisation de HEAD@{1} a fonctionné pour moi, alors voici ma solution :

git reflog

d0c9f22 HEAD@{0}: commit (amend): [Feature] - ABC Commit Description 
c296452 HEAD@{1}: commit: [Feature] - ABC Commit Description 

git reset --soft c296452

Votre environnement de test contient maintenant tous les changements que vous avez accidentellement fusionnés avec le commit c296452.

9 votes

J'ai exécuté git commit --amend sur un commit déjà poussé et donc les autres suggestions n'ont pas fonctionné. Mais ceci a fonctionné. Merci.

33voto

David Sopko Points 173

Si vous avez poussé le commit à distance et ensuite modifié par erreur les changements à ce commit, cela résoudra votre problème. Émettez un git log pour trouver le SHA avant le commit. (ceci suppose que le distant est nommé origine). Maintenant, lancez ces commandes en utilisant ce SHA.

git reset --soft <SHA BEFORE THE AMMEND>
#you now see all the changes in the commit and the amend undone

#save ALL the changes to the stash
git stash

git pull origin <your-branch> --ff-only
#if you issue git log you can see that you have the commit you didn't want to amend

git stash pop
#git status reveals only the changes you incorrectly amended

#now you can create your new unamended commit

4 votes

Il s'agit d'un cas particulier de la question plus générale, mais elle répondait exactement à mon besoin immédiat.

1 votes

Pareil pour moi. J'ai parfois des conflits pendant le rebasement de git, et parfois je fais "amend" au lieu de "rebase --continue" ... et ceci me sauve la vie !

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