Entfernen Sie eine Datei aus einem Git-Repository, ohne sie aus dem lokalen Dateisystem zu löschen

3047

Mein erstes Commit enthielt einige Protokolldateien. Ich habe *logzu meinem hinzugefügt .gitignore, und jetzt möchte ich die Protokolldateien aus meinem Repository entfernen.

git rm mylogfile.log

entfernt eine Datei aus dem Repository, entfernt sie aber auch aus dem lokalen Dateisystem.

Wie kann ich diese Datei aus dem Repo entfernen, ohne meine lokale Kopie der Datei zu löschen?

Mveerman
quelle
14
Es ist erwähnenswert, dass die am besten bewertete Antwort für einige gefährlich ist. Wenn Sie ein Remote-Repo verwenden, als wenn Sie Ihr lokales Repo drücken, ziehen Sie die Dateien, die Sie nur aus Git entfernt haben, an eine andere Stelle . Dies wird in einer der Antworten erwähnt, aber nicht kommentiert.
RichieHH

Antworten:

4354

Aus der Man-Datei :

Wenn --cachedangegeben, muss der bereitgestellte Inhalt entweder mit der Spitze des Zweigs oder mit der Datei auf der Festplatte übereinstimmen, damit die Datei nur aus dem Index entfernt werden kann.

Also für eine einzelne Datei:

git rm --cached mylogfile.log

und für ein einzelnes Verzeichnis:

git rm --cached -r mydirectory
bdonlan
quelle
151
Leicht zu übersehen, weil es nicht so selbsterklärend ist wie svn rm --keep-local.
Martin
114
Aber wie bewahre ich die Dateien auf Remote-Servern auf? Dadurch bleibt meine lokale Datei erhalten. Wenn ich jedoch von einem anderen Server aus pushe und ziehe, wird die Datei gelöscht. Ich habe auch einen .gitignore für die Datei hinzugefügt, aber er wird immer noch entfernt
spankmaster79
6
Dies entfernt immer noch die Dateien auf, git pullwenn Sie hinter dem Commit nachgit rm
Petr Peller
9
Beachten Sie, dass Sie nach dem Ausführen des Befehls in der Antwort git commit -m "Commit message"und verwenden müssen git push. Wenn Sie andere bereitgestellte Änderungen haben (überprüfen Sie mit git status), werden diese zu diesem Zeitpunkt ebenfalls festgeschrieben.
Sinjai
9
Da dies die am meisten akzeptierte Antwort ist und nicht tut, was gefragt wird, werde ich sagen, was ich tue. Ich benutze den Befehl git rm --cached mylogfile.logund lösche die Datei aus dem Repository. Um zu vermeiden, dass die Datei auf dem Produktivsystem verloren geht, mache ich eine Sicherungskopie der Datei und ziehe danach. Die Datei wird wie zuvor erwähnt gelöscht und muss aus Ihrem Backup zurückkopiert werden. Das ist ziemlich schmerzhaft, aber ich habe keine bessere Lösung für dieses Problem gefunden.
Marcel Grolms
275

Gehen Sie folgendermaßen vor, um einen gesamten Ordner aus dem Repo zu entfernen (z. B. Resharper-Dateien):

git rm -r --cached folderName

Ich hatte einige Resharper-Dateien festgeschrieben und wollte nicht, dass diese für andere Projektbenutzer bestehen bleiben.

Sam Tyson
quelle
13
Nur ein zusätzlicher Hinweis für zukünftige Besucher: Verwenden Sie keine GUI, um das Commit zurück zum Repo zu "synchronisieren". Dadurch werden die Dateien wieder in Ihr lokales Repo verschoben. Sie müssen a Git Push repo branchausführen, um die Dateien tatsächlich von der Fernbedienung zu entfernen.
RubberDuck
211

Sie können Dateien auch basierend auf Ihrem .gitignore aus dem Repository entfernen, ohne sie aus dem lokalen Dateisystem zu löschen:

git rm --cached `git ls-files -i -X .gitignore`

Oder alternativ unter Windows Powershell:

git rm --cached $(git ls-files -i -X .gitignore)
Null
quelle
7
Funktioniert nicht unter Windows. git ls-files -i -X ​​.gitignore funktioniert, aber ich weiß nicht, wie ich die Dateien an 'git rm' senden soll. Weißt du wie das geht?
Erik Z
17
Funktioniert unter Windows, wenn Sie Git Bash anstelle von cmd-console verwenden
Andreas Zita
17
Ich liebe das. Hat funktioniert, außer dass ich einige Dateien hatte, die Leerzeichen im Dateinamen hatten. Ich habe hier die Lösung dahingehend geändert : git ls-files -i -X .gitignore | xargs -I{} git rm --cached "{}". Bitte erwägen Sie, diese Lösung zu
ändern
Ich habe es nicht versucht, aber es sollte getestet werden, um auch Dateien zu entfernen, bei .gitkeepdenen ein leerer Ordner im Repository erhalten bleibt. Z.B. .gitignoreOrdner enthalten uploadsund Repo ist gezwungen, den Überblick zu behalten .gitkeep. Wenn Sie alles aus dem Repo uploadsentfernen, wird es auch entfernt .gitkeep.
Vladimir Vukanac
Dieser Vorschlag funktionierte perfekt in Powershell: git rm --cached $ (git ls-files -i -X ​​.gitignore)
geekandglitter
89

Gemäß meiner Antwort hier: /programming/6313126/how-to-remove-a-directory-in-my-github-repository

Um Ordner / Verzeichnis oder Datei nur aus dem Git-Repository und nicht aus dem lokalen zu entfernen, versuchen Sie 3 einfache Schritte.


Schritte zum Entfernen des Verzeichnisses

git rm -r --cached File-or-FolderName
git commit -m "Removed folder from repository"
git push origin master

Schritte zum Ignorieren dieses Ordners bei den nächsten Commits

Um diesen Ordner bei den nächsten Commits zu ignorieren, erstellen Sie eine Datei im Stammverzeichnis mit dem Namen .gitignore und fügen Sie diesen Ordnernamen ein . Sie können so viele setzen, wie Sie möchten

Die .gitignore- Datei sieht folgendermaßen aus

/FolderName

Verzeichnis entfernen

Eirenaios
quelle
@ Gaurav froh, dass es geholfen hat!
Eirenaios
69

Wenn Sie vertrauliche Daten festgeschrieben haben (z. B. eine Datei mit Kennwörtern), sollten Sie diese vollständig aus dem Verlauf des Repositorys löschen. Hier ist eine Anleitung, die erklärt, wie das geht: http://help.github.com/remove-sensitive-data/

BoD
quelle
13
Diese Antwort sollte die erforderlichen Befehle zum Ausführen dieser Aufgabe enthalten, anstatt auf eine andere Website zu verlinken.
Florian Lemaitre
1
Ich würde auch bemerken, dass ich die Verwendung des git bfg Repo Cleaner Tools einfacher und schneller fand.
Geschmierte Schnecke
64

Eine allgemeinere Lösung:

  1. .gitignoreDatei bearbeiten .

    ECHO mylogfile.log >> .gitignore

  2. Entfernen Sie alle Elemente aus dem Index.

    git rm -r -f --cached .

  3. Index neu erstellen.

    git add .

  4. Machen Sie ein neues Commit

    git commit -m "Removed mylogfile.log"

mAsT3RpEE
quelle
2
Wird dadurch die Datei tatsächlich gelöscht?
Mr_and_Mrs_D
6
Von GitHub? NEIN. Wenn Sie bereits auf github gedrückt haben, wird es nicht von der Site entfernt. Es wird jedoch Ihr lokales Git-Repository aktualisiert.
mAsT3RpEE
5
Der Kommentar, den Sie gelöscht haben, wurde tatsächlich mehr beseitigt :) Das Problem mit der Lösung rm --cashedist, dass die Datei schließlich gelöscht wird, wenn man sie zieht - richtig? Und dies ist nicht das, was die Leute wollen, wenn sie sagen "Entfernen Sie eine Datei aus dem Repository, ohne sie aus dem lokalen Dateisystem zu löschen ". Warum ist die oben akzeptierte Lösung mir ein Rätsel - wahrscheinlich hat das OP alleine gearbeitet und nie gezogen? Keine Ahnung. Ich verstehe die Github "einmal geschoben immer da" Ausgabe von c
Mr_and_Mrs_D
Ich glaube nicht, dass es eine 100% ige Lösung gibt, wenn Sie nicht Github selbst fragen. Bleib vorerst dabei. Datei kopieren, Zum Gitignore hinzufügen, das eigentliche Git rm -r ausführen, Datei festschreiben, pushen, wiederherstellen. Haben Sie es geschafft, eine andere Lösung zu finden?
mAsT3RpEE
9
Mein Problem ist nicht Github - es ist, dass die Datei tatsächlich von Kollegen gelöscht wird, wenn sie ziehen . Ich möchte nicht, dass die Datei gelöscht wird. Dies hat mir in der Vergangenheit große Probleme bereitet. Also habe ich mich gefragt, ob es wirklich eine Lösung gibt, die die Datei wirklich nicht löscht. Siehe auch den Kommentar in der akzeptierten Antwort: stackoverflow.com/questions/1143796/…
Mr_and_Mrs_D
24

Mit Git können Sie diese Dateien ignorieren, indem Sie davon ausgehen, dass sie unverändert sind. Dies erfolgt durch Ausführen des git update-index --assume-unchanged path/to/file.txtBefehls. Sobald eine Datei als solche markiert ist, ignoriert git alle Änderungen an dieser Datei vollständig. Sie werden weder angezeigt, wenn der Git-Status oder der Git-Diff ausgeführt wird, noch werden sie jemals festgeschrieben.

(Von https://help.github.com/articles/ignoring-files )

Daher nicht löschen, sondern Änderungen daran für immer ignorieren. Ich denke, dies funktioniert nur lokal, sodass Mitarbeiter weiterhin Änderungen daran sehen können, es sei denn, sie führen denselben Befehl wie oben aus. (Muss dies jedoch noch überprüfen.)

Hinweis: Dies beantwortet die Frage nicht direkt, sondern basiert auf Folgefragen in den Kommentaren der anderen Antworten.

Rystraum
quelle
2
Hm, ich mache das, aber ich sehe, dass die Datei überschrieben werden kann, wenn jemand anderes im Repo Änderungen daran vornimmt.
AlxVallejo
17

Wenn Sie nur eine Datei entfernen und nicht aus dem lokalen und Remote-Repo löschen möchten, verwenden Sie diesen Befehl:

git update-index --assume-unchanged  file_name_with_path
Afraz Ahmad
quelle
2
Dies ist zwar eine gute Antwort, es ist jedoch wichtig zu beachten, dass eine Datei dadurch nicht in dem Sinne "entverfolgt" wird, dass Benutzer dieses Wort normalerweise mit Git verwenden, wobei eine nicht verfolgte Datei nicht im Repository-Verlauf enthalten ist und dies noch nie war . Mit dieser Antwort wird die Datei im Repository gespeichert, Git wird jedoch daran gehindert, zu bemerken, dass Änderungen daran vorgenommen wurden. Das hat einige signifikante Unterschiede - am wichtigsten ist, dass die Datei für andere noch vorhanden ist. Wenn jemand anderes Änderungen daran vornimmt und Sie ziehen, kann Ihre lokale Kopie ohne Bestätigung überschrieben werden.
Soren Bjornstad
8

Die obigen Antworten haben bei mir nicht funktioniert. Ich habe filter-branchalle festgeschriebenen Dateien entfernt.

Entfernen Sie eine Datei aus einem Git-Repository mit:

git filter-branch --tree-filter 'rm  file'

Entfernen Sie einen Ordner aus einem Git-Repository mit:

git filter-branch --tree-filter 'rm -rf directory'

Dadurch wird das Verzeichnis oder die Datei aus allen Commits entfernt.

Sie können ein Commit angeben, indem Sie Folgendes verwenden:

git filter-branch --tree-filter 'rm -rf directory' HEAD

Oder eine Reichweite:

git filter-branch --tree-filter 'rm -rf vendor/gems' t49dse..HEAD

Um alles auf die Fernbedienung zu übertragen, haben Sie folgende Möglichkeiten:

git push origin master --force
Martijn Mellens
quelle
2
Dies zusammen mit git rm -r --cached NAMEist der Trick, um es aus Ihrem lokalen Git-Repo zu entfernen und zu verhindern, dass es jeden betrifft, der später zieht (indem Sie den Verlauf der Datei oder des Verzeichnisses aus Git löschen)
notbad.jpeg
1
Dies schreibt den Git-Verlauf neu und Sie müssten --force nachher drücken, dies ist ein bisschen außerhalb des Rahmens mit der Frage, die ich denke. Bei einem öffentlich bekannten Repo kann man die Verlaufslinie nicht einfach so ändern, da jeder, der das Repo bereits geklont hat, beim Ziehen Probleme bekommt.
Guillaume Perrot
0

Ignorieren Sie die Dateien, entfernen Sie die Dateien aus git, aktualisieren Sie git (zum Entfernen).

Hinweis: Dies betrifft nicht den Verlauf vertraulicher Informationen.

Dieser Prozess erfordert definitiv ein gewisses Verständnis dafür, was mit Git los ist. Nachdem ich das gewonnen habe, habe ich im Laufe der Zeit gelernt, Prozesse wie:

1) Ignorieren Sie die Dateien

  • Fügen Sie das Projekt hinzu oder aktualisieren Sie es .gitignore, um sie zu ignorieren. In vielen Fällen, z. B. bei Ihnen, ist das übergeordnete Verzeichnis, z. B. log/der zu verwendende reguläre Ausdruck.
  • Commit und Push dieser .gitignoreDateiänderung (nicht sicher, ob Push wohlgemerkt benötigt wird, kein Schaden, wenn getan).

2) Entfernen Sie die Dateien aus git (nur).

  • Entfernen Sie nun die Dateien aus git (nur) mit git remove --cached some_dir/
  • Überprüfen Sie, ob sie noch lokal bleiben (sollten sie!).

3) Fügen Sie diese Änderung hinzu und übernehmen Sie sie (im Wesentlichen handelt es sich um eine Änderung zum "Hinzufügen" von Löschvorgängen, trotz des ansonsten verwirrenden Befehls "Hinzufügen"!)

  • git add .
  • git commit -m"removal"
Michael Durrant
quelle