Veröffentlicht am: 18. August 2025
10 Minuten Lesezeit
Erfahren Sie mehr über die neuesten Beiträge von GitLabs Git-Team und der Git-Community, einschließlich Performance-Optimierungen für git-push(1) und git-fetch(1), die besonders für deutsche Entwicklungsteams relevant sind.

Das Git-Projekt hat kürzlich Git 2.51 veröffentlicht. Aufgrund des Sommers auf der Nordhalbkugel und langsamerer Fortschritte war dieser Release-Zyklus mit 8 Wochen eher kurz (normalerweise dauert ein Release-Zyklus etwa 12 Wochen). Die wichtigste Neuerung: Git-Operationen werden bis zu 22-mal schneller - besonders bei großen Repositories mit vielen Branches profitieren Entwicklungsteams von erheblichen Performance-Verbesserungen. Schauen wir uns diese und andere bemerkenswerte Änderungen in diesem Release an, einschließlich Beiträgen vom Git-Team bei GitLab und der breiteren Git-Community.
Große Repositories mit tausenden von Branches standen vor einem schmerzhaften Engpass. Git-Operationen, die Referenzen aktualisieren, konnten mehrere Sekunden dauern - ein echter Produktivitätskiller für Teams mit umfangreichen CI/CD-Pipelines oder Monorepo-Workflows. Git 2.51.0 ändert alles. Eine 10.000-Referenzen-Fetch-Operation, die 3,4 Sekunden dauerte, wird jetzt in 154 Millisekunden abgeschlossen:
VORHER: git-fetch mit 10.000 Referenzen Time: 3.403 s ± 0.775 s
NACHHER: git-fetch mit 10.000 Referenzen Time: 154.3 ms ± 17.6 ms
ERGEBNIS: 22× schneller
Ähnlich dramatische Verbesserungen bei git-push:
VORHER: git-push mit 10.000 Referenzen Time: 4.276 s ± 0.078 s
NACHHER: git-push mit 10.000 Referenzen Time: 235.4 ms ± 6.9 ms
ERGEBNIS: 18× schneller
Das Problem lag in der Art, wie Git Referenz-Transaktionen behandelte. Die Kommandos git-push(1) und git-fetch(1) erstellten eine separate Transaktion für jedes Referenz-Update, was enormen Overhead verursachte - jede Transaktion benötigte eine Initialisierungs- und Abbauphase und löste Auto-Komprimierungen aus. Git 2.51.0 verwendet nun gebündelte Updates: Mehrere Referenzen werden in einer einzigen Transaktion aktualisiert, während einzelne Updates weiterhin fehlschlagen dürfen. Dies eliminiert den Overhead und skaliert linear mit der Anzahl der Referenzen. Das Beste daran? Benutzer profitieren automatisch von diesen Verbesserungen, ohne Änderungen an ihrem Workflow vornehmen zu müssen. Dieses Projekt wurde von Karthik Nayak geleitet.
Vor 11 Jahren wurde Git 2.0 veröffentlicht, die letzte große Versionsfreigabe von Git. Obwohl wir keinen spezifischen Zeitplan für die nächste große Git-Veröffentlichung haben, enthält dieses Release Entscheidungen, die in Richtung Git 3.0 getroffen wurden. Die Git 3.0-Release-Planung ermöglicht es uns, Breaking Changes zu planen und zu implementieren und diese der erweiterten Git-Community zu kommunizieren. Neben der Dokumentation kann Git auch mit diesen Breaking Changes kompiliert werden für diejenigen, die mit diesen Änderungen experimentieren möchten. Weitere Informationen finden Sie im BreakingChanges-Dokument. Das Git 2.51.0-Release bringt einige bedeutende Änderungen in Richtung Git 3.0.
Im Git 2.45.0-Release wurde das "reftable"-Format als neues Backend zur Speicherung von Referenzen wie Branches oder Tags in Git eingeführt, das viele der Probleme des bestehenden "files"-Backends behebt. Lesen Sie unseren Einsteiger-Leitfaden zur Funktionsweise von reftables für weitere Einblicke in das "reftable"-Backend. Das Git 2.51.0-Release markiert den Wechsel zur Verwendung des "reftable"-Formats als Standard in Git 3.0 für neu erstellte Repositories und verdrahtet die Änderung hinter einem Feature-Flag. Das "reftable"-Format bietet folgende Verbesserungen gegenüber dem traditionellen "files"-Backend:
Das Git-Versionskontrollsystem speichert Objekte in einem inhaltsadressierbaren Dateisystem. Das bedeutet, es verwendet den Hash eines Objekts zur Adressierung von Inhalten wie Dateien, Verzeichnissen und Revisionen, anders als traditionelle Dateisysteme, die sequenzielle Nummern verwenden. Die Verwendung einer Hash-Funktion hat folgende Vorteile:
Der git-whatchanged(1)-Befehl zeigt Logs mit Unterschieden, die jeder Commit einführt. Obwohl dies nun von git log --raw abgelöst wurde, wurde der Befehl aus historischen Gründen beibehalten. Git 2.51.0 erfordert, dass Benutzer des Befehls explizit das --i-still-use-this-Flag verwenden, um alle Benutzer zu erfassen, die noch den veralteten Befehl verwenden, und markiert den Befehl auch für die Entfernung in Git 3.0. Dieses Projekt wurde von Junio C Hamano geleitet.
Der git-checkout(1)-Befehl kann für mehrere verschiedene Anwendungsfälle verwendet werden. Er kann zum Wechseln von Referenzen verwendet werden:
$ git status Auf Zweig master Ihr Branch ist auf dem neuesten Stand mit 'origin/master'. Nichts zu committen, Arbeitsverzeichnis unverändert
$ git checkout next Zu Branch 'next' gewechselt Ihr Branch ist auf dem neuesten Stand mit 'origin/next'.
Oder zur Wiederherstellung von Dateien:
$ echo "additional line" >> git.c
$ git status Auf Zweig master Ihr Branch ist auf dem neuesten Stand mit 'origin/master'.
Änderungen, die nicht zum Commit vorgemerkt sind:
(benutzen Sie "git add <Datei>...", um die Änderungen zum Commit vorzumerken)
(benutzen Sie "git restore <Datei>...", um die Änderungen im Arbeitsverzeichnis zu verwerfen)
geändert: git.c
keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add" und/oder "git commit -a")
$ git checkout git.c 1 Pfad von Index aktualisiert
$ git status Auf Zweig master Ihr Branch ist auf dem neuesten Stand mit 'origin/master'. Nichts zu committen, Arbeitsverzeichnis unverändert
Für neue Git-Benutzer kann dies zu viel Verwirrung führen. In Git 2.33.0 wurden diese in zwei neue Befehle aufgeteilt: git-switch(1) und git-restore(1). Der git-switch(1)-Befehl ermöglicht es Benutzern, zu einem bestimmten Branch zu wechseln:
$ git status Auf Zweig master Ihr Branch ist auf dem neuesten Stand mit 'origin/master'. Nichts zu committen, Arbeitsverzeichnis unverändert
$ git switch next Zu Branch 'next' gewechselt Ihr Branch ist auf dem neuesten Stand mit 'origin/next'.
Und der git-restore(1)-Befehl ermöglicht es Benutzern, Working-Tree-Dateien wiederherzustellen:
$ echo "additional line" >> git.c
$ git status Auf Zweig master Ihr Branch ist auf dem neuesten Stand mit 'origin/master'.
Änderungen, die nicht zum Commit vorgemerkt sind:
(benutzen Sie "git add <Datei>...", um die Änderungen zum Commit vorzumerken)
(benutzen Sie "git restore <Datei>...", um die Änderungen im Arbeitsverzeichnis zu verwerfen)
geändert: git.c
keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add" und/oder "git commit -a")
$ git restore git.c
$ git status Auf Zweig master Ihr Branch ist auf dem neuesten Stand mit 'origin/master'. Nichts zu committen, Arbeitsverzeichnis unverändert
Obwohl die beiden Befehle seit 2019 existieren, wurden sie als experimentell markiert. Der Effekt ist, dass das Git-Projekt keine Rückwärtskompatibilität für diese Befehle garantiert: das Verhalten kann sich jederzeit ändern. Obwohl die Absicht ursprünglich war, diese Befehle nach einigen Releases zu stabilisieren, ist das bis zu diesem Punkt nicht geschehen. Dies hat zu mehreren Diskussionen auf der Git-Mailing-Liste geführt, wo Benutzer unsicher sind, ob sie diese neuen Befehle verwenden können oder ob sie eventuell wieder verschwinden. Da jedoch keine bedeutenden Änderungen vorgeschlagen wurden und einige Benutzer diese Befehle bereits verwenden, haben wir beschlossen, sie in Git 2.51 nicht mehr als experimentell zu deklarieren. Dieses Projekt wurde von Justin Tobler geleitet.
Der git for-each-ref-Befehl wird verwendet, um alle im Repository vorhandenen Referenzen aufzulisten. Als Teil der Plumbing-Schicht von Git wird dieser Befehl häufig beispielsweise von Hosting-Forges verwendet, um Referenzen, die im Repository existieren, in ihrer UI aufzulisten. Aber während Repositories wachsen, wird es weniger realistisch, alle Referenzen auf einmal aufzulisten – schließlich können die größten Repositories Millionen davon enthalten! Stattdessen neigen Forges dazu, die Referenzen zu paginieren. Dies zeigt eine wichtige Lücke auf: git-for-each-ref weiß nicht, Referenzen von vorherigen Seiten zu überspringen, die bereits gezeigt wurden. Folglich muss es möglicherweise eine große Anzahl uninteressanter Referenzen auflisten, bevor es endlich beginnt, die für die aktuelle Seite benötigten Referenzen zu liefern. Dies ist ineffizient und führt zu höherer als notwendiger Latenz oder sogar Timeouts. Git 2.51.0 unterstützt ein neues --start-after-Flag für git for-each-ref, das die Paginierung der Ausgabe ermöglicht. Dies kann auch mit dem --count-Flag kombiniert werden, um über einen Batch von Referenzen zu iterieren.
$ git for-each-ref --count=10 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-001 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-002 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-003 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-004 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-005 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-006 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-007 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-008 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-009 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-010
$ git for-each-ref --count=10 --start-after=refs/heads/branch-010 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-011 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-012 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-013 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-014 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-015 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-016 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-017 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-018 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-019 9751243fba48b34d29aabfc9784803617a806e81 commit refs/heads/branch-020
Dieses Projekt wurde von Karthik Nayak geleitet.
Für vollständige technische Details, Benchmarks und Implementierungshinweise lesen Sie den englischen Originalartikel.