Veröffentlicht am: 17. November 2025
12 Minuten Lesezeit
Alles zum aktuellen Release, darunter der neue git-last-modified(1)-Befehl, Verbesserungen an History-Rewriting-Tools und eine neue Maintenance-Strategie.

Das Git-Projekt hat kürzlich Git 2.52 veröffentlicht. Nach einem relativ kurzen 8-Wochen-Release-Zyklus für 2.51, aufgrund des Sommers auf der Nordhalbkugel, ist dieses Release wieder beim üblichen 12-Wochen-Zyklus.
Schauen wir uns einige Highlights an, darunter Beiträge vom GitLab Git-Team und der weiteren Git-Community.
Viele Git-Forges wie GitLab zeigen Dateien in einer Tree-Ansicht wie dieser an:
| Name | Last commit | Last update |
|---|---|---|
| README.md | README: *.txt -> *.adoc fixes | 4 months ago |
| RelNotes | Start 2.51 cycle, the first batch | 4 weeks ago |
| SECURITY.md | SECURITY: describe how to report vulnerabilities | 4 years |
| abspath.c | abspath: move related functions to abspath | 2 years |
| abspath.h | abspath: move related functions to abspath | 2 years |
| aclocal.m4 | configure: use AC_LANG_PROGRAM consistently | 15 years ago |
| add-patch.c | pager: stop using the_repository | 7 months ago |
| advice.c | advice: allow disabling default branch name advice | 4 months ago |
| advice.h | advice: allow disabling default branch name advice | 4 months ago |
| alias.h | rebase -m: fix serialization of strategy options | 2 years |
| alloc.h | git-compat-util: move alloc macros to git-compat-util.h | 2 years ago |
| apply.c | apply: only write intents to add for new files | 8 days ago |
| archive.c | Merge branch 'ps/parse-options-integers' | 3 months ago |
| archive.h | archive.h: remove unnecessary include | 1 year |
| attr.h | fuzz: port fuzz-parse-attr-line from OSS-Fuzz | 9 months ago |
| banned.h | banned.h: mark strtok() and strtok_r() as banned | 2 years |
Neben den Dateien selbst zeigen wir auch an, welcher Commit jede jeweilige Datei zuletzt geändert hat. Diese Information lässt sich einfach aus Git extrahieren, indem du folgenden Befehl ausführst:
$ git log --max-count=1 HEAD -- <filename>
Obwohl schön und einfach, hat das einen erheblichen Haken: Git hat keine Möglichkeit, diese Information für jede dieser Dateien in einem einzigen Befehl zu extrahieren. Um also den letzten Commit für alle Dateien im Tree zu erhalten, müssten wir diesen Befehl für jede Datei separat ausführen. Das führt zu einer Befehlspipeline ähnlich der folgenden:
$ git ls-tree HEAD --name-only | xargs --max-args=1 git log --max-count=1 HEAD --
Natürlich ist das nicht sehr effizient:
Als Konsequenz ist diese gesamte Operation ziemlich kostspielig und erzeugt erhebliche Last für GitLab.
Um diese Probleme zu beheben, wurde ein neuer Git-Subcommand git-last-modified(1) eingeführt. Dieser Befehl gibt den Commit für jede Datei eines gegebenen Commits zurück:
$ git last-modified HEAD
e56f6dcd7b4c90192018e848d0810f091d092913 add-patch.c
373ad8917beb99dc643b6e7f5c117a294384a57e advice.h
e9330ae4b820147c98e723399e9438c8bee60a80 advice.c
5e2feb5ca692c5c4d39b11e1ffa056911dd7dfd3 alloc.h
954d33a9757fcfab723a824116902f1eb16e05f7 RelNotes
4ce0caa7cc27d50ee1bedf1dff03f13be4c54c1f apply.c
5d215a7b3eb0a9a69c0cb9aa43dcae956a0aa03e archive.c
c50fbb2dd225e7e82abba4380423ae105089f4d7 README.md
72686d4e5e9a7236b9716368d86fae5bf1ae6156 attr.h
c2c4138c07ca4d5ffc41ace0bfda0f189d3e262e archive.h
5d1344b4973c8ea4904005f3bb51a47334ebb370 abspath.c
5d1344b4973c8ea4904005f3bb51a47334ebb370 abspath.h
60ff56f50372c1498718938ef504e744fe011ffb banned.h
4960e5c7bdd399e791353bc6c551f09298746f61 alias.h
2e99b1e383d2da56c81d7ab7dd849e9dab5b7bf0 SECURITY.md
1e58dba142c673c59fbb9d10aeecf62217d4fc9c aclocal.m4
Der Vorteil davon ist offensichtlich, dass wir jetzt nur noch einen einzigen Git-Prozess ausführen müssen, um all diese Informationen abzuleiten. Aber noch wichtiger ist, dass wir die History nur einmal für alle Dateien zusammen durchlaufen müssen, anstatt sie mehrmals durchlaufen zu müssen. Dies wird wie folgt erreicht:
Gitaly wurde bereits angepasst, um den neuen Befehl zu verwenden, aber die Logik ist noch hinter einem Feature-Flag geschützt. Vorläufige Tests haben gezeigt, dass git-last-modified(1) in den meisten Situationen mindestens doppelt so schnell ist wie die Verwendung von git log --max-count=1.
Diese Änderungen wurden ursprünglich geschrieben von mehreren Entwicklern von GitHub und wurden upstream in Git von Toon Claes integriert.
Die Befehle git-fast-export(1) und git-fast-import(1) sind dafür konzipiert, hauptsächlich von Interoperabilitäts- oder History-Rewriting-Tools verwendet zu werden. Das Ziel von Interoperabilitäts-Tools ist es, Git problemlos mit anderer Software interagieren zu lassen, normalerweise einem anderen Versionskontrollsystem, das Daten in einem anderen Format als Git speichert. Zum Beispiel ist hg-fast-export.sh ein „Mercurial-zu-Git-Konverter, der git-fast-import verwendet."
Alternativ lassen History-Rewriting-Tools Benutzer – normalerweise Admins – Änderungen an der History ihrer Repositories vornehmen, die Versionskontrollsysteme nicht zulassen. Zum Beispiel sagt reposurgeon in seiner Einführung, dass sein Zweck ist, „riskante Operationen zu ermöglichen, die Versionskontrollsysteme dich nicht durchführen lassen wollen, wie zum Beispiel (a) Bearbeitung vergangener Kommentare und Metadaten, (b) Entfernung von Commits, (c) Zusammenführung und Aufteilung von Commits, (d) Entfernung von Dateien und Subtrees aus der Repo-History, (e) Zusammenführung oder Verknüpfung von zwei oder mehr Repos und (f) Aufteilung eines Repos in zwei durch Durchtrennung einer Parent-Child-Verbindung, wobei die Branch-Struktur beider Child-Repos erhalten bleibt."
Innerhalb von GitLab verwenden wir git-filter-repo, um Admins einige riskante Operationen an ihren Git-Repositories durchführen zu lassen. Leider haben bis Git 2.50 (veröffentlicht im letzten Juni) sowohl git-fast-export(1) als auch git-fast-import(1) kryptografische Commit-Signaturen überhaupt nicht behandelt. Obwohl git-fast-export(1) also eine Option --signed-tags=<mode> hatte, die es Benutzern ermöglicht zu ändern, wie kryptografische Tag-Signaturen behandelt werden, wurden Commit-Signaturen einfach ignoriert.
Kryptografische Signaturen sind sehr fragil, weil sie auf den exakten Commit- oder Tag-Daten basieren, die signiert wurden. Wenn sich die signierten Daten oder irgendetwas von ihrer vorhergehenden History ändert, wird die kryptografische Signatur ungültig. Dies ist eine fragile, aber notwendige Anforderung, um diese Signaturen nützlich zu machen.
Aber im Kontext des Neuschreibens der History ist das ein Problem:
Weder git-fast-import(1) noch git-fast-export(1) erlauben diese Anwendungsfälle jedoch, was einschränkt, was Tools wie git-filter-repo oder reposurgeon erreichen können.
Wir haben einige erhebliche Fortschritte gemacht:
--signed-commits=<mode> zu git-fast-export(1) hinzugefügt, um Commit-Signaturen zu exportieren, und Unterstützung in git-fast-import(1), um sie zu importieren.git-fast-import(1) möglich gemacht, sowohl eine Signatur zu importieren, die auf der SHA-1-Objekt-ID des Commits gemacht wurde, als auch eine, die auf seiner SHA-256-Objekt-ID gemacht wurde.--signed-commits=<mode> und --signed-tags=<mode> zu git-fast-import(1) hinzugefügt, sodass der Benutzer Kontrolle darüber hat, wie signierte Daten zum Zeitpunkt des Imports behandelt werden.Es gibt noch mehr zu tun. Wir müssen die Fähigkeit hinzufügen:
git-fast-import(1).Wir arbeiten bereits an diesen nächsten Schritten, und erwarten, dass dies in Git 2.53 landet. Sobald das erledigt ist, werden Tools wie git-filter-repo(1) endlich beginnen, kryptografische Signaturen eleganter zu handhaben. Wir werden dich in unserem nächsten Git-Release-Blogpost auf dem Laufenden halten.
Dieses Projekt wurde von Christian Couder geleitet.
Git-Repositories benötigen regelmäßige Wartung, um sicherzustellen, dass sie gut funktionieren. Diese Wartung führt eine Reihe verschiedener Aufgaben aus: Referenzen werden optimiert, Objekte werden komprimiert und veraltete Daten werden bereinigt.
Bis Git 2.28 wurden diese Wartungsaufgaben von git-gc(1) durchgeführt. Das Problem mit diesem Befehl war, dass er nicht mit Blick auf Anpassbarkeit entwickelt wurde: Während bestimmte Parameter konfiguriert werden können, ist es nicht möglich zu kontrollieren, welche Teile eines Repositorys optimiert werden sollen. Das bedeutet, dass es möglicherweise nicht für alle Anwendungsfälle gut geeignet ist. Noch wichtiger ist, dass es sehr schwer wurde, darüber zu iterieren, wie genau Git Repository-Wartung durchführt.
Um dieses Problem zu beheben und uns wieder iterieren zu lassen, hat Derrick Stolee git-maintenance(1) eingeführt. Im Gegensatz zu git-gc(1) ist es mit Blick auf Anpassbarkeit entwickelt und ermöglicht es dem Benutzer zu konfigurieren, welche Aufgaben speziell in einem bestimmten Repository ausgeführt werden sollen. Dieses neue Tool wurde in Git 2.29 zum Standard für Gits automatisierte Wartung gemacht, aber standardmäßig verwendet es immer noch git-gc(1), um die Wartung durchzuführen.
Während diese Standard-Wartungsstrategie in kleinen oder sogar mittelgroßen Repositories gut funktioniert, ist sie im Kontext großer Monorepos problematisch. Der größte limitierende Faktor ist, wie git-gc(1) Objekte neu packt: Immer wenn es mehr als 50 Packfiles gibt, wird das Tool alle zusammen in ein einziges Packfile zusammenführen. Diese Operation ist ziemlich CPU-intensiv und verursacht viele I/O-Operationen, sodass diese Operation für große Monorepos leicht viele Minuten oder sogar Stunden dauern kann.
Git weiß bereits, wie diese Repacks durch „geometrisches Repacking" minimiert werden können. Die Idee ist einfach: Die Packfiles, die im Repository existieren, müssen einer geometrischen Progression folgen, bei der jedes Packfile mindestens doppelt so viele Objekte enthalten muss wie das nächstkleinere. Dies ermöglicht es Git, die Anzahl der erforderlichen Repacks zu amortisieren und gleichzeitig sicherzustellen, dass es insgesamt nur eine relativ kleine Anzahl von Packfiles gibt. Dieser Modus wurde von Taylor Blau in Git 2.32 eingeführt, aber er wurde nicht als Teil der automatisierten Wartung eingebunden.
Alle Teile existieren, um die Repository-Wartung für große Monorepos viel skalierbarer zu machen: Wir haben das flexible git-maintenance(1)-Tool, das erweitert werden kann, um eine neue Wartungsstrategie zu haben, und wir haben einen besseren Weg, Objekte neu zu packen. Alles, was getan werden muss, ist, diese beiden zu kombinieren.
Und genau das haben wir mit Git 2.52 getan! Wir haben eine neue „geometrische" Wartungsstrategie eingeführt, die du in deinen Git-Repositories konfigurieren kannst. Diese Strategie ist als vollständiger Ersatz für die alte Strategie basierend auf git-gc(1) gedacht. Hier ist der Config-Code, den du benötigst:
$ git config set maintenance.strategy geometric
Ab jetzt verwendet Git geometrisches Repacking verwenden, um deine Objekte zu optimieren. Das sollte zu weniger Churn führen und gleichzeitig sicherstellen, dass deine Objekte in einem besser optimierten Zustand sind, besonders in großen Monorepos.
In Git 2.53 wollen wir dies zur Standard-Strategie machen. Also bleib dran!
Dieses Projekt wurde von Patrick Steinhardt geleitet.
Die Performance von Git-Operationen in einem Repository hängt oft von bestimmten Eigenschaften seiner zugrunde liegenden Struktur ab. Bei GitLab hosten wir einige extrem große Repositories, und Einblicke in die allgemeine Struktur eines Repositorys sind entscheidend, um die Performance zu verstehen. Während es möglich ist, verschiedene Git-Befehle und andere Tools zusammenzusetzen, um bestimmte Repository-Metriken zu ermitteln, fehlt Git eine Möglichkeit, Informationen über die Form/Struktur eines Repositorys über einen einzigen Befehl zu liefern. Dies hat zur Entwicklung anderer externer Tools geführt, wie git-sizer(1), um diese Lücke zu füllen.
Mit dem Release von Git 2.52 wurde ein neuer „structure"-Subcommand zu git-repo(1) hinzugefügt mit dem Ziel, Informationen über die Struktur eines Repositorys zu liefern. Derzeit zeigt er Informationen über die Anzahl der Referenzen und Objekte im Repository in der folgenden Form an:
$ git repo structure
| Repository structure | Value |
| -------------------- | ------ |
| * References | |
| * Count | 1772 |
| * Branches | 3 |
| * Tags | 1025 |
| * Remotes | 744 |
| * Others | 0 |
| | |
| * Reachable objects | |
| * Count | 418958 |
| * Commits | 87468 |
| * Trees | 168866 |
| * Blobs | 161632 |
| * Tags | 992 |
In zukünftigen Releases hoffen wir, dies zu erweitern und andere interessante Datenpunkte bereitzustellen, wie die größten Objekte im Repository.
Dieses Projekt wurde von Justin Tobler geleitet.
Wir hatten drei erfolgreiche Projekte mit dem Google Summer of Code.
Git enthält mehrere globale Variablen, die in der gesamten Codebasis verwendet werden. Dies erhöht die Komplexität des Codes und verringert die Wartbarkeit. Als Teil dieses Projekts hat Ayush Chandekar daran gearbeitet, die Verwendung der globalen Variable the_repository durch eine Reihe von Patches zu reduzieren.
Das Projekt wurde betreut von Christian Couder und Ghanshyam Thakkar.
Git fehlt ein zentraler Weg, um Repository-Informationen abzurufen, was Benutzer zwingt, sie aus verschiedenen Befehlen zusammenzusetzen. Während git-rev-parse(1) zum De-facto-Tool für den Zugriff auf viele dieser Informationen geworden ist, liegt dies außerhalb seines Hauptzwecks.
Als Teil dieses Projekts hat Lucas Oshiro einen neuen Befehl eingeführt, git-repo(1), der alle Repository-Level-Informationen beherbergen wird. Benutzer können jetzt git repo info verwenden, um Repository-Informationen zu erhalten:
$ git repo info layout.bare layout.shallow object.format references.format
layout.bare=false
layout.shallow=false
object.format=sha1
references.format=reftable
Das Projekt wurde betreut von Patrick Steinhardt und Karthik Nayak.
Git bietet mehrere Befehle zur Verwaltung von Referenzen, nämlich git-for-each-ref(1), git show-ref(1), git-update-ref(1) und git-pack-refs(1). Das macht sie schwerer zu entdecken und erzeugt sich überschneidende Funktionalität. Um dies anzugehen, haben wir den Befehl git-refs(1) eingeführt, um diese Operationen unter einer einzigen Schnittstelle zu konsolidieren. Als Teil dieses Projekts hat Meet Soni den Befehl durch Hinzufügen der folgenden Subcommands erweitert:
git refs optimize zur Optimierung des Reference-Backendsgit refs list zum Auflisten aller Referenzengit refs exists zur Überprüfung der Existenz einer ReferenzDas Projekt wurde betreut von Patrick Steinhardt und shejialuo.
Bereit, diese Verbesserungen zu erleben? Aktualisiere auf Git 2.52.0 und fang an, git last-modified zu verwenden.
Bei GitLab werden wir natürlich sicherstellen, dass all diese Verbesserungen schließlich in einer GitLab-Instanz in deiner Nähe landen!
Erfahre mehr in den offiziellen Git 2.52.0 Release Notes und erkunde unser vollständiges Archiv der Git-Entwicklungs-Berichterstattung.
Dieser Blogbeitrag hat gefallen oder es gibt Fragen oder Feedback? Ein neues Diskussionsthema im GitLab-Community-Forum erstellen und Eindrücke austauschen.
Feedback teilen