Das Problem
Git LFS entscheidet nach Pfadmuster, welche Dateien es speichert, zum Beispiel
git lfs track "*.psd". Große Dateien mit einer gängigen Endung (.json,
.bin, .bam), Dateien ohne Endung und Dateien an unerwarteten Orten landen
in der Git-Historie, bevor es jemand bemerkt. Danach entfernt sie nur noch ein
Umschreiben der Historie.
git-lfs/git-lfs#282, "support
tracking by file size", ist seit 2015 offen und hatte am 2026-10-21 176
Reaktionen und 135 Kommentare. Damit ist es das meistdiskutierte offene Issue
des Projekts. Typische Fälle im Thread sind .bam-Dateien aus der Genomik,
mitgelieferte Binärdateien ohne Endung und Spiele-Assets, die nach dem ersten
Commit über eine Grenze wachsen.
Die Maintainer halten Git selbst für den richtigen Ort für einen Größenfilter.
Ein Pull Request, der --min-size hinzufügt,
wartet seit Juni 2026 auf ein Review und würde den neuen Client auf jedem
Rechner voraussetzen. Der vorhandene Hook
lfs-auto-track läuft nur über
npm, husky und lint-staged, und ein Kommentar im Issue fragt nach einer Version
außerhalb des npm-Ökosystems.
Wie es funktioniert
lfs-size-track läuft als
Pre-Commit-Hook und prüft jede gestagte Datei. Eine Datei über der Schwelle,
die LFS noch nicht erfasst, wird mit git lfs track --filename über ihren
genauen Pfad getrackt und erneut als LFS-Pointer gestagt. Der Commit enthält
dann den Pointer und den Eintrag in .gitattributes. Kleinere Dateien bleiben
unberührt. Es nutzt den normalen git-lfs-Client, kein Rechner braucht eine
gepatchte Version.
Die Schwelle liegt standardmäßig bei 10 MB. Sie lässt sich mit
git config lfs-size-track.threshold oder --threshold in dezimalen oder
binären Einheiten setzen (500KB, 10MB, 1GiB), und --exclude
überspringt Pfade, die auf ein Glob-Muster passen. Installiert wird der Hook
entweder mit lfs-size-track install als .git/hooks/pre-commit oder über das
pre-commit-Framework.
Für Repositories, die schon große Dateien enthalten, listet scan die Dateien
in HEAD über der Schwelle, die in Git statt in LFS liegen. scan --history
tut dasselbe für jeden Commit. Beide geben den git lfs migrate-Befehl aus,
der sie verschieben würde.
Das ist die Ausgabe in einem Test-Repository mit einer gestagten .bam-Datei
von 30 MB und einer von 2 KB bei der Standardschwelle:
$ lfs-size-track hook
lfs-size-track: data/reads.bam (30.0 MB) is now tracked by Git LFS
$ cat .gitattributes
data/reads.bam filter=lfs diff=lfs merge=lfs -text
Im selben Repository wurde danach eine Datei von 15 MB ohne LFS committet und
im nächsten Commit gelöscht. scan meldet für HEAD nichts, scan --history
findet sie:
$ lfs-size-track scan
No files above 10.0 MB outside Git LFS in HEAD.
$ lfs-size-track scan --history
Files above 10.0 MB stored in Git instead of LFS (in the history):
15.0 MB old.iso
To rewrite history (changes commit IDs):
git lfs migrate import --everything --include="old.iso"
Tests
Die Tests legen in einem temporären Verzeichnis echte Git-Repositories mit
git lfs install --local an, schreiben Dateien aus Zufallsbytes und prüfen
mit git cat-file, ob der gespeicherte Blob ein LFS-Pointer ist. Eine Datei
namens data/sample [1].bam über der Schwelle muss zum Pointer werden, während
eine kleine Datei mit derselben Endung in Git bleibt, und die geänderte
.gitattributes muss gestagt sein. Weitere Tests decken Dateien ab, die schon
ein LFS-Muster erfasst, ausgeschlossene Pfade, eine Datei mit ungestagten
Änderungen (Exit-Code 1, nicht neu gestagt), die Schwelle aus git config,
scan auf HEAD und mit --history, den installierten Hook bei einem echten
git commit, die Weigerung, einen fremden Hook zu überschreiben, und den
Parser für Größenangaben. Das CI führt die Tests auf Python 3.10 bis 3.13 mit
dem git-lfs-Client des Runners aus, prüft mit ruff und scannt das eigene
Repository mit einer Schwelle von 1 MB.
Grenzen
- Dateien werden über ihren genauen Pfad getrackt. Wird eine solche Datei
später umbenannt, braucht es einen neuen Commit über den Hook oder
git lfs trackvon Hand. - Hat eine große Datei zusätzlich ungestagte Änderungen, stagt der Hook sie nicht neu, weil das die ungestagten Änderungen in den Commit aufnehmen würde. Er endet mit Exit-Code 1 und bittet darum, die Datei vollständig zu stagen.
- Eine Datei, die unter die Schwelle schrumpft, bleibt in LFS. Dateien wieder aus LFS herauszunehmen, bleibt dem Nutzer überlassen.
- Jeder Klon braucht
git lfs install, wie bei jedem LFS-Repository.
Code und Installationsanleitung liegen unter github.com/Jwrede/lfs-size-track.