Git: Wie macht man git add rückgängig?
Du hast etwas gestaged, das du nicht wolltest. Es wieder aus dem Index zu nehmen ist ein Befehl — es gibt aber einen sehr ähnlichen Befehl, ein Wort daneben, der die Änderung selbst wegwirft. Es lohnt sich zu wissen, welcher welcher ist.
Aus dem Index nehmen
user@pc:~$ git restore --staged file.txt
staged : "M tracked.txt" "A untracked.txt"
restore --staged : " M tracked.txt" "?? untracked.txt"
file still : changed
Die Änderung steckt weiterhin in deiner Datei. Zurückgenommen wurde nur der Index.
git restore gibt es seit Git 2.23.
Jede ältere Antwort schreibt stattdessen das hier, und es tut genau dasselbe:
user@pc:~$ git reset HEAD file.txt
Beides ist in Ordnung. restore --staged sagt deutlicher, was es tut, und
reset ist das, was dir in bestehenden Skripten begegnet.
Das Ergebnis lesen
git status --short gibt zwei Spalten
aus: die erste ist der Index, die zweite das Arbeitsverzeichnis.
M tracked.txt gestaged
M tracked.txt nicht gestaged
?? untracked.txt gar nicht getrackt
Ein M, das von der ersten in die zweite Spalte wandert, ist also das
Zurücknehmen. Darauf zu achten ist einfacher, als sich zu merken welcher Befehl
was gemacht hat.
Beachte, dass die neu hinzugefügte Datei wieder auf ?? steht und nicht auf
“geändert” — sie war nie getrackt, das Zurücknehmen macht sie also wieder zu
etwas, das git nicht kennt.
Das Wort, das alles ändert
user@pc:~$ git restore --staged file.txt # zuruecknehmen, Aenderung bleibt
user@pc:~$ git restore file.txt # Aenderung VERWERFEN
Ohne --staged stellt restore das Arbeitsverzeichnis aus dem Index
wieder her:
git restore tracked.txt (ohne --staged)
status : 'M tracked.txt'
file : changed
Lies das genau: In der Datei steht weiterhin changed, weil sie vorher gestaged
war und restore sie aus dem Index wiederhergestellt hat. Die gestagte
Version hat also gewonnen, und jede spätere Änderung ist weg. Bei einer nicht
gestagten Änderung setzt derselbe Befehl die Datei stillschweigend auf den
zuletzt committeten Stand zurück.
Ein Zurück gibt es nicht. Die verworfene Fassung war nie committet, es liegt
also nichts in der Objektdatenbank und git reflog findet nichts. Von allem in
dieser Reihe sind dieser Befehl und git clean die beiden, die wirklich Arbeit
vernichten.
Willst du beides — aus dem Index nehmen und verwerfen — dann schreib es in zwei Schritten, damit der zerstörerische bewusst passiert.
Alles auf einmal zurücknehmen
user@pc:~$ git restore --staged .
Dasselbe wie für eine einzelne Datei, nur für den ganzen Baum. git reset ohne
Pfade tut dasselbe — deshalb siehst du in älteren Antworten ein nacktes
git reset. Ohne --hard fasst es nur den Index an und ist damit ungefährlich.
Vor dem ersten Commit funktioniert es nicht
Das hat mich überrascht, und die Demo hat den Artikel korrigiert:
user@pc:~$ git reset HEAD a.txt
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
user@pc:~$ git restore --staged a.txt
fatal: could not resolve 'HEAD'
status : A a.txt <- still staged
Ich hatte erwartet, dass der neuere Befehl damit zurechtkommt. Tut er nicht.
Beide brauchen einen Commit, auf den sie den Index zurücksetzen können, und in
einem Repository, dessen erster Commit noch aussteht, gibt es kein HEAD.
Was dort funktioniert:
user@pc:~$ git rm --cached a.txt
?? a.txt
git rm --cached entfernt den Eintrag aus
dem Index und lässt die Datei in Ruhe — und genau das heißt “aus dem Index
nehmen”, wenn es nichts gibt, womit man vergleichen könnte.
Hinweis zu Netcup (Werbung)
Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).