Wie entferne ich Dateien, die im Gitignore aufgeführt sind, sich aber noch im Repository befinden?


327

Ich habe einige Dateien in meinem Repository, die ignoriert werden sollten. Ich habe sie dem .gitignore hinzugefügt, aber natürlich werden sie nicht aus meinem Repository entfernt.

Meine Frage ist also, gibt es einen magischen Befehl oder ein Skript mit Filterzweig, mit dem ich meinen Verlauf neu schreiben und all diese Dateien einfach entfernen kann? Oder einfach ein Befehl, der ein Commit erstellt, das sie entfernt?





WARNUNG: Dadurch wird zwar die physische Datei nicht von Ihrem lokalen Computer entfernt, beim nächsten Git-Pull werden jedoch die Dateien von anderen Entwicklercomputern entfernt. Wie kann man Git dazu bringen, eine Datei zu "vergessen", die verfolgt wurde, sich aber jetzt in .gitignore befindet?
Kris Roofe

@Stevoisiak Dies ist kein Duplikat dieser Frage, da diese nach ALLEN ignorierten Dateien fragt und auch eine bessere Antwort hat als jede der ähnlichen Fragen.
Omn

Antworten:


436

Sie können sie manuell aus dem Repository entfernen:

git rm --cached file1 file2 dir/file3

Oder wenn Sie viele Dateien haben:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

Dies scheint jedoch in Git Bash unter Windows nicht zu funktionieren. Es wird eine Fehlermeldung ausgegeben. Folgendes funktioniert besser:

git ls-files -i --exclude-from=.gitignore | xargs git rm --cached  

In Bezug auf das Umschreiben des gesamten Verlaufs ohne diese Dateien bezweifle ich sehr, dass es einen automatischen Weg gibt, dies zu tun.
Und wir alle wissen, dass es schlecht ist, die Geschichte neu zu schreiben, nicht wahr? :) :)


2
Leider funktioniert der Befehl Git Bash unter Windows nicht mit Pfaden, die Leerzeichen enthalten
Nate Bundy

19
@ Cupcake danke. git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedscheint den Trick zu tun
Nate Bundy

3
Ich hatte das gleiche Problem mit Windows. Ich benutze Powershell und in meinem Fall habe ich den dritten Befehl von @ samy-dindane erhalten und ihn in einen foreach geändert. Es wurde diesgit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomatias

1
"git ls-files -i --exclude-from = .gitignore" ist sehr hilfreich und sagt mir, welche Dateien von .ignore ausgeschlossen werden.
Owen Cao

1
Ich war froh, diese Befehle zu finden, ABER es entfernt die Dateien nicht wirklich aus dem Repository. Als ich 2300 kB Bilder entfernte, sank die Repository-Größe nur um 10 kB. So kann es beispielsweise nicht verwendet werden, um das Repository kleiner und schneller zu übertragen.
Jan Potužník

342

Eine einfachere Möglichkeit, die auf jedem Betriebssystem funktioniert, ist dies

git rm -r --cached .
git add .
git commit -m "Removing all files in .gitignore"

Sie haben im Grunde alle Dateien gelesen, außer denen im .gitignore


1
Wie wirkt sich dies auf andere Benutzer auf dem Repo aus, die einen Pull ausführen - während ich es lese, wird der Ordner gelöscht, den wir nicht mehr verfolgen möchten? Wie können wir das verhindern - wir wollen nur die Spur aufheben
snh_nl

Dadurch werden alle Dateien als geändert mit einer gefälschten Festschreibungsnachricht markiert!
Haidar Zeineddine

3
Was meinst du mit gefälschter Commit-Nachricht? Es ist eine echte Commit-Nachricht: P Sie können die Nachricht natürlich ändern, je nach Ihren Bedürfnissen ...
GTATR

1
Der Vollständigkeit halber benötigen Sie am Ende den Befehl git push.
Mariusz Bialobrzeski

1
Tun Sie dies nicht, es wird den Verlauf aller Dateien entfernen
agrath

144

Da die Dateien in .gitignore nicht verfolgt werden, können Sie mit dem Befehl git clean Dateien rekursiv entfernen, die nicht der Versionskontrolle unterliegen.

Verwenden Sie git clean -xdndiese Option , um einen Trockenlauf durchzuführen und zu sehen, was entfernt wird.
Dann verwenden Sie git clean -xdf, um es auszuführen.

Grundsätzlich git clean -hoder man git-clean(unter Unix) gibt Ihnen Hilfe.

Beachten Sie, dass mit diesem Befehl auch neue Dateien entfernt werden , die sich nicht im Staging-Bereich befinden.

Ich hoffe es hilft.


6
Dies sollte die akzeptierte Antwort sein. Es funktioniert tatsächlich (die akzeptierte Antwort hat bei mir unter macOS nicht funktioniert) und es ist viel sauberer.
Roger Oba

25
Diese Antwort ist nicht anwendbar - die OP sagt die Dateien in .gitignore werden verfolgt.
Ken Williams

20
IN ACHT NEHMEN! Dadurch werden alle nicht verfolgten Dateien dauerhaft gelöscht, anstatt nur aus dem Zweig entfernt zu werden
Emmanuel

1
Das git clean -xdnist ein Trockenlauf, der nicht gelöscht wird. der nächste wird.
JohnZaj

17
-1: Dies ist eine sehr irreführende Antwort - das Originalposter wollte aus dem Repository entfernt werden, nicht die Dateien vollständig entfernen. Ich war so kurz davor, eine Menge dynamischer Dateien zu löschen, die von meiner IDE benötigt wurden, aber nicht im Repo sein mussten.
Auspice

4

Ich habe eine sehr einfache Lösung gefunden, indem ich die Ausgabe der .gitignore-Anweisung mit sed manipuliert habe:

cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash

Erläuterung:

  1. Drucken Sie die Gitignore-Datei
  2. Entfernen Sie alle Kommentare aus dem Druck
  3. Alle Leerzeilen löschen
  4. Fügen Sie 'git rm -r' am Anfang der Zeile hinzu
  5. Führen Sie jede Zeile aus.

10
sedist geradeaus?
IgorGanapolsky

0

Unter Linux können Sie diesen Befehl verwenden:

Zum Beispiel möchte ich "* .py ~" löschen, also sollte mein Befehl ==> sein

find . -name "*.py~" -exec rm -f {} \;


-3

Der Git ignoriert die Dateien, die mit dem Gitignore-Muster übereinstimmen, nachdem Sie es zu Gitignore hinzugefügt haben.

Die bereits im Repository vorhandenen Dateien befinden sich jedoch noch im.

Verwenden Sie git rm files_ignored; git commit -m 'rm no use files'diese Option, um ignorierte Dateien zu löschen.


4
Es gibt viele von ihnen. Gibt es eine Möglichkeit, sie zu löschen, ohne ihre Namen angeben zu müssen?
Intrepidd
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.