Fehlerbehebung bei Leistungsproblemen durch große Dateien in Git
Diagnostizieren Sie langsame Git-Repositorys, die durch große Dateien verursacht werden, wählen Sie Git LFS mit Bedacht aus und bereinigen Sie die Historie, ohne Ihr Team zu überraschen.
Fehlerbehebung bei Leistungsproblemen durch große Dateien in Git
Große Dateien beeinträchtigen Git auf eine Weise, die leicht übersehen wird, bis das Repository bereits schmerzhaft zu nutzen ist. Eine einzelne Video-, Archiv-, Datenbank-Dump- oder Design-Datei mag nicht gefährlich aussehen, wenn jemand sie hinzufügt. Das Problem beginnt, wenn diese Datei mehrmals geändert wird. Git behält die Historie, und jeder Klon muss diese Historie mit sich herumtragen.
Das Symptom ist anfangs meist vage. git clone dauert länger als es sollte. git fetch fühlt sich langsam an, wenn man im Hotel-WLAN ist. CI-Jobs verbringen zu viel Zeit damit, das Repository auszuchecken, bevor sie überhaupt bauen. Entwickler beginnen, alte lokale Klone zu verwenden, weil ein frischer Klon nervt. Das ist der Moment, das Repository zu inspizieren, anstatt allen zu sagen, sie sollen geduldig sein.
Bestätigen Sie, dass große Dateien das Problem sind
Beginnen Sie mit einfachen Überprüfungen:
du -sh .git
git count-objects -vH
du -sh .git zeigt Ihnen, wie schwer die lokale Repository-Datenbank ist. git count-objects -vH zeigt lose Objekte und Packgröße. Wenn die Packgröße im Vergleich zum tatsächlichen Quellbaum groß ist, trägt die Historie wahrscheinlich alte Nutzlasten mit sich.
Um große Dateien im aktuellen Checkout zu finden:
find . -path ./.git -prune -o -type f -size +10M -print
Das zeigt nur, was jetzt existiert. Ein Repository kann langsam sein wegen einer Datei, die vor Monaten gelöscht wurde. Um die Historie zu inspizieren, bietet Git LFS einen nützlichen Bericht, noch bevor Sie etwas migrieren:
git lfs migrate info --everything --above=10MB
Wenn Git LFS nicht installiert ist, können Sie dennoch mit Git-Plumbing untersuchen, aber der obige Befehl ist oft die direkteste Sicht auf dieses spezifische Problem.
Entscheiden Sie, was in Git gehört
Nicht jede große Datei ist ein Fehler. Eine kleine Menge stabiler Binär-Assets kann in Ordnung sein. Ein Repository für Infrastruktur-Code sollte keine VM-Images, Datenbank-Backups, Kundenexporte oder Build-Artefakte enthalten. Ein Spiel-Repository kann legitimerweise Kunst- und Audio-Assets enthalten, aber diese Dateien benötigen normalerweise Git LFS oder ein separates Asset-System.
Eine praktische Regel ist: Git ist hervorragend für Quelltext und kleine unterstützende Dateien. Git ist schlecht für häufig wechselnde Binär-Blobs. Wenn die Datei in einem Diff nicht sinnvoll überprüft werden kann und sie sich häufig ändert, sollte sie wahrscheinlich nicht als normales Git-Objekt leben.
Häufige Kandidaten für Git LFS sind:
*.psd
*.ai
*.mp4
*.mov
*.wav
*.zip
*.uasset
*.fbx
*.blend
Seien Sie vorsichtig mit breiten Bildmustern. Jedes *.png in LFS zu verfolgen, kann für ein designlastiges Repository hilfreich sein, aber es kann für eine Web-App mit vielen winzigen Symbolen nervig sein. Muster sollten den Dateien entsprechen, die tatsächlich Schmerzen verursachen.
Verwenden Sie Git LFS für zukünftige große Dateien
Git LFS speichert eine kleine Pointer-Datei in Git und behält den großen Inhalt im LFS-Speicher. Die normale Git-Historie bleibt leichter, während Benutzer die echte Datei im Arbeitsverzeichnis erhalten, wenn LFS sie herunterlädt.
Installieren und initialisieren Sie es:
git lfs install
Verfolgen Sie die Dateimuster, die Sie tatsächlich benötigen:
git lfs track "*.psd"
git lfs track "*.mp4"
git add .gitattributes
git commit -m "Große Design- und Videodateien mit Git LFS verfolgen"
Die .gitattributes-Datei ist wichtig. Committen Sie sie, damit alle die gleichen LFS-Regeln verwenden.
Danach fügen Sie Dateien normal hinzu:
git add demo.mp4
git commit -m "Produkt-Demo-Video hinzufügen"
git push origin main
Ein Mitarbeiter sollte Git LFS installieren, bevor er mit dem Repository arbeitet. Wenn sie ohne LFS-Unterstützung klonen, sehen sie möglicherweise Pointer-Dateien anstelle der echten Assets, bis sie LFS installieren und ausführen:
git lfs pull
Überprüfen Sie auch die Speicher- und Bandbreitenrichtlinie Ihres Git-Hosts. Git LFS löst das Problem der Git-Objektaufblähung, macht große Assets aber nicht kostenlos zu speichern oder zu übertragen.
Migration der vorhandenen Historie
Das Aktivieren von LFS heute behebt nicht automatisch die Commits von gestern. Wenn ein 700 MB großes Archiv committet und später gelöscht wurde, kann es immer noch in der Historie leben. Das Bereinigen erfordert eine Umschreibung der Historie.
Das Umschreiben der Historie ändert Commit-IDs. Jeder mit einem vorhandenen Klon muss sorgfältig neu synchronisieren, und offene Pull-Requests müssen möglicherweise rebased oder neu erstellt werden. Tun Sie dies in einem Wartungsfenster und erstellen Sie zuerst ein Mirror-Backup:
git clone --mirror [email protected]:ORG/REPO.git repo-backup.git
Arbeiten Sie dann in einem frischen Klon. Stellen Sie sicher, dass der Arbeitsbaum sauber ist:
git status
Überprüfen Sie, was migriert würde:
git lfs migrate info --everything --above=10MB
Migrieren Sie nach Möglichkeit nach Muster:
git lfs migrate import --everything --include="*.psd,*.mp4,*.zip"
Oder migrieren Sie Dateien über einem Schwellenwert, wenn das Repository viele unbekannte große Dateien hat:
git lfs migrate import --everything --above=10MB
Überprüfen Sie das Ergebnis vor dem Pushen:
git log --oneline --decorate -5
git lfs ls-files
git status
git lfs migrate info --everything --above=10MB
Wenn die Migration das getan hat, was Sie erwartet haben, pushen Sie die umgeschriebenen Branches und Tags gezielt:
git push --force-with-lease origin main
git push --force-with-lease origin --tags
Für ein Repository mit vielen aktiven Branches entscheiden Sie, welche Branches wichtig sind. Sie müssen nicht jeden aufgegebenen Branch umschreiben, aber jeder Branch, der noch die großen Objekte enthält, kann das Remote-Repository schwer halten.
Nach einer Historie-Umschreibung
Teilen Sie Teammitgliedern genau mit, was sich geändert hat. Die sauberste Anweisung ist oft, neu zu klonen. Wenn Leute lokale Arbeit haben, sollten sie sie zuerst speichern:
git status
git branch my-work-before-lfs-migration
git fetch origin
git rebase origin/main
Bei unordentlichen lokalen Klonen ist ein Neuklonen weniger riskant als der Versuch, alte Historie chirurgisch zu reparieren.
Der Remote-Speicher schrumpft möglicherweise nicht sofort. Hosting-Anbieter behalten unerreichbare Objekte eine Weile, und einige erfordern Support oder Repository-Wartung, bevor die Speicherzahlen aktualisiert werden. Lokal können Sie alte Objekte bereinigen, nachdem Sie sicher sind, dass die Migration gut ist:
git reflog expire --expire=now --all
git gc --prune=now --aggressive
Führen Sie Bereinigungsbefehle nicht als Ersatz für eine Überprüfung aus. Sie machen es schwieriger, alte lokale Objekte wiederherzustellen.
Verhindern des gleichen Problems erneut
Fügen Sie einen Pre-Commit- oder Pre-Receive-Check hinzu, wenn weiterhin versehentlich große Dateien auftauchen. Ein lokaler Pre-Commit-Hook kann Entwickler warnen, bevor sie ein großes Artefakt committen. Eine serverseitige Regel ist stärker, da sie das gemeinsame Repository schützt, auch wenn jemand lokale Hooks überspringt.
Eine einfache lokale Überprüfung könnte Dateien über einer gewählten Größe ablehnen, es sei denn, sie werden bereits von LFS verfolgt. Der genaue Schwellenwert hängt vom Projekt ab. Eine Dokumentationsseite und ein Spielprojekt sollten nicht denselben Grenzwert verwenden.
Beheben Sie auch die Quelle der Dateien. Wenn CI dist/, target/, Coverage-Berichte, Archive oder Screenshots innerhalb des Repositorys erstellt, fügen Sie die richtigen Einträge zu .gitignore hinzu:
dist/
target/
coverage/
*.log
*.zip
Ignorieren Sie Dateien nicht blind. Stellen Sie sicher, dass die ignorierten Pfade generierte Ausgaben sind, keine Quell-Eingaben.
Wenn LFS nicht die Antwort ist
Git LFS ist kein universeller Artefakt-Speicher. Build-Ausgaben gehören normalerweise in ein Paket-Repository, Objektspeicher, Release-Asset oder CI-Artefakt-Speicher. Datenbank-Dumps gehören in den Backup-Speicher. Große Datensätze benötigen möglicherweise ein Datenversionierungswerkzeug oder einen separaten Speicher-Workflow.
Das Ziel ist nicht, jede große Datei vor Git zu verstecken. Das Ziel ist, das Repository schnell genug zu halten, damit Leute klonen, branchen, fetchen und überprüfen können, ohne gegen das Tool zu kämpfen.
Eine gute Bereinigung hinterlässt drei Dinge: klare .gitattributes-Regeln für Dateien, die in LFS gehören, .gitignore-Regeln für Dateien, die nie committet werden sollten, und eine kurze Team-Notiz, die erklärt, wie vorhandene Klone neu synchronisieren sollen. Das ist es, was die Reparatur davor bewahrt, eine einmalige Bereinigung zu sein, die Sie im nächsten Quartal wiederholen.