Comment modifier le dernier commit pour annuler l'ajout d'un fichier?

108

J'ai modifié deux fichiers a, bdans le dernier commit. Mais les fichiers bne doivent pas être validés. Quel est le flux de travail pour modifier cela?

Xiè Jìléi
la source

Réponses:

109

Mise à jour (quelques années plus tard)

Jan Hudec

Il est trivial de le supprimer de l'index uniquement.

Vrai: vous pouvez facilement réinitialiser un fichier au contenu de son index, comme le suggère la réponse la plus récente (écrite par Matt Connolly ):

git reset HEAD^ path/to/file/to/revert

HEAD^permet au fichier d'accéder à son contenu dans la précédente validation avant la dernière.

Alors vous pouvez git commit --amend, comme je l'ai écrit à l'origine ci-dessous.


Avec Git 2.23 (août 2019), vous pouvez utiliser la nouvelle git restorecommande

 git restore --source=HEAD^ --staged  -- path/to/file/to/revert

plus court:

 git restore -s@^ -S -- path/to/file/to/revert

Encore une fois, vous pouvez alors git commit --amend, comme je l'ai écrit à l'origine ci-dessous.


Réponse originale (janvier 2011)

S'il s'agit de votre dernier commit (et que vous ne l'avez poussé nulle part), vous pouvez le modifier :
(première sauvegarde ou sauvegarde b)

 git commit --amend

Puis supprimez b, re-commettez. Restaurez b et vous avez terminé.

--amend

Utilisé pour modifier la pointe de la branche actuelle.
Préparez l'objet arbre que vous souhaitez remplacer par la dernière validation, comme d'habitude (cela inclut les chemins habituels -i / -o et explicites), et l'éditeur de journal de validation est alimenté avec le message de validation de la pointe de la branche actuelle.
Le commit que vous créez remplace le conseil actuel (s'il s'agissait d'une fusion, les parents du conseil actuel étaient les parents), de sorte que le premier commit actuel est ignoré.

VonC
la source
... Then stash/delete b, re-commit.., Ici ne devrait pas le mot Thenêtre after? - --amendaprès stach / supprimer b, ...
Xiè Jìléi
@ 继 雷: autrement dit, enregistrez d'abord b, puis validez --amend, puis restaurez? Vrai. J'ai mis à jour la réponse.
VonC
Avec la puissance de git index, dire à tout le monde de cacher / sauvegarder le fichier est tout simplement ridicule (-1). Il est trivial de le supprimer de l'index uniquement.
Jan Hudec
1
@ JanHudec C'est vrai, j'ai modifié la réponse en conséquence. Je n'ai pas suivi cette vieille réponse d'aussi près que sur Stack Overflow. Quoi qu'il en soit, 99% des questions git sur le SU devraient être migrées sur le SO.
VonC
66
  1. git diff --name-only HEAD^ - (facultatif) permet de répertorier les fichiers modifiés lors de la dernière validation.
  2. git reset HEAD^ path/to/file/to/revert- réinitialiser l' index à cette dernière version en laissant la copie de travail intacte.
  3. git commit --amend- modifier ce dernier engagement pour inclure les modifications d' index
Matt Connolly
la source
9
A mon avis, c'est une bien meilleure réponse que celle acceptée.
mik01aj
1
Notez que vous ne devriez pas utiliser git commit -a --amend(c’est-à-dire ne pas ajouter de fichiers) pour l’étape 3, ou vous allez valider vos modifications de copie de travail, qui sont les modifications que vous essayez de supprimer. Une étape facultative 2.5 pourrait également consister git checkout path/to/file/to/revertà nettoyer votre copie de travail.
dmnd
1
Sinon, git rm --cached path/to/file/to/revertsupprimez le fichier sans le supprimer de l'arborescence.
Jan Hudec
13

Alternativement, si vous utilisez git gui, il vous suffit de sélectionner l’option "Modifier le dernier commit", le fichier ajouté apparaît dans la liste "Staged", cliquez sur son icône pour le déplacer dans la liste "Unstaged" et validez.

Jan Hudec
la source
1
@VonC: La modification et le fractionnement de correctifs étant une opération assez courante pour les gros utilisateurs de git, l'interface graphique a été conçue pour faciliter la tâche et constitue le meilleur outil pour l'OMI.
Jan Hudec
Celui-là fonctionne! Je n'ai pas réussi avec d'autres options pour cette tâche particulière. Merci pour le conseil!
Serguzest
10

Si vous voulez supprimer b de votre dernier commit

git rm --cached b (will preserve the file in the working tree but remove it from the index)
git commit --amend

Si vous souhaitez supprimer toutes les modifications apportées à b dans votre dernier commit

(backup b)
(modify b to state before incorrect commit)
git commit --amend
(restore b)
pingo
la source
git rm --cachedet supprimez la danse de sauvegarde / restauration (-1).
Jan Hudec
Merci d'avoir fait remarquer cela. Je voulais partager ma démarche, car c’était l’approche avec laquelle je me sentais le plus à l’aise même après avoir lu tout le fil.
pingo
4

Une alternative qui ne nécessite pas de hackery d'index, mais conserve néanmoins l'ancien message de commit:

$ git reset HEAD^
$ git add <all the files you want, excluding the one you don't want>
$ git commit -C HEAD@{1}

J'aime ça parce que (a) il utilise des commandes que j'utilise régulièrement et (b) je peux le faire git add -ppour comprendre exactement ce que je veux commettre.

Justin L.
la source