In diesem Abschnitt geht es um die genaue Beschreibung des Befehls git clean. Der Befehl git clean ermöglicht in gewisser Weise das Rückgängigmachen. git clean ist eine Art Ergänzung zu anderen Befehlen wie git reset und git checkout. Während sich die anderen Befehle auf Dateien auswirken, die zuvor dem Git-Tracking-Index hinzugefügt wurden, spricht der Befehl git clean nicht verfolgte Dateien an. Nicht verfolgte Dateien sind Dateien, die im Arbeitsverzeichnis deines Repositorys erstellt, aber noch nicht mit dem Befehl git add dem Index deines Repositorys hinzugefügt wurden. Die folgenden Befehlszeilen veranschaulichen den Unterschied zwischen verfolgten und nicht verfolgten Dateien:

$ mkdir git_clean_test
$ cd git_clean_test/
$ git init .
Initialized empty Git repository in /Users/kev/code/git_clean_test/.git/
$ echo "tracked" > ./tracked_file
$ git add ./tracked_file
$ echo "untracked" > ./untracked_file
$ mkdir ./untracked_dir && touch ./untracked_dir/file
$ git status
On branch master
Initial commit
Changes to be committed: (use "git rm --cached <file>..." to unstage)
new file: tracked_file
Untracked files: (use "git add <file>..." to include in what will be committed) untracked_dir/ untracked_file

In diesem Beispiel wird ein neues Git-Repository im Verzeichnis git_clean_test erstellt. Anschließend wird eine tracked_file erstellt und dem Git-Index hinzugefügt. Zusätzlich werden eine untracked_file und ein untracked_dir angelegt. In dem Beispiel wird dann git status ausgeführt, woraufhin der interne Git-Status von verfolgten und nicht verfolgten Änderungen angezeigt wird. In diesem Repository-Zustand können wir git clean ausführen, um zu zeigen, was dieser Befehl bewirkt.

$ git clean fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean

An dieser Stelle kann der Standard-Befehl git clean einen schwerwiegenden Fehler verursachen. Das Beispiel oben zeigt, wie das aussehen kann. Die globale Konfiguration von Git sieht vor, dass git clean standardmäßig mit der Option "force" ausgeführt wird. Das ist ein wichtiger Sicherheitsmechanismus. Wenn git clean am Ende ausgeführt wird, ist der Befehl nicht mehr rückgängig zu machen. Wird er vollständig ausgeführt, bewirkt git clean ein endgültiges Löschen des Dateisystems, ähnlich wie durch Ausführen der Befehlszeilenoption "rm". Stelle also sicher, dass du die nicht verfolgten Dateien löschen willst, bevor du den Befehl ausführst.

Allgemeine Optionen und Anwendungen

Nachdem wir erklärt haben, was mit git clean normalerweise geschieht und was zu beachten ist, wollen wir nun ein paar Anwendungsfälle für git clean und die dafür erforderlichen Befehlszeilenoptionen veranschaulichen.

-n

Die Option -n führt einen "Probelauf" mit git clean durch. So siehst du, welche Dateien entfernt werden, ohne dass sie tatsächlich entfernt werden. Ein Probelauf von git clean ist eine bewährte Methode. Diese Option lässt sich anhand unseres zuvor erstellten Demo-Repositorys demonstrieren:

$ git clean -n
Would remove untracked_file

Anhand des Outputs erkennen wir, dass die untracked_file beim Ausführen von git clean entfernt wird. Beachte, dass untracked_dir hier nicht genannt wird. git clean wird standardmäßig nicht rekursiv auf Verzeichnisse angewendet. Auch das ist ein Sicherheitsmechanismus, der dafür sorgt, dass nichts versehentlich dauerhaft gelöscht wird.

-f or --force

Die Option "force" leitet die Löschung nicht verfolgter Dateien vom aktuellen Verzeichnis aus ein. Wenn die Konfigurationsoption clean.requireForce auf "false" gesetzt ist, musst du "force" nicht verwenden. Die in der Datei .gitignore angegebenen nicht verfolgten Ordner und Dateien werden nicht entfernt. Führen wir git clean direkt einmal in unserem Beispiel-Repository aus.

$ git clean -f
Removing untracked_file

Auf den Befehl hin werden die gelöschten Dateien ausgegeben. Wie du sehen kannst, ist die untracked_file entfernt worden. Führst du an dieser Stelle git status aus oder gibst ls ein, wird angezeigt, dass untracked_file gelöscht wurde und nicht zu finden ist. git clean -f wird standardmäßig auf alle nicht verfolgten Dateien im aktuellen Verzeichnis angewendet. Zusätzlich kannst du einen <path>-Wert zur Option -f eingeben, um eine bestimmte Datei zu löschen.

git clean -f <path>
-d include directories

Die Option -d weist git clean an, dass du auch alle nicht verfolgten Verzeichnisse entfernen möchtest. Verzeichnisse werden standardmäßig ignoriert. Wir können die Option -d unseren vorherigen Beispielen hinzufügen:

$ git clean -dn
Would remove untracked_dir/
$ git clean -df
Removing untracked_dir/

Hier haben wir mit der Kombination -dn einen "Probelauf" durchgeführt, der die zu entfernenden untracked_dir ausgibt. Dann führen wir eine erzwungene Reinigung durch und erhalten die Ausgabe, dass untracked_dir entfernt wurde.

-x force removal of ignored files

Bei Software-Releases gibt es häufig ein Build- oder Verteilungsverzeichnis, das nicht in den Tracking-Index der Repositorys committet ist. Das Build-Verzeichnis enthält vorübergehende Build-Artefakte die aus dem committeten Quellcode generiert werden. Dieses Build-Verzeichnis wird normalerweise zur .gitignore-Datei der Repositorys hinzugefügt. Es kann praktisch sein, dieses Verzeichnis zusammen mit anderen nicht verfolgten Dateien zu bereinigen. Die Option -x weist git clean an, auch alle ignorierten Dateien einzubeziehen. Wie beim vorherigen Aufrufen von git clean hat es sich bewährt, vor der endgültigen Löschung einen "Probelauf" durchzuführen. Die Option -x wirkt sich auf alle ignorierten Dateien und nicht nur auf die des Projektbuilds aus. Dies könnte ungewollte Auswirkungen haben, wie zum Beispiel auf die IDE-Konfigurationsdateien unter ./.idea.

git clean -xf

Du kannst die Option -x wie auch -d zusammen mit anderen Optionen anwenden und kombinieren. In dieser Verbindung mit -f werden aus dem aktuellen Verzeichnis nicht verfolgte Dateien sowie auch all die Dateien entfernt, die Git normalerweise ignoriert.

Interaktiver Modus oder "git clean interactive"

Neben einzelnen Befehlen, die wir bisher ausgeführt haben, verfügt git clean auch über einen "interaktiven" Modus, den du mit der Option -i einleiten kannst. Werfen wir noch einmal einen Blick auf das Beispiel-Repository vom Anfang. In diesem anfänglichen Zustand starten wir eine interaktive Bereinigungssitzung.

$ git clean -di
Would remove the following items:
untracked_dir/ untracked_file
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help
What now>

Da wir die interaktive Sitzung mit der Option -d eingeleitet haben, wird dabei auch unser untracked_dir einbezogen. Im interaktiven Modus wirst du mit What now> dazu aufgefordert, einen Befehl auf die nicht verfolgten Dateien anzuwenden. Die Befehle selbst sind selbsterklärend. Werfen wir einen kurzen Blick darauf und beginnen wir einfach mal mit dem Befehl 6: help. Wenn du Befehl 6 auswählst, werden die anderen Befehl anschließend erklärt:

What now> 6
clean - start cleaning
filter by pattern - exclude items from deletion
select by numbers - select items to be deleted by numbers
ask each - confirm each deletion (like "rm -i")
quit - stop cleaning
help - this screen
? - help for prompt selection
5: quit

Es liegt auf der Hand: Dieser Befehl beendet die interaktive Sitzung.

1: clean

So kannst du die angegebenen Elemente löschen. Wenn wir 1: clean an dieser Stelle ausführen, wird untracked_dir/ untracked_file entfernt.

4: ask each

wird für jede nicht verfolgte Datei wiederholt. Zum Löschen erscheint eine Y/N (Ja/Nein)-Aufforderung. Das sieht in etwa so aus:

*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help
What now> 4
Remove untracked_dir/ [y/N]? N
Remove untracked_file [y/N]? N
2: filter by pattern

Zeigt eine zusätzliche Aufforderung zur Eingabe von Informationen für das Filtern der Liste nicht verfolgter Dateien an.

Would remove the following items:
untracked_dir/ untracked_file
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help
What now> 2
untracked_dir/ untracked_file
Input ignore patterns>> *_file
untracked_dir/

Hier folgen wir dem Muster des Platzhalters *_file. Daraufhin wird die Liste nicht verfolgter Dateien auf untracked_dir beschränkt.

3: select by numbers

Mit Befehl 3 kannst du, ähnlich wie mit Befehl 2, mehr Informationen zur Namensliste der nicht verfolgten Dateien anzeigen lassen. Bei der interaktiven Sitzung werden Zahlen zu den Namen der nicht verfolgten Dateien ausgegeben.

Would remove the following items:
untracked_dir/ untracked_file
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help
What now> 3
1: untracked_dir/ 2: untracked_file
Select items to delete>> 2
1: untracked_dir/ * 2: untracked_file
Select items to delete>>
Would remove the following item:
untracked_file
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help

Zusammenfassung

Zur Erinnerung: git clean ist ein praktischer Befehl zum Löschen nicht verfolgter Dateien im Arbeitsverzeichnis eines Repositorys. Nicht verfolgte Dateien sind Dateien im Arbeitsverzeichnis deines Repositorys, die noch nicht per git add dem Index deines Repositorys hinzugefügt wurden. Mit git clean erzielst du im Allgemeinen dasselbe Ergebnis, als würdest du git status und die nativen Tools zum Löschen verwenden, die dein Betriebssystem dir bietet. Wenn du git clean und git reset miteinander kombinierst, kannst du sämtliche Ergänzungen und Commits in einem Repository vollständig zurücksetzen.