Comment annuler un commit git local

745

Mon problème est que j'ai changé un fichier, par exemple: README, ajouté une nouvelle ligne « ceci pour ma ligne de test » et enregistré le fichier, puis j'ai émis les commandes suivantes

 git status

 # On branch master
 # Changed but not updated:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #  modified:   README
 #
 no changes added to commit (use "git add" and/or "git commit -a")


 git add README

 git commit -a -m 'To add new line to readme'

Je n'ai pas poussé le code vers github, maintenant je veux annuler ce commit.

Pour cela, j'ai utilisé

   git reset --hard HEAD~1

Mais j'ai perdu la ligne nouvellement ajoutée « ceci pour ma ligne de test » du fichier README. Cela ne devrait pas arriver. J'ai besoin que le contenu soit là. Existe-t-il un moyen de conserver le contenu et d'annuler mon engagement local?

Amal Kumar S
la source
3
Il semble que vous ne demandiez certainement pas git revert, ce qui crée un nouveau commit avec la différence inverse du commit inversé. La réinitialisation pointe simplement votre branche actuelle vers un commit différent, dans ce cas, celui avant le commit que vous voulez "oublier".
Cascabel
1
NB: Il peut être utile de mentionner que vous git-commitpouvez abandonner si vous laissez le message vide, donc si vous n'avez pas réellement terminé la validation, cela pourrait être utile.
GKFX

Réponses:

1424

Utilisez simplement git resetsans le --harddrapeau:

git reset HEAD~1

PS: Sur les systèmes basés sur Unix, vous pouvez utiliser HEAD^ce qui est égal à HEAD~1. Sur Windows HEAD^ne fonctionnera pas car ^signale une continuation de ligne. Ainsi, votre invite de commande vous demandera simplement More?.

Koraktor
la source
13
Soit dit en passant, cela est appelé --mixed dans le manuel .
Josh Lee
10
Les versions plus récentes de Git permettent même @^de les raccourcir HEAD^.
Koraktor
Je ne sais pas ce que cela a fait, mais beaucoup de fichiers sont apparus sur ma liste de modifications, des fichiers que je n'ai pas touchés
FRR
@feresr Si vous n'avez vraiment pas touché ces fichiers dans le dernier commit ou dans l'arborescence de travail, cela est dû à d'autres incohérences dans votre arborescence de travail, par exemple vous êtes sous Windows et les fins de fichier ne correspondent pas.
Koraktor
1
est-il possible de réinitialiser tous les commit d'une seule main?
Webwoman
185

Utiliser à la --softplace du --harddrapeau:

git reset --soft HEAD^
TpED
la source
18
pouvez-vous expliquer la différence entre les 2 drapeaux?
John Giotta
1
Si vous ouvrez la console du gestionnaire de packages et exécutez ce "git reset --soft HEAD ^", il fait ce que vous voulez (et ce dont j'avais besoin).
David Cornelson du
54
@JohnGiotta - git reset --soft HEAD^supprimera le dernier commit local (non poussé) mais conservera les modifications que vous avez
apportées
@fider Saviour! Je ne sais pas si la réponse acceptée fonctionne toujours, mais cela devrait être la réponse exacte dont l'OP avait besoin.
Babu
git reset --soft HEAD~sur les fenêtres
Jack0fshad0ws
34

Si vous êtes au milieu d'un commit (c'est-à-dire déjà dans votre éditeur), vous pouvez l'annuler en supprimant toutes les lignes au-dessus de la première #. Cela annulera le commit.

Vous pouvez donc supprimer toutes les lignes pour que le message de validation soit vide, puis enregistrez le fichier:

Ça devrait ressembler à ça.

Vous obtiendrez alors un message qui dit Aborting commit due to empty commit message..

MODIFIER :

Vous pouvez également supprimer toutes les lignes et le résultat sera exactement le même.

Pour supprimer toutes les lignes dans vim (si c'est votre éditeur par défaut), une fois que vous êtes dans l'éditeur, tapez ggpour aller à la première ligne, puis dGpour supprimer toutes les lignes. Enfin, écrivez et quittez le fichier avec wqet votre validation sera abandonnée.

inostia
la source
3
C'est exactement ce que je cherchais! Cette réponse a besoin de plus de votes positifs :)
jdunk
Pour info, cela fonctionne aussi si vous essayez d'interrompre unrebase -i mybranchname
inostia
18

La première chose que vous devez faire est de déterminer si vous souhaitez conserver les modifications locales avant de supprimer le message de validation.

Utilisez git logpour afficher les messages de validation actuels, puis recherchez l' commit_id avant avant la validation que vous souhaitez supprimer, et non la validation que vous souhaitez supprimer.

Si vous souhaitez conserver les fichiers modifiés localement et supprimer simplement le message de validation:

git reset --soft commit_id

Si vous souhaitez supprimer tous les fichiers modifiés localement et le message de validation:

git reset --hard commit_id

C'est la différence du doux et du dur

mistdon
la source
1
Je pense que c'est le contraire.
Ruff9
9

Vous pouvez dire à Git quoi faire avec votre index (ensemble de fichiers qui deviendront le prochain commit) et votre répertoire de travail lors de la réinitialisation de git en utilisant l'un des paramètres:

--soft: Seules les validations seront réinitialisées, tandis que l'index et le répertoire de travail ne sont pas modifiés.

--mixed: Cela réinitialisera l'index pour qu'il corresponde à HEAD, tandis que le répertoire de travail ne sera pas touché. Toutes les modifications resteront dans le répertoire de travail et apparaîtront comme modifiées.

--hard: Il réinitialise tout (commits, index, répertoire de travail) pour correspondre à HEAD.

Dans votre cas, j'utiliserais git reset --softpour conserver vos modifications modifiées dans l'index et le répertoire de travail. Assurez-vous de vérifier ceci pour une explication plus détaillée.

Nesha Zoric
la source
1

Utilisez la commande ci-dessous:

$ git reset HEAD~1

Après cela, vous pouvez également afficher les fichiers qui reviennent comme ci-dessous la réponse.

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
Omkar
la source