Veröffentlicht am: 17. November 2025

12 Minuten Lesezeit

Was ist neu in Git 2.52.0?

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.

Neuer git-last-modified(1)-Befehl

Viele Git-Forges wie GitLab zeigen Dateien in einer Tree-Ansicht wie dieser an:

NameLast commitLast update
README.mdREADME: *.txt -> *.adoc fixes4 months ago
RelNotesStart 2.51 cycle, the first batch4 weeks ago
SECURITY.mdSECURITY: describe how to report vulnerabilities4 years
abspath.cabspath: move related functions to abspath2 years
abspath.habspath: move related functions to abspath2 years
aclocal.m4configure: use AC_LANG_PROGRAM consistently15 years ago
add-patch.cpager: stop using the_repository7 months ago
advice.cadvice: allow disabling default branch name advice4 months ago
advice.hadvice: allow disabling default branch name advice4 months ago
alias.hrebase -m: fix serialization of strategy options2 years
alloc.hgit-compat-util: move alloc macros to git-compat-util.h2 years ago
apply.capply: only write intents to add for new files8 days ago
archive.cMerge branch 'ps/parse-options-integers'3 months ago
archive.harchive.h: remove unnecessary include1 year
attr.hfuzz: port fuzz-parse-attr-line from OSS-Fuzz9 months ago
banned.hbanned.h: mark strtok() and strtok_r() as banned2 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:

  • Wir müssen für jede Datei einen neuen Git-Befehl starten.
  • Git muss die History für jede Datei separat durchlaufen.

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:

  1. Beginne damit, die History vom angegebenen Commit aus zu durchlaufen.
  2. Für jeden Commit:
    1. Wenn er keinen der Pfade ändert, an denen wir interessiert sind, fahren wir mit dem nächsten Commit fort.
    2. Wenn er es tut, geben wir die Commit-ID zusammen mit dem Pfad aus. Außerdem entfernen wir den Pfad aus der Menge der interessanten Pfade.
  3. Wenn die Liste der interessanten Pfade leer wird, stoppen wir.

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.

Signatur-bezogene Verbesserungen für git-fast-export(1) und git-fast-import(1)

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:

  • Wir möchten vielleicht kryptografische Signaturen sowohl für Commits als auch für Tags behalten, die nach dem Neuschreiben noch gültig sind (z.B. weil sich die History, die zu ihnen führt, nicht geändert hat).
  • Wir möchten vielleicht neue kryptografische Signaturen für Commits und Tags erstellen, bei denen die vorherige Signatur ungültig geworden ist.

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:

  • In Git 2.50 haben wir eine Option --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.
  • In Git 2.51 haben wir das Format verbessert, das zum Exportieren und Importieren von Commit-Signaturen verwendet wird, und wir haben es für 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.
  • In Git 2.52 haben wir die Optionen --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:

  • Nur die Commit-Signaturen beizubehalten, die noch gültig sind, zu git-fast-import(1).
  • Daten neu zu signieren, bei denen die Signatur ungültig wurde.

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.

Neue und verbesserte git-maintenance(1)-Strategien

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.

Neuer Subcommand für git-repo(1) zur Anzeige von Repository-Metriken

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.

Verbesserungen im Zusammenhang mit dem Google Summer of Code 2025

Wir hatten drei erfolgreiche Projekte mit dem Google Summer of Code.

Refactoring zur Reduzierung von Gits globalem Status

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.

Maschinenlesbares Repository-Informations-Abfrage-Tool

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.

Konsolidierung ref-bezogener Funktionalität in git-refs

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-Backends
  • git refs list zum Auflisten aller Referenzen
  • git refs exists zur Überprüfung der Existenz einer Referenz

Das Projekt wurde betreut von Patrick Steinhardt und shejialuo.

Was kommt als Nächstes?

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.

Feedback erwünscht

Dieser Blogbeitrag hat gefallen oder es gibt Fragen oder Feedback? Ein neues Diskussionsthema im GitLab-Community-Forum erstellen und Eindrücke austauschen.

Feedback teilen

Beginne noch heute, schneller zu entwickeln

Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.