Wie kann ich meine Dateien nach einem lokalen Commit wieder entfernen?

268

Ich habe den folgenden Befehl ausgeführt

git add <foo.java>
git commit -m "add the foo.java file"

Wie kann ich mein lokales Commit jetzt löschen und foo.java deaktivieren?

Wenn ich tippe git reset --hard, habe ich festgestellt, dass meine geänderte Version foo.javaauf die ursprüngliche zurückgesetzt wird.

Kit Ho
quelle

Antworten:

451

git reset --soft HEAD~1sollte tun was du willst. Danach haben Sie die ersten Änderungen im Index (sichtbar mit git diff --cached) und Ihre neuesten Änderungen werden nicht bereitgestellt. git statuswird dann so aussehen:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

Sie können dann git add foo.javabeide Änderungen gleichzeitig vornehmen und festschreiben.

Antti
quelle
Ich habe die Antwort bearbeitet: "Zu übernehmende Änderungen" haben die ersten Änderungen, und "Änderungen, die nicht zum Festschreiben bereitgestellt werden" haben die zweiten Änderungen.
Antti
4
Was in dieser Antwort beschrieben wird, ist tatsächlich das, was es git commit --amendtut; aber mit einem viel komplizierteren Workflow. Dies beantwortet die gestellte Frage OP nicht, obwohl eine gute Richtung angegeben wurde ( git reset).
7heo.tk
2
Musste das '^' durch ein '~' ersetzen, damit es funktioniert, also sieht es so aus:git reset --soft HEAD~
Shahar
3
git zurücksetzen --soft HEAD ~ 1 dann git zurücksetzen HEAD
Joko Wandiro
perfekte Antwort auf das, was ich will!
DeepInJava
78

Verwenden:

git reset HEAD^

Dies führt standardmäßig einen "gemischten" Reset durch, der das tut, was Sie gefragt haben. Setzen Sie foo.java in nicht inszeniert und entfernen Sie das letzte Commit.

Ryan Stewart
quelle
2
Würde es Ihnen etwas ausmachen, mir zu erklären, was "gemischter" Reset, "weicher" Reset und "harter" Reset ist?
Kit Ho
1
Das @ Kit Ho - Git - Reset - Handbuch enthält ausgezeichnete Beschreibungen dieser.
Manojlds
4
@Kit, @manojlds: So auch stackoverflow.com/questions/2530060/… (schamloser Stecker)
Cascabel
5
Das ist eigentlich die einzig richtige Antwort. Die beiden anderen Antworten werden inszenieren die Dateien erneut , nachdem Sie ein Commit.
7heo.tk
git reset --softfunktionierte nicht, git reset HEAD^tat es aber
Worte für den
43

Für mich ist die folgende Methode besser lesbar (daher vorzuziehen):

git reset HEAD~1

Stattdessen 1kann es eine beliebige Anzahl von Commits geben, die Sie aufheben möchten.

Andrey Deineko
quelle
39

git reset --softist nur dafür: es ist wie git reset --hard, berührt aber nicht die Dateien.

wRAR
quelle
4
Das war die am leichtesten verständliche Erklärung, die ich bisher gehört habe (in nur 11 Worten)! Vielen Dank!
Phreakhead
3
Diese Antwort ist falsch. git reset"ist wie git reset --hard, berührt aber nicht die Dateien." Nicht git reset --soft. git reset --softDie Änderungen werden inszeniert, sodass Sie sie nicht zur Bereitstellung hinzufügen müssen, wenn Sie sie festschreiben möchten, aber Sie müssen git resetsie (ja, ein zweites Mal und ohne die --soft), falls Sie dies nicht tun. Diese Antwort ist also kurz, aber falsch.
7heo.tk
12

Zum Aufheben der Bereitstellung aller Dateien in Ihrem letzten Commit -

git reset HEAD~

Lavika
quelle
8

"Zurücksetzen" ist der Weg, um Änderungen lokal rückgängig zu machen. Beim Festschreiben wählen Sie zuerst Änderungen aus, die in " git add " aufgenommen werden sollen - das wird als "Staging" bezeichnet. Und sobald die Änderungen inszeniert sind, " git Commit " Sie sie.

Um entweder vom Staging oder vom Commit zurückzutreten, setzen Sie den HEAD zurück. In einem Zweig ist HEAD eine Git-Variable, die auf das letzte Commit verweist. Wenn Sie also inszeniert, aber nicht festgeschrieben haben, setzen Sie " HEAD HEAD zurück ". Dies sichert den aktuellen HEAD, indem Änderungen von der Bühne genommen werden. Es ist eine Abkürzung für " git reset --mixed HEAD ~ 0" ".

Wenn Sie bereits ein Commit durchgeführt haben, ist der HEAD bereits fortgeschritten, sodass Sie zum vorherigen Commit sichern müssen. Hier " setzen Sie HEAD ~ 1 zurück " oder " HEAD ^ 1 zurücksetzen " oder " HEAD ~ zurücksetzen " oder " HEAD ^ zurücksetzen " - alle Referenz HEAD minus eins.

Welches ist das bessere Symbol, ~ oder ^? Stellen Sie sich die ~ Tilde als einen einzelnen Stream vor. Wenn jedes Commit ein einzelnes übergeordnetes Element hat und es sich nur um eine Reihe von Änderungen in der Reihenfolge handelt, können Sie den Stream mithilfe der Tilde als HEAD ~ 1, HEAD ~ 2, HEAD sichern ~ 3, für Eltern, Großeltern, Urgroßeltern usw. (technisch gesehen findet es den ersten Elternteil in früheren Generationen).

Wenn es zu einer Zusammenführung kommt, haben Commits mehr als ein übergeordnetes Element. Dann kommt das ^ caret ins Spiel - Sie können sich erinnern, weil es zeigt, wie die Zweige zusammenkommen. Mit dem Caret wäre HEAD ^ 1 der erste Elternteil und HEAD ^ 2 der zweite Elternteil eines einzelnen Commits - Mutter und Vater zum Beispiel.

Wenn Sie also nur einen Sprung auf ein Commit mit nur einem Elternteil zurückgehen, sind HEAD ~ und HEAD ^ gleichwertig - Sie können beide verwenden.

Der Reset kann auch --soft , --mixed oder --hard sein . Bei einem Soft-Reset wird nur das Commit zurückgesetzt - der HEAD wird zurückgesetzt, die Dateien aus dem früheren Commit werden jedoch nicht ausgecheckt, sodass alle Änderungen im Arbeitsverzeichnis erhalten bleiben. Und --soft reset löscht nicht einmal die Bühne (auch als Index bezeichnet ), sodass alle bereitgestellten Dateien weiterhin auf der Bühne stehen.

Bei einem --mixed- Reset (Standardeinstellung) werden auch die Dateien aus dem früheren Commit nicht ausgecheckt , sodass alle Änderungen beibehalten werden, die Phase jedoch gelöscht wird. Deshalb wird ein einfacher " Git Reset HEAD " die Bühne räumen.

Ein --hard- Reset setzt den HEAD zurück und löscht die Phase, überprüft aber auch alle Dateien aus dem früheren Commit und überschreibt so alle Änderungen.

Wenn Sie das Commit in ein Remote-Repository verschoben haben, funktioniert das Zurücksetzen nicht so gut. Sie können lokal zurücksetzen, aber wenn Sie versuchen, auf die Fernbedienung zu pushen, erkennt git, dass sich Ihr lokaler HEAD hinter dem HEAD in der Remote-Verzweigung befindet, und weigert sich, zu pushen. Sie können vielleicht den Push erzwingen, aber Git mag das wirklich nicht.

Alternativ können Sie verstauen Sie Ihre Änderungen , wenn Sie sie behalten möchten, überprüfen die früher begehen, un-bunkern die Änderungen, Bühne sie, erstellen Sie eine neue begehen, und dann , dass drücken.

HieroB
quelle
+1 für die detaillierte Erläuterung der Operation. IMO sollte dies die akzeptierte Antwort sein!
ISAE
2

Nehmen wir an, Sie möchten Änderungen bis zu n Commits aufheben.

Wo Commit-Hashes wie folgt sind:

  • h1
  • h2 ...
  • hn
  • hn + 1

Führen Sie dann den folgenden Befehl aus:
git reset hn

Jetzt ist der KOPF bei hn + 1. Änderungen von h1 nach hn werden nicht bereitgestellt.

Vasantha Ganesh K.
quelle