1980 Stimmen

Rückgängig machen von "git commit --amend" anstelle von "git commit"

Ich habe versehentlich meine vorherige Übertragung geändert. Der Commit hätte separat sein sollen, um den Verlauf der Änderungen an einer bestimmten Datei festzuhalten.

Gibt es eine Möglichkeit, diese letzte Übertragung rückgängig zu machen? Wenn ich etwas tue wie git reset --hard HEAD^ wird die erste Übertragung ebenfalls rückgängig gemacht.

(Ich habe noch keine entfernten Verzeichnisse übertragen)

0 Stimmen

wenn Sie die Auswirkungen der einzelnen Schritte überprüfen möchten (entweder bevor Sie die folgenden Antworten ausprobieren, oder wenn Ihnen beim Ausführen eines Schrittes der Kopf schwirrt), versuchen Sie git log --reflog -p -- {{name-of-the-dir-or-file-in-question}} . Es zeigt sowohl die tatsächlichen Änderungen als auch die Commit-Meldungen für jede Aktion.

3509voto

CB Bailey Punkte 693084

Sie müssen eine neue Übergabe mit denselben Details wie die aktuelle erstellen HEAD übertragen, aber mit dem Elternteil der vorherigen Version von HEAD . git reset --soft verschiebt den Verzweigungszeiger so, dass der nächste Commit auf einem anderen Commit stattfindet, als der aktuelle Verzweigungskopf jetzt ist.

# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before 
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
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}

55 Stimmen

Sehr cool, +1. Ich habe es sogar mit der vorletzten Änderungsansicht in git reflog um die richtige Zahl zu finden, z. B. {2} .

264 Stimmen

Nur um das klarzustellen: Der erste Befehl ist ein echtes "Undo". Er stellt den HEAD, das Arbeitsverzeichnis (unverändert) und den Indexzustand vor dem git commit --amend . Die 2. ist ein "Redo" in eine neue Übertragung. Diese funktionieren für jede git commit , nicht nur --amend .

88 Stimmen

Wenn Sie also nicht mit einer neuen Commit-Nachricht geändert haben, die Sie retten müssen, kann der zweite Teil einfach eine normale git commit .

249voto

Oisín Foley Punkte 1267

Keine dieser Antworten mit der Verwendung von HEAD@{1} Das hat bei mir nicht geklappt, also hier ist meine Lösung:

git reflog

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

git reset --soft c296452

Ihre Staging-Umgebung enthält nun alle Änderungen, die Sie versehentlich mit dem Commit c296452 zusammengeführt haben.

13 Stimmen

I ausgeführt git commit --amend auf einen bereits gepushten Commit und daher haben die anderen Vorschläge nicht funktioniert. Aber dies hat funktioniert. Danke.

224voto

knittl Punkte 214432

Verwenden Sie die ref-log :

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

Sie sollten dann alle Ihre zuvor geänderten Änderungen nur noch in Ihrer Arbeitskopie haben und können erneut übertragen

um eine vollständige Liste der bisherigen Indizes zu sehen, geben Sie git reflog

9 Stimmen

Dies löscht auch den Index - immer noch nützlich, aber mehr als ein einfaches "Rückgängigmachen".

6 Stimmen

Gibt es einen Unterschied zwischen HEAD@{1} y HEAD~1 ?

23 Stimmen

@neaumusic: ja! HEAD~1 ist genau dasselbe wie HEAD^ und Identifikatoren die Elternteil der aktuellen Übertragung. HEAD@{1} auf der anderen Seite bezieht sich auf den Commit, auf den HEAD vor diesem Commit gezeigt hat, d.h. sie bedeuten unterschiedliche Commits, wenn Sie einen anderen Zweig auschecken oder einen Commit ändern.

144voto

kenorb Punkte 134883

Finden Sie Ihre geänderten Übertragungen durch:

git log --reflog

Hinweis: Sie können Folgendes hinzufügen --patch um den Körper der Commits zu sehen, um Klarheit zu schaffen. Gleich wie git reflog .

dann setzen Sie Ihren HEAD auf einen früheren Commit an dem Punkt zurück, an dem er in Ordnung war:

git reset SHA1 --hard

Anmerkung: Ersetzen Sie SHA1 mit Ihrem echten Commit-Hash. Beachten Sie auch, dass dieser Befehl verlieren alle noch nicht bestätigten Änderungen, so dass Sie sie vorher verstecken können. Alternativ dazu, verwenden. --soft um die letzten Änderungen beizubehalten und legen sie dann fest.

Dann picken Sie sich die anderen Commits heraus, die Sie zusätzlich benötigen:

git cherry-pick SHA1

50 Stimmen

Wenn Sie das tun git reset SHA1 --soft können Sie die letzten Änderungen beibehalten und sie dann festschreiben.

0 Stimmen

Und ein weiterer praktischer Trick: wenn Wenn Sie die Auswirkungen der einzelnen Schritte überprüfen möchten, bevor Sie sich an die Arbeit machen, versuchen Sie git log --reflog -p -- {{name-of-the-dir-or-file-in-question}} . Es zeigt sowohl die tatsächlichen Änderungen als auch die Commit-Meldungen.

0 Stimmen

Verwenden Sie einfach git reset SHA1 die standardmäßig den Modus --mixed die den Arbeitsbaum nicht zurücksetzt, so dass Sie sofort eine Übergabe durchführen können. git reset SHA1 && git commit -m "abc"

35voto

David Sopko Punkte 4604

Wenn Sie den Commit auf remote gepusht haben und dann fälschlicherweise Änderungen an diesem Commit vorgenommen haben, wird dies Ihr Problem beheben. Ausgabe einer git log um den SHA vor der Übergabe zu finden. (dies setzt voraus, dass die Gegenstelle den Namen origin trägt). Geben Sie nun diese Befehle mit diesem SHA ein.

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 Stimmen

Dies ist ein Spezialfall der allgemeineren Frage, aber sie deckte genau meinen unmittelbaren Bedarf.

1 Stimmen

Das gilt auch für mich. Ich bekomme gelegentlich Konflikte während Git rebase, und manchmal mache ich "amend" statt "rebase --continue" ... und das hier ist einfach ein Lebensretter!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X