"Git rm --cached x" vs "git reset head - x"?


163

GitRef.org - Basic :

git rmentfernt Einträge aus dem Staging-Bereich. Dies ist ein bisschen anders als bei git reset HEAD"Staging" -Dateien. Mit "unstage" meine ich, dass der Staging-Bereich auf das zurückgesetzt wird, was dort war, bevor wir anfingen, Dinge zu ändern. git rmAuf der anderen Seite wird die Datei nur vollständig von der Bühne geworfen, sodass sie nicht im nächsten Commit-Snapshot enthalten ist, wodurch sie effektiv gelöscht wird.

Standardmäßig git rm fileentfernt a die Datei vollständig aus dem Staging-Bereich und auch von Ihrer Festplatte> (dem Arbeitsverzeichnis). Um die Datei im Arbeitsverzeichnis zu belassen, können Sie verwenden git rm --cached.

Aber was genau ist der Unterschied zwischen git rm --cached asdund git reset head -- asd?

Antworten:


219

Es gibt drei Stellen, an denen sich beispielsweise eine Datei befinden kann - den Baum, den Index und die Arbeitskopie. Wenn Sie einem Ordner nur eine Datei hinzufügen, fügen Sie sie der Arbeitskopie hinzu.

Wenn Sie so etwas tun, git add filefügen Sie es dem Index hinzu. Und wenn Sie es festschreiben, fügen Sie es auch dem Baum hinzu.

Es wird Ihnen wahrscheinlich helfen, die drei häufigsten Flags beim Zurücksetzen von Git zu kennen:

Git Reset [- <mode>] [ <commit>]

Dieses Formular setzt den aktuellen Verzweigungskopf zurück <commit>und aktualisiert möglicherweise den Index (Zurücksetzen auf den Baum von <commit>) und den Arbeitsbaum, je nachdem <mode>, welcher der folgenden Werte sein muss:
--soft

Berührt weder die Indexdatei noch den Arbeitsbaum (setzt jedoch den Kopf auf zurück <commit>, genau wie in allen Modi). Dadurch bleiben alle geänderten Dateien "Änderungen müssen festgeschrieben werden", wie der Git-Status es ausdrücken würde.

--gemischt

Setzt den Index, aber nicht den Arbeitsbaum zurück (dh die geänderten Dateien werden beibehalten, aber nicht für das Festschreiben markiert) und meldet, was nicht aktualisiert wurde. Dies ist die Standardaktion.

--schwer

Setzt den Index und den Arbeitsbaum zurück. Alle Änderungen an nachverfolgten Dateien im Arbeitsbaum seitdem <commit>werden verworfen.

Wenn Sie nun so etwas tun git reset HEAD- was Sie tatsächlich tun, ist, git reset HEAD --mixeddass der Index auf den Zustand "zurückgesetzt" wird, der vor dem Hinzufügen von Dateien / Hinzufügen von Änderungen zum Index (über git add) war. In diesem Fall die Arbeitskopie und die Index (oder Staging) waren synchron, aber Sie haben HEAD und Index nach dem Zurücksetzen synchronisiert.

git rmAuf der anderen Seite wird eine Datei aus dem Arbeitsverzeichnis und dem Index entfernt. Wenn Sie ein Commit ausführen, wird die Datei auch aus dem Baum entfernt. git rm --cachedEntfernt die Datei jedoch nur aus dem Index und behält sie in Ihrer Arbeitskopie. Dies ist das genaue Gegenteil von git add file In diesem Fall haben Sie den Index so gestaltet, dass er sich vom HEAD und vom funktionierenden unterscheidet. Der HEAD verfügt über die zuvor festgeschriebene Version der Datei. Die Arbeitskopie hatte die letzte Änderung, falls vorhanden, oder den Inhalt von HEAD von die Datei und Sie haben die Datei aus dem Index entfernt. Ein Commit synchronisiert jetzt den Index und den Baum und die Datei wird entfernt.


Ich stelle fest, dass nach git rm --cacheddem git diffBefehl kein Diff angezeigt wird, sondern git diff --cachedder Diff, als ob er noch zwischengespeichert wäre. Das git statuszeigt jedoch die Datei als Untracked. Scheint irgendwie inkonsistent.
Haridsv

7
Egal ... ich hätte es benutzen sollen git reset --mixed. Ich war ein wenig verwirrt von der Aussage, git rm --cacheddie das Gegenteil von ist git add. Wörtlich genommen ist es falsch und kann Schäden verursachen. In meinem Fall habe ich git adddem Staging-Bereich eine geänderte Datei hinzugefügt und wollte das Gegenteil von "das Hinzufügen" und nicht das anfängliche Hinzufügen der Datei. + Greg Hewgills Antwort hat mir geholfen, ein klareres Bild zu bekommen.
Haridsv

12
Ich finde die Verwendung von Arbeitskopie, Baum und Arbeitsbaum etwas verwirrend. Ist der Arbeitsbaum die Arbeitskopie oder der Baum?
Nealv

3
Wie @haridsv erwähnt hat, ist es irreführend zu sagen, git rm --cached"ist das genaue Gegenteil von git add file". git reset fileist näher am Gegenteil von git add file.
Matt Browne

@Nealv verspätet, aber für andere, die diesen Thread finden: Arbeitskopie, Baum und Arbeitsbaum beziehen sich alle auf dasselbe (im Kontext von git).
De Novo

83

Vielleicht hilft ein Beispiel:

git rm --cached asd
git commit -m "the file asd is gone from the repository"

gegen

git reset HEAD -- asd
git commit -m "the file asd remains in the repository"

Beachten Sie , dass das zweite Commit nichts bewirkt , wenn Sie nichts anderes geändert haben.


3
Können Sie mir sagen, was dieser doppelte Bindestrich bedeutet - nachdem HEAD tatsächlich bedeutet?
Yuva

30
@yuva: Mit --wird Befehlsoptionen von Dateinamen getrennt. Wenn es sowohl einen Zweig als auch eine Datei mit dem Namen gäbe asd, git reset HEAD asdwäre dies mehrdeutig. Das --sagt "alles, was darauf folgt, ist ein Dateiname".
Greg Hewgill

Ist git reset HEAD <file>genau das gleiche wie git rm --cached <file>und dann git add --intent-to-add <file>?
Alkohol ist böse

1
@ Alkoholisevil nein, außer in einem besonderen Fall. Sehen Sie diese ausgezeichnete, prägnante Antwort.
De Novo

45

git rm --cached filewird entfernen Sie die Datei von der Bühne. Das heißt, wenn Sie festschreiben, wird die Datei entfernt. git reset HEAD -- fileSetzt die Datei im Staging-Bereich einfach auf den Zustand zurück, in dem sie sich beim HEAD-Commit befand, dh macht alle Änderungen rückgängig, die Sie seit dem letzten Commit daran vorgenommen haben. Wenn diese Änderung die Datei neu hinzufügt, sind sie gleichwertig.


7
In Verbindung mit dem Begriff (wie in anderen Antworten erwähnt), der git rm --cached filedas Gegenteil von ist git add, ergab diese Antwort für mich sehr viel Sinn und war ziemlich prägnant. Fast so kurz wie dieser Kommentar;)
rbatt

2
@rbatt, nur um den Kommentar auch hier zu setzen und zu verdeutlichen, git rm --cached fileist nicht das Gegenteil vongit add file . Das Verhalten ist genau das Gegenteil von dem git add filein dem speziellen Fall, in dem Sie eine neue, zuvor nicht verfolgte Datei hinzugefügt haben. In jedem anderen Fall des anderen git add fileist git reset HEAD file. git reset HEAD filekehrt sich auch git add fileim ersten Fall um (Hinzufügen einer nicht verfolgten Datei) und in jedem Fall, weshalb es das ist, was git vorschlägt, wenn Sie ein git-Add umkehren möchten.
De Novo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.