485 Stimmen

Kann nicht auf GitHub pushen, weil eine große Datei vorhanden ist, die ich bereits gelöscht habe

Aktuell habe ich

  1. Leeres GitHub-Repository
  2. SSH-Server-Repository (Hauptrepository)
  3. Lokales Repo

Das SSH-Server-Repository war das aktuellste Repository (Produktionsseite), also habe ich von dort aus ein Git clone auf das lokale Repository durchgeführt. Anschließend habe ich versucht, ein git push zu GitHub zu machen.

Alles lief gut, aber dann kam eine Meldung, dass die Datei filename.gz für GitHub zu groß sei. Da ich diese Datei nicht brauchte, habe ich mehrere Git-Befehle ausgeführt, um sie aus dem Git-Cache zu entfernen, und dann zurück auf den SSH-Server gepusht.

Ich sehe die große Datei lokal nicht, aber sie ist immer noch auf dem SSH-Server, obwohl git diff nichts zurückgibt und git push "Alles ist auf dem neuesten Stand" zurückgibt - und obwohl die Datei im lokalen Repository nicht sichtbar ist. Beim Versuch, zu GitHub zu pushen, erhalte ich immer noch einen Fehler.

remote: Fehler: Die Datei fpss.tar.gz ist 135,17 MB groß; das übersteigt das Dateigrößenlimit von GitHub von 100 MB

Ich habe die Schritte unter "Problembehebung" auf der GitHub-Hilfeseite befolgt, sollte das nicht ausreichen?

Warum ist die Datei immer noch "in der Luft", wenn sie weder lokal ist noch in git status/diff/push aufgelistet ist?

617voto

MacGyver Punkte 6149

Sie können verwenden

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ' HEAD

Dadurch wird alles im Verlauf dieser Datei gelöscht. Das Problem ist, dass die Datei im Verlauf vorhanden ist.

Dieser Befehl ändert die Hashes Ihrer Commits, was ein echtes Problem sein kann, insbesondere bei gemeinsam genutzten Repositories. Er sollte nicht ohne das Verständnis der Konsequenzen durchgeführt werden.

Bearbeiten: Das Git-Projekt empfiehlt jetzt, dass Benutzer anstelle von git filter-branch git filter-repo verwenden.


Die Verwendung von git filter-repo

WARNUNG: git-filter-branch hat eine Vielzahl von Fallstricken, die zu verunstalteten Historien führen. Drücken Sie Strg+C, um abzubrechen, verwenden Sie dann ein alternatives Filterwerkzeug wie 'git filter-repo' (https://github.com/newren/git-filter-repo/) stattdessen. Siehe die Anleitung zu filter-branch für weitere Details; um diese Warnung zu unterdrücken, setzen Sie FILTER_BRANCH_SQUELCH_WARNING=1.

Installation

[brew|pip3|...] install git-filter-repo

Verwendung

Um eine Datei mit dem Pfadpräfix example/path/to/something zu entfernen, können Sie ausführen

git filter-repo --path example/path/to/something--invert-paths

Um eine Datei ohne das Pfadpräfix example/path/to/something zu entfernen, können Sie ausführen

git filter-repo --path example/path/to/something

268voto

Ich habe herausgefunden, dass Squashing nützlicher ist als filter-branch. Ich habe Folgendes gemacht:

  1. Lokale große Dateien löschen.
  2. Die lokalen Löschungen committen.
  3. Weiche Zurücksetzung um X Commits (bei mir waren es 3): git reset --soft HEAD~3.
  4. Dann alle Änderungen zusammen wieder committen (auch bekannt als Squash) git commit -m "Neue Nachricht für den kombinierten Commit"
  5. Squashed Commit pushen.

Spezialfall (von Benutzer @lituo): Wenn das obige nicht funktioniert, dann könnte dieser Fall zutreffen. Commit 1 enthielt die große Datei und der Push von Commit 1 ist aufgrund eines Fehlers mit der großen Datei fehlgeschlagen. Commit 2 entfernte die große Datei mit git rm --cached [Dateiname], aber der Push von Commit 2 ist immer noch fehlgeschlagen. Sie können dieselben Schritte wie oben befolgen, jedoch anstelle von HEAD~3 HEAD~2 verwenden.

214voto

Shreya Punkte 2301

Hier ist etwas, was ich super hilfreich fand, wenn du bereits mit deinem Repository herumgespielt hast, bevor du um Hilfe gebeten hast. Tippe zuerst:

git status

Danach solltest du etwas in der Art von sehen

Auf Branch master
Ihr Branch liegt um 2 Commits vor 'origin/master'.
  (verwende "git push", um deine lokalen Commits zu veröffentlichen)

Nichts zum Commiten, Arbeitsverzeichnis sauber

Der wichtige Teil sind die "2 Commits"! Von hier aus tippe:

git reset HEAD~

Also würde man für das obige Beispiel eingeben:

git reset HEAD~2

Nachdem du das eingegeben hast, sollte dein "git status" sagen:

Auf Branch master
Ihr Branch ist auf dem aktuellen Stand von 'origin/master'.

Nichts zum Commiten, Arbeitsverzeichnis sauber

Von dort aus kannst du die große Datei löschen (sofern du das noch nicht getan hast), und du solltest in der Lage sein, alles erneut zu committen, ohne deine Arbeit zu verlieren.

48voto

BlueMoon93 Punkte 2900

Wenn die Datei mit Ihrem letzten Commit hinzugefügt wurde und Sie nicht auf das entfernte Repository gepusht haben, können Sie die Datei löschen und den Commit ändern, entnommen von hier:

git rm --cached giant_file
    # Stage "giant_file" für die Entfernung mit "git rm"
    # Auf der Festplatte belassen mit "--cached", wenn Sie es von der Festplatte entfernen möchten
    # ignorieren Sie dann den Parameter "--cached"
git commit --amend -CHEAD
    # Commiten des aktuellen Baums ohne die Riesendatei mit "git commit"
    # Ändern des vorherigen Commits mit Ihrer Änderung "--amend"
    # (einfach ein neuer Commit funktioniert nicht, da Sie
    # die Datei auch aus der ungpushed History entfernen müssen)
    # Verwenden Sie das Log/Besitzer/Datum des letzten Commits (den wir
    # ändern) mit "-CHEAD", äquivalent zu --reuse-message=HEAD
git push
    # Unser umgeschriebener, kleinerer Commit wird mit "git push" gepusht

23voto

Roberto Tyley Punkte 22905

Warum lehnt GitHub meinen Repo ab, auch nachdem ich die große Datei gelöscht habe?

Git speichert die vollständige Historie Ihres Projekts, daher hat das Git-Repo auch dann eine Kopie der Datei in seiner Historie, wenn Sie eine Datei aus Ihrem Projekt 'löschen'. Wenn Sie versuchen, in ein anderes Repository zu pushen (wie eines, das bei GitHub gehostet wird), verlangt Git , dass das Remote-Repo die gleiche Historie hat wie Ihr lokales Repo (also die gleichen großen Dateien in seiner Historie).

Wie kann ich GitHub dazu bringen, meinen Repo zu akzeptieren?

Sie müssen die Git-Historie Ihres Projekts lokal bereinigen, das unerwünschte große Dateien aus der gesamten Historie entfernen und dann nur die 'bereinigte' Historie nutzen. Die Git Commit-IDs der betroffenen Commits werden sich ändern.

Wie entferne ich große Dateien aus meinem Git-Repo?

Das beste Tool zum Bereinigen unerwünschter großer Dateien aus der Git-Historie ist der BFG Repo-Cleaner - es handelt sich um eine einfachere, schnellere Alternative zu git-filter-branch, die speziell zum Entfernen unerwünschter Dateien aus der Git-Historie entwickelt wurde.

Befolgen Sie sorgfältig die Verwendungshinweise, der Kern besteht nur darin:

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

Alle Dateien über 100 MB Größe (die nicht in Ihrem neuesten Commit sind) werden aus der Git-Repository-Historie entfernt. Sie können dann git gc verwenden, um die nicht mehr benötigten Daten zu bereinigen:

$ git gc --prune=now --aggressive

Der BFG ist in der Regel mindestens 10-50x schneller als das Ausführen von git-filter-branch und im Allgemeinen viel einfacher zu bedienen.

Vollständige Offenlegung: Ich bin der Autor des BFG Repo-Cleaners.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X