Eine häufige Frage bei der ersten Arbeit mit Git ist: "Wie kann ich Git sagen, dass eine Datei (oder mehrere Dateien) nicht mehr länger nachverfolgt werden sollen?". Der Befehl git rm wird verwendet, um Dateien aus einem Git-Repository zu löschen. Er kann als Gegenstück zum git add Befehl betrachtet werden.

Git rm – Übersicht

Der Befehl git rm kann verwendet werden, um einzelne Dateien oder eine Gruppe von Dateien zu entfernen. Die primäre Funktion von git rm ist die Entfernung der nachverfolgten Dateien aus dem Git-Index. Zusätzlich kann git rm eingesetzt werden, um Dateien aus dem Staging-Index und dem Arbeitsverzeichnis zu entfernen. Es gibt keine Option, mit der eine Datei allein aus dem Arbeitsverzeichnis entfernt werden kann. Die Dateien, mit denen der Befehl arbeitet, müssen mit den Dateien im aktuellen HEAD identisch sein. Falls es eine Diskrepanz zwischen der HEAD-Version einer Datei und dem Staging-Index oder einer Arbeitsbaumversion gibt, blockiert Git das Entfernen. Dies ist eine Sicherheitsvorkehrung, um ein Entfernen möglicher aktuell in Bearbeitung befindlicher Änderungen zu unterbinden.

Beachte, dass git rm keine Branches entfernt. Weitere Informationen dazu findest du unter Verwenden von Git-Branches

Anwendung

<file>…​

Gibt die zu entfernende Zieldatei an. Der Optionswert kann eine einzelne Datei, eine mit Leerstellen getrennte Dateiliste file1 file2 file3 oder ein Wildcard-Dateiauswahl (~./directory/*) sein.

-f
--force

Die Option -f wird verwendet, um die Sicherheitsprüfung zu umgehen, die Git durchführt, um sicherzustellen, dass die Dateien im HEAD zum aktuellen Inhalt des Staging-Index und des Arbeitsverzeichnisses passen.

-n
--dry-run

Die Option "dry run" ist ein Schutz, mit dem der Befehl git rm ausgeführt, die Dateien aber nicht tatsächlich gelöscht werden. Stattdessen wird ausgegeben, welche Dateien von der Löschung betroffen wären.

-r

Die Option -r ist die abgekürzte Variante für "recursive". Bei Betrieb im rekursiven Modus entfernt git rm ein Zielverzeichnis und den gesamten Inhalt dieses Verzeichnisses.

--

Die Trennoption wird verwendet, um ausdrücklich zwischen einer Liste von Dateinamen und den an git rm weitergegebenen Befehlszeilenargumenten zu unterscheiden. Dies ist nützlich, wenn einige der Dateinamen eine Syntax aufweisen, die mit anderen Optionen verwechselt werden könnte.

--cached

Die Option cached gibt an, dass die Löschung nur im Staging-Index erfolgen soll. Die Dateien im Arbeitsverzeichnis werden nicht angerührt.

--ignore-unmatch

Diese Option führt dazu, dass der Befehl mit einem Sigterm-Status 0 beendet wird, selbst wenn keine passenden Dateien gefunden wurden. Dies ist ein Statuscode auf Unix-Ebene. Der Code 0 zeigt eine erfolgreiche Ausführung des Befehls an. Die Option --ignore-unmatch kann nützlich sein, wenn git rm als Teil eines größeren Shell-Skripts eingesetzt wird, das ordentlich fehlschlagen muss.

-q
--quiet

Die Option quiet verbirgt die Ausgabe des Befehls git rm. Der Befehl gibt normalerweise eine Zeile für jede entfernte Datei aus.

So wird git rm rückgängig gemacht

Das Ausführen von git rm ist kein permanentes Update. Der Befehl aktualisiert den Staging-Index und das Arbeitsverzeichnis. Diese Änderungen werden nicht dauerhaft übertragen, bis ein neuer Commit erstellt und die Änderungen zum Commit-Verlauf hinzugefügt werden. Dies bedeutet, dass die hier durchgeführten Änderungen auch mit den normalen Git-Befehlen "rückgängig" gemacht werden können.

git reset HEAD

Ein Reset setzt den aktuellen Staging-Index und das Arbeitsverzeichnis wieder auf den HEAD Commit zurück. Dies macht ein git rm rückgängig.

git checkout .

Ein Check-out hat dieselbe Wirkung und stellt die letzte Version einer Datei aus dem HEAD wieder her.

Für den Fall, dass git rm ausgeführt und ein neuer Commit erstellt wurde, der die Löschung dauerhaft durchführt, kann git reflog verwendet werden, um eine Referenz zu finden, die vor der Ausführung von git rm lag. Weitere Informationen dazu findest du unter Verwenden von git reflog.

Diskussion

Das an den Befehl weitergegebene <file>-Argument kann eine genaue Pfadangabe, Dateisammelausdrücke mit Wildcards oder auch genaue Verzeichnisnamen enthalten. Der Befehl entfernt nur Verzeichnisse, die aktuell im Git-Repository committed sind.

Dateisammelausdrücke mit Wildcards werden über Verzeichnisse hinweg abgeglichen. Man sollte bei der Verwendung von Wildcard-Ausdrücken unbedingt vorsichtig sein. Sehen wir uns dazu ein Beispiel an: directory/* und directory*. Das erste Beispiel entfernt alle Unterverzeichnisse von directory/ während das zweite Beispiel alle gleichgeordneten Verzeichnisse wie directory1 directory2 directory_whatever entfernt, was ein unerwartetes Ergebnis sein kann.

Der Umfang von git rm

Der Befehl git rm arbeitet nur auf dem aktuellen Branch. Das Löschen wird nur auf das Arbeitsverzeichnis und den Staging-Index-Baum angewendet. Die Dateilöschung wird nicht in den Repository-Verlauf übertragen, bis ein neuer Commit erstellt wird.

Warum besser git rm anstatt rm verwenden

Ein Git-Repository erkennt, wenn ein normaler rm Befehl auf einer Datei ausgeführt wurde, die nachverfolgt wird. Das Arbeitsverzeichnis wird aktualisiert, um die Löschung widerzuspiegeln. Es wird aber nicht der Staging-Index mit der Löschung aktualisiert. Ein zusätzlicher git add Befehl muss auf den gelöschten Dateiverzeichnissen ausgeführt werden, um die Änderungen zum Staging-Index hinzuzufügen. Der Befehl git rm funktioniert wie ein Shortcut, da hier das Arbeitsverzeichnis und der Staging-Index mit der Löschung aktualisiert werden.

Beispiele

git rm Documentation/\*.txt

In diesem Beispiel wird ein Wildcard-Dateisammelausdruck verwendet, um alle *.txt Dateien zu entfernen, die im Documentation-Verzeichnis oder einem seiner Unterverzeichnisse liegen.

Beachte, dass das Sternchen * in diesem Beispiel mit Schrägstrich beendet wird. Mit diesem Schutzmechanismus wird verhindert, dass in der Befehlszeile das Wildcard-Symbol erweitert wird. Die Wildcard erweitert dann die Verzeichnisnamen um Dateien und Unterverzeichnisse unterhalb des Verzeichnisses Documentation/.

git rm -f git-*.sh

In diesem Beispiel wird die Option Force eingesetzt und es werden alle Wildcard git-*.sh Dateien angesprochen. Die Force-Option löscht die Zieldateien explizit aus dem Arbeitsverzeichnis und dem Staging-Index.

So werden Dateien gelöscht, die nicht mehr im Dateisystem sind

Wie bereits oben in "Warum besser git rm anstatt rm verwenden" erklärt, ist git rm ein sehr praktischer Befehl, der die Standardbefehle rm und git add kombiniert, um eine Datei aus dem Arbeitsverzeichnis zu entfernen und diese Löschung in den Staging-Index zu übertragen. Wenn mehrere Dateien nur mit dem einfachen Befehl rm gelöscht werden, kann ein Repository schnell sperrig werden.

Wenn alle explizit gelöschten Dateien als Teil des nächsten Commit festgeschrieben werden sollen, fügt git commit -a in Vorbereitung des nächsten Commits alle Löschereignisse dem Staging-Index hinzu.

Falls jedoch die mit rm entfernten Dateien dauerhaft gelöscht werden sollen, verwende den folgenden Befehl:

git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

Dieser Befehl erzeugt eine Liste der aus dem Arbeitsverzeichnis gelöschten Dateien und leitet diese Liste an git rm --cached weiter, was dann den Staging-Index aktualisiert.

Git rm – Zusammenfassung

git rm ist ein Befehl, der zwei der primären internen Zustandsverwaltungsbäume von Git bearbeitet: das Arbeitsverzeichnis und den Staging-Index. git rm wird verwendet, um eine Datei aus einem Git-Repository zu löschen. Dies ist eine praktische Methode, da die Ergebnisse der Standardbefehle rm mit git add kombiniert werden. Dies bedeutet, dass zuerst ein Ziel aus dem Dateisystem entfernt wird und dann das Löschereignis an den Staging-Index weitergegeben wird. Der Befehl ist einer von vielen, die eingesetzt werden können, um Änderungen in Git rückgängig zu machen.