git - Löschen von einem Ordner aus dem Repository nachdem er zu .gitignore hinzugefügt wurde

Ein Ordner liegt im git-Repo, obwohl er in der .gitignore steht? git rm -r —cached nimmt ihn aus dem Index, ohne ihn lokal zu löschen — samt der drei Fallstricke dabei.

Mit einer .gitignore legst du fest, welche Dateien und Ordner Git unbeachtet lässt. Der Haken daran: Die Datei wirkt nur nach vorn. Die Git-Dokumentation sagt es in einem Satz: „Files already tracked by Git are not affected“.

Genau daran scheitert der häufigste Fall. Der Ordner ist längst committet und gepusht, und erst danach fällt auf, dass node_modules, vendor oder ein Build-Verzeichnis nichts im Repository verloren haben. Der neue Eintrag in der .gitignore ändert daran nichts, solange der Ordner im Index steht. Dieser Beitrag zeigt, wie du ihn dort herausbekommst, ohne ihn auf deinem Rechner zu verlieren. Drei Stellen gibt es, an denen der Befehl weniger tut, als man von ihm erwartet; sie stehen weiter unten.

Warum der Eintrag in .gitignore nicht mehr greift

Ob Git eine Datei noch verfolgt, beantwortet git ls-files. Wer wissen will, welche Regel greifen würde, fragt git check-ignore. Die Dokumentation führt es als Werkzeug zum Debuggen von gitignore-Dateien:

git ls-files | grep mein-ordner
git check-ignore -v mein-ordner/datei.txt

Die zweite Zeile antwortet mit Quelle, Zeilennummer und Muster, also etwa .gitignore:1:mein-ordner/ mein-ordner/datei.txt. Hier laufen viele in die Irre: git check-ignore bestätigt, dass das Muster passt, und trotzdem steht die Datei weiter in der Liste von git ls-files. Beides stimmt gleichzeitig. Die Ignorier-Regeln entscheiden nur über unverfolgte Dateien; über eine Datei, die bereits im Index liegt, haben sie keine Gewalt.

Den Ordner aus dem Index nehmen

Trage den Ordner also zuerst in die .gitignore ein. Danach nimmst du ihn mit dem folgenden Befehl aus dem Repository heraus. Auf deinem Rechner bleibt er dabei liegen, gelöscht wird er nur im git-Repo:

git rm -r --cached mein-ordner
git commit -m 'Löschen des nun ignorierter Ordners "mein-ordner"'
git push origin master

Zwei Schalter tragen den Befehl. --cached beschränkt die Löschung auf den Index: „Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.“ Und -r erlaubt dasselbe für ein ganzes Verzeichnis statt für eine einzelne Datei („Allow recursive removal when a leading directory name is given“).

Nach dem Commit ist der Ordner aus der Verfolgung heraus. Ab jetzt greift die .gitignore, denn nun ist er das, wofür sie gemacht ist: unverfolgt.

Drei Dinge, die der Befehl nicht erledigt

In den Arbeitskopien der anderen verschwindet der Ordner wirklich. Das --cached schützt deine Arbeitskopie, nicht die deiner Mitarbeiter. Der Commit trägt eine Löschung, und wer ihn zieht, bei dem räumt Git das Verzeichnis ab. Ein Build-Ordner ist danach in einer Minute neu erzeugt, eine lokale Konfigurationsdatei oder eine gewachsene Datenbank nicht. Sag deshalb vorher Bescheid. Für Konfigurationsdateien legst du ohnehin besser eine beispiel.env ins Repo, die niemandem fehlt, wenn sie verschwindet.

Die alten Commits behalten den Inhalt. Entfernt wird der Ordner ab diesem Commit, nicht rückwirkend. git show :mein-ordner/datei fördert ihn weiterhin zutage, und geklont wird er mit. Bei einem Build-Ordner ist das gleichgültig. Waren es Zugangsdaten, fängt die Arbeit hier erst an: GitHub nennt als ersten Schritt ausdrücklich nicht das Umschreiben, sondern das Zurückziehen des Geheimnisses: „as a first step you need to revoke and/or rotate that secret“. Die History mit git filter-repo umzuschreiben kommt danach. Klone und Forks, die es zu diesem Zeitpunkt schon gibt, erreicht auch das nicht mehr.

Der Branchname master aus dem Befehl weiter oben ist nicht mehr selbstverständlich. GitHub legt neue Repositories seit dem 1. Oktober 2020 mit main an. Ein lokales git init bleibt dagegen bei master, solange init.defaultBranch nichts anderes sagt; die Umstellung ist für Git 3.0 angekündigt, ein Termin dafür steht nicht fest (nachgesehen in Git 2.55 vom 29. Juni 2026). In einem Repo, das beide Wege gesehen hat, rät man deshalb besser nicht:

git branch --show-current
git push origin HEAD

git push origin HEAD schiebt den Branch, auf dem du gerade stehst, und geht damit keinem der beiden Namen auf den Leim.

Wenn git rm den Dienst verweigert

Manchmal bricht der Befehl ab, statt zu löschen. Der Grund liegt dann im Index: Du hast eine Datei geändert, mit git add vorgemerkt und danach noch einmal geändert, sodass drei verschiedene Fassungen im Spiel sind. Die Dokumentation nennt die Bedingung: „the staged content has to match either the tip of the branch or the file on disk“. Die Meldung sieht so aus:

error: the following file has staged content different from both the
file and the HEAD:
    mein-ordner/datei.txt
(use -f to force removal)

Der Hinweis in der letzten Zeile ist wörtlich gemeint: -f verwirft den vorgemerkten Stand. Wer ihn noch braucht, committet ihn vorher oder legt ihn mit git stash zur Seite.

Den Index in einem Rutsch neu aufbauen

Ist die .gitignore über die Jahre gewachsen und du weißt gar nicht mehr, welche der eingetragenen Ordner schon im Repository liegen, lohnt der große Schnitt. Er nimmt alles aus dem Index und fügt es nach den geltenden Regeln neu hinzu:

git rm -r --cached .
git add .
git status --short

git status --short listet danach mit einem D genau die Pfade auf, die künftig ignoriert werden. Stimmt die Liste nicht, bringt dich git reset ohne Schaden zurück in den Ausgangszustand: Die Arbeitskopie fasst keiner der drei Befehle an.

Alle neuen Änderungen in dem Ordner werden ab sofort nicht mehr von git berücksichtigt. Beim nächsten Stagen und Pushen ist der Ordner im Repository nicht mehr dabei.

Viel Spaß!

Warum ignoriert git meinen Ordner trotz Eintrag in .gitignore?

Weil die Datei nur unverfolgte Dateien betrifft. Steht der Ordner schon im Index, weil er einmal committet wurde, greift keine Ignorier-Regel mehr. Erst git rm -r --cached mein-ordner nimmt ihn heraus, danach wirkt die .gitignore.

Löscht git rm --cached meine Dateien auf der Festplatte?

Nein. --cached arbeitet ausschließlich im Index, die Arbeitskopie bleibt unberührt. Ohne --cached löscht git rm dagegen beides.

Verschwindet der Ordner auch bei meinen Mitarbeitern?

Ja. Der Commit enthält eine Löschung, und die wird beim git pull in der Arbeitskopie nachvollzogen. Was dort nicht neu erzeugt werden kann, sollte vorher gesichert sein.

Sind die Dateien damit aus dem Repository verschwunden?

Nur ab diesem Commit. Alle älteren Commits enthalten sie weiterhin. Für Zugangsdaten reicht das nicht: Die muss man zurückziehen oder wechseln und die History anschließend mit git filter-repo umschreiben.

Wie finde ich heraus, ob mein Branch master oder main heißt?

git branch --show-current gibt den Namen aus. git push origin HEAD kommt ganz ohne die Angabe aus und pusht immer den gerade ausgecheckten Branch.