Eine Ergänzung zur akzeptierten Antwort: Wenn Ihre versehentlich hinzugefügte Datei sehr groß war, werden Sie wahrscheinlich feststellen, dass sie auch nach dem Entfernen aus dem Index mit ' git reset
' immer noch Speicherplatz im .git
Verzeichnis belegt.
Dies ist kein Grund zur Sorge; Die Datei befindet sich zwar noch im Repository, aber nur als "loses Objekt". Es wird nicht in andere Repositorys kopiert (per Klon, Push), und der Speicherplatz wird schließlich zurückgefordert - wenn auch möglicherweise nicht sehr bald. Wenn Sie Angst haben, können Sie laufen:
git gc --prune=now
Update (was folgt, ist mein Versuch, einige Verwirrungen zu beseitigen, die sich aus den am besten bewerteten Antworten ergeben können):
Also, was ist das wahre Rückgängigmachen von git add
?
git reset HEAD <file>
?
oder
git rm --cached <file>
?
Genau genommen, und wenn ich mich nicht irre: keine .
git add
kann nicht rückgängig gemacht werden - sicher im Allgemeinen.
Erinnern wir uns zuerst daran, was git add <file>
tatsächlich tut:
Wenn <file>
wurde bisher nicht verfolgt , git add
fügt sie den Cache , mit seinem aktuellen Inhalt.
Wenn <file>
wurde bereits verfolgt , git add
speichert den aktuellen Inhalt (Snapshot, Version) in den Cache. In Git wird diese Aktion immer noch als Hinzufügen bezeichnet (nicht nur als Aktualisierung ), da zwei verschiedene Versionen (Snapshots) einer Datei als zwei verschiedene Elemente betrachtet werden. Daher fügen wir dem Cache tatsächlich ein neues Element hinzu, um schließlich zu sein später begangen.
Vor diesem Hintergrund ist die Frage etwas mehrdeutig:
Ich habe fälschlicherweise Dateien mit dem Befehl hinzugefügt ...
Das OP-Szenario scheint das erste zu sein (nicht verfolgte Datei). Wir möchten, dass durch "Rückgängig" die Datei (nicht nur der aktuelle Inhalt) aus den verfolgten Elementen entfernt wird. Wenn dies der Fall ist, ist es in Ordnung zu laufen git rm --cached <file>
.
Und wir könnten auch rennen git reset HEAD <file>
. Dies ist im Allgemeinen vorzuziehen, da es in beiden Szenarien funktioniert: Es wird auch rückgängig gemacht, wenn wir fälschlicherweise eine Version eines bereits verfolgten Elements hinzugefügt haben.
Es gibt jedoch zwei Einschränkungen.
Erstens: Es gibt (wie in der Antwort ausgeführt) nur ein Szenario, in dem git reset HEAD
dies nicht funktioniert, aber git rm --cached
funktioniert: ein neues Repository (keine Commits). Aber das ist wirklich ein praktisch irrelevanter Fall.
Zweitens: Beachten Sie, dass git reset HEAD
der zuvor zwischengespeicherte Dateiinhalt nicht auf magische Weise wiederhergestellt werden kann, sondern nur vom HEAD neu synchronisiert wird. Wenn unser git add
Irrtum eine zuvor bereitgestellte, nicht festgeschriebene Version überschrieben hat, können wir sie nicht wiederherstellen. Genau deshalb können wir [*] nicht rückgängig machen.
Beispiel:
$ git init
$ echo "version 1" > file.txt
$ git add file.txt # First add of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add file.txt # Stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt
$ git diff file.txt
-version 2
+version 3
$ git add file.txt # Oops we didn't mean this
$ git reset HEAD file.txt # Undo?
$ git diff --cached file.txt # No dif, of course. stage == HEAD
$ git diff file.txt # We have irrevocably lost "version 2"
-version 1
+version 3
Dies ist natürlich nicht sehr kritisch, wenn wir nur dem üblichen verzögerten Workflow folgen, bei dem 'git add' nur zum Hinzufügen neuer Dateien ausgeführt wird (Fall 1), und neue Inhalte über den git commit -a
Befehl commit, aktualisieren .
* (Bearbeiten: Das oben Gesagte ist praktisch korrekt, aber es kann dennoch einige leicht hackige / verschlungene Möglichkeiten geben, Änderungen wiederherzustellen, die inszeniert, aber nicht festgeschrieben und dann überschrieben wurden - siehe die Kommentare von Johannes Matokic und iolsmit).
HEAD
oderhead
können jetzt@
anstelle vonHEAD
stattdessen verwendet werden. In dieser Antwort (letzter Abschnitt) erfahren Sie, warum Sie das tun können.