Wie ändere ich das letzte Commit, um das Hinzufügen einer Datei aufzuheben?

108

Ich habe zwei Dateien geändert a, bin den letzten begehen. Aber die Datei bsollte nicht festgeschrieben werden. Wie sieht der Workflow aus, um dies zu ändern?

Xiè Jìléi
quelle

Antworten:

109

Update (einige Jahre später)

Jan Hudec

Es ist trivial, es nur aus dem Index zu entfernen.

True: Sie können eine Datei einfach auf ihren Indexinhalt zurücksetzen, wie die neuere Antwort (geschrieben von Matt Connolly ) besagt:

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

HEAD^Ermöglicht der Datei den Zugriff auf den Inhalt des vorherigen Commits vor dem letzten.

Dann kannst du git commit --amend, wie ich unten ursprünglich schrieb.


Mit Git 2.23 (August 2019) können Sie den neuen git restoreBefehl verwenden

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

kürzer:

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

Auch das kannst du dann git commit --amend, wie ich ursprünglich unten schrieb.


Ursprüngliche Antwort (Januar 2011)

Wenn dies Ihr letztes Commit ist (und Sie haben es nirgendwo gepusht), können Sie es ändern :
(Erstes Stash oder Speichern b)

 git commit --amend

Löschen Sie anschließend b und wiederholen Sie die Festschreibung. Stellen Sie b wieder her und Sie sind fertig.

--amend

Dient zum Ändern der Spitze des aktuellen Zweigs.
Bereiten Sie das Tree-Objekt vor, das Sie wie gewohnt durch das letzte Commit ersetzen möchten (einschließlich der üblichen -i / -o-Pfade und expliziten Pfade), und der Commit-Protokoll-Editor wird mit der Commit-Nachricht aus der Spitze des aktuellen Zweigs versehen.
Das von Ihnen erstellte Commit ersetzt den aktuellen Tipp. Wenn es sich um eine Zusammenführung handelte, werden die Eltern des aktuellen Tipps als Eltern verwendet. Das aktuelle oberste Commit wird verworfen.

VonC
quelle
... Then stash/delete b, re-commit.., hier sollte das Wort nicht Thensein after? - --amendnach stach / delete b, ...
Xiè Jìléi
@ 谢 继 雷: Mit anderen Worten, erst b speichern, dann --amend festschreiben und dann wiederherstellen? Wahr. Ich habe die Antwort aktualisiert.
Vom
Mit der Macht des Git-Index ist es einfach albern (-1), irgendjemandem zu sagen, dass er die Datei verstecken / speichern soll. Es ist trivial, es nur aus dem Index zu entfernen.
Jan Hudec
1
@JanHudec Stimmt, ich habe die Antwort entsprechend bearbeitet. Ich bin dieser alten Antwort nicht so genau gefolgt wie bei Stack Overflow. 99% der Git-Fragen zu SU sollten sowieso auf SO migriert werden.
Vom
66
  1. git diff --name-only HEAD^ - (optional) Verwenden Sie diese Option, um die Dateien aufzulisten, die sich beim letzten Festschreiben geändert haben.
  2. git reset HEAD^ path/to/file/to/revert- um den Index auf die letzte Version zurückzusetzen, wobei die Arbeitskopie unverändert bleibt.
  3. git commit --amend- zu ändern , dass sich verpflichten, zuletzt die umfassen Indexänderungen
Matt Connolly
quelle
9
Imho ist es eine viel bessere Antwort als die akzeptierte.
mik01aj
1
Beachten Sie, dass Sie git commit -a --amendSchritt 3 nicht verwenden (dh keine Dateien hinzufügen) sollten, da Sie sonst die Änderungen an der Arbeitskopie festschreiben, bei denen es sich um die Änderungen handelt, die Sie entfernen möchten. Ein optionaler Schritt 2.5 könnte darin bestehen git checkout path/to/file/to/revert, auch Ihre Arbeitskopie zu bereinigen.
16.
1
Alternativ können Sie git rm --cached path/to/file/to/revertdie Datei auch entfernen, ohne sie aus dem Baum zu löschen.
Jan Hudec
13

Wenn Sie alternativ verwenden git gui, wählen Sie einfach die Option "Last Commit ändern". Die hinzugefügte Datei wird in der Liste "Staged" angezeigt. Klicken Sie auf das entsprechende Symbol, um sie in die Liste "Unstaged" zu verschieben und zu bestätigen.

Jan Hudec
quelle
1
@VonC: Das Bearbeiten und Aufteilen von Patches ist für Heavy-Git-Benutzer eine weit verbreitete Aufgabe, daher wurde die GUI so konzipiert, dass sie einfach ist und IMO das beste Tool dafür darstellt.
Jan Hudec
Das funktioniert! Ich hatte keine Erfolge mit anderen Optionen für diese bestimmte Aufgabe. Danke für den Tipp!
Serguzest
10

Wenn Sie b aus Ihrem letzten Commit löschen möchten

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

Wenn Sie alle Änderungen an b in Ihrem letzten Commit entfernen möchten

(backup b)
(modify b to state before incorrect commit)
git commit --amend
(restore b)
Pingo
quelle
git rm --cachedund den Backup / Restore-Tanz (-1) abschaffen.
Jan Hudec
Vielen Dank für den Hinweis. Ich wollte mitteilen, wie ich das gemacht habe, da dies der Ansatz war, mit dem ich mich am wohlsten fühlte, selbst nachdem ich den gesamten Thread gelesen hatte.
Pingo
4

Eine Alternative, die keine Index-Hacker-Attacke erfordert, aber dennoch die alte Commit-Nachricht beibehält:

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

Das gefällt mir, weil (a) Befehle verwendet werden, die ich regelmäßig verwende, und (b) ich kann git add -pgenau herausfinden, was ich festschreiben möchte.

Justin L.
quelle