Veröffentlicht am: 20. April 2026

11 Minuten Lesezeit

Was ist neu in Git 2.54.0?

Erfahre mehr über die Beiträge zu diesem Release, darunter neue Repository-Wartung, ein neuer Befehl zur Bearbeitung der Commit-Historie, ein Ersatz für git-sizer(1) und mehr.

Das Git-Projekt hat kürzlich Git 2.54.0 veröffentlicht. Werfen wir einen Blick auf einige bemerkenswerte Highlights dieses Releases, das Beiträge des Git-Teams bei GitLab enthält.

Pluggable Object Databases

Git bietet bereits die Möglichkeit, Referenzen entweder mit dem "files"-Backend oder dem "reftable"-Backend zu speichern. Dies wird durch geeignete Abstraktionen in Git ermöglicht, die verschiedene Backends zulassen.

Referenzen sind aber nur einer der beiden wichtigen Datentypen, die in Repositories gespeichert werden – der andere sind Objekte. Objekte werden in der Object Database gespeichert, und jede Object Database wiederum besteht aus mehreren Objektquellen, aus denen Objekte gelesen oder in die geschrieben werden kann. Jede Objektquelle speichert einzelne Objekte entweder als sogenannte "Loose"-Objekte oder komprimiert mehrere Objekte in ein "Packfile" im Verzeichnis .git/objects.

Bisher hatten diese Quellen jedoch keine echte Abstraktionsschicht, sodass das Speicherformat für Objekte komplett in Git fest verdrahtet war. Das ändert sich nun endlich mit Pluggable Object Databases! Das Konzept ist unkompliziert und ähnlich wie bei Referenzen: Statt fest verdrahteter Codepfade für die Objektspeicherung wird eine Abstraktionsschicht eingeführt, die verschiedene Backends für die Objektspeicherung ermöglicht.

Obwohl die Idee einfach ist, ist die Umsetzung komplex, da es überall in Git fest verdrahtete Annahmen über die verwendeten Speicherformate gibt. Die Arbeit an diesem Thema begann bereits mit Git 2.48, das im Januar 2025 veröffentlicht wurde. Der anfängliche Fokus lag darauf, objektbezogene Subsysteme eigenständig zu machen und geeignete Subsysteme für die bestehenden Backends in Git zu erstellen.

Mit Git 2.54 wurde nun ein Meilenstein erreicht: Das Object-Database-Backend ist jetzt pluggable. Noch wird nicht die gesamte Funktionalität von Git abgedeckt, aber die Einführung eines alternativen Backends, das eine sinnvolle Teilmenge der Operationen verarbeitet, ist jetzt ein realistisches Unterfangen.

Derzeit funktionieren nur lokale Workflows wie das Erstellen von Commits, das Anzeigen von Commit-Graphen oder das Durchführen von Merges mit einer solchen alternativen Implementierung. Ausgenommen ist insbesondere alles, was mit einem Remote interagiert, zum Beispiel beim Fetchen oder Pushen von Änderungen. Dennoch ist dies das Ergebnis von fast zwei Jahren Arbeit über fast 400 Commits, die Upstream gemergt wurden, und die Arbeit daran wird natürlich fortgesetzt.

Warum ist das relevant? Die Idee ist, dass es praktikabel wird, neue Speicherformate in Git einzuführen. Beispiele könnten sein:

  • Ein Speicherformat, das große Binärdateien effizienter speichern kann als es Packfiles heute tun
  • Ein Speicherformat, das speziell auf GitLab zugeschnitten ist, um Repositories noch effizienter bereitstellen zu können

Dies ist ein groß angelegtes Vorhaben, das die Zukunft von Git und GitLab maßgeblich prägen dürfte.

Dieses Projekt wurde von Patrick Steinhardt geleitet.

Einfachere Bearbeitung der Commit-Historie

In vielen Softwareentwicklungsprojekten ist es gängige Praxis, nicht nur den Code zu verfeinern, sondern auch die Commit-Historie zu bereinigen, damit sie leicht überprüfbar ist. Das Ergebnis ist eine Reihe kleiner, atomarer Commits, die jeweils eine Sache tun, mit einer guten Commit-Nachricht, die die Intention des Commits sowie spezifische Nuancen beschreibt.

Natürlich entstehen diese atomaren Commits meist nicht einfach von selbst während des Entwicklungsprozesses. Stattdessen gewinnt die Person, die die Änderungen erstellt, durch Iteration ein besseres Verständnis dafür, und die Art und Weise, die Commits aufzuteilen, wird mit der Zeit klarer. Darüber hinaus kann der anschließende Review-Prozess zu Feedback führen, das Änderungen an den erstellten Commits erfordert.

Die Konsequenz dieses Prozesses ist, dass die Commit-Historie im Laufe der Entwicklung viele Male umgeschrieben werden muss. Historisch hat Git dafür interaktive Rebases vorgesehen. Diese interaktiven Rebases sind ein extrem leistungsfähiges Werkzeug: Sie ermöglichen es, Commits umzuordnen, Commit-Nachrichten umzuschreiben, mehrere Commits zusammenzufassen oder beliebige Bearbeitungen an jedem Commit vorzunehmen.

Allerdings sind sie auch etwas kryptisch und schwer zu verstehen. Man muss den Basis-Commit für den Rebase bestimmen, verstehen, wie ein etwas obskures "Instruction Sheet" zu bearbeiten ist, und sich mit dem zustandsbehafteten Rebase-Prozess auskennen. Zum Beispiel wird beim Rebase eines Topic-Branch ein Instruction Sheet wie das folgende angezeigt:

      pick b60623f382 # t: detect errors outside of test cases # empty
pick b80cb55882 # t: prepare `test_match_signal ()` calls for `set -e`
pick 5ffe397f30 # t: prepare `test_must_fail ()` for `set -e`
pick 5e9b0cf5e1 # t: prepare `stop_git_daemon ()` for `set -e`
pick 299561e7a2 # t: prepare `git config --unset` calls for `set -e`
pick ed0e7ca2b5 # t: detect errors outside of test cases

    

Interaktive Rebases sind also zwar leistungsfähig, aber auch ziemlich einschüchternd für durchschnittliche Nutzende.

Das muss aber nicht so sein. Tools wie Jujutsu bieten Interfaces, die im Vergleich zu Git deutlich einfacher zu benutzen sind – zum Beispiel kann man einfach jj split ausführen, um einen Commit in zwei aufzuteilen. Bei Git mit interaktiven Rebases erfordert dieser Anwendungsfall viele verschiedene Schritte mit verwirrenden Befehlszeilenargumenten.

Inspiriert von Jujutsu wurde daher ein neuer Befehl git-history(1) in Git eingeführt, der die Grundlage für eine bessere Bearbeitung der Historie bildet. Derzeit hat dieser Befehl zwei Unterbefehle:

  • git history reword ermöglicht das einfache Umschreiben einer Commit-Nachricht. Man gibt den Commit an, dessen Nachricht umformuliert werden soll, Git fragt nach der neuen Commit-Nachricht, und das war's.
  • git history split ermöglicht das Aufteilen eines Commits in zwei, inspiriert von jj split. Man gibt einen Commit an, Git fragt, welche Änderungen in welchen Commit aufgenommen werden sollen und nach den beiden Commit-Nachrichten, und dann ist man fertig.

Das ist natürlich erst der Anfang, und im Laufe der Zeit sollen weitere Unterbefehle hinzukommen. Zum Beispiel:

  • git history fixup um gestagete Änderungen automatisch in einen bestimmten Commit einzufügen
  • git history drop um einen Commit zu entfernen
  • git history reorder um die Reihenfolge von Commits zu ändern
  • git history squash um eine Reihe von Commits zusammenzufassen

Aber das ist noch nicht alles! Zusätzlich zur einfachen Bearbeitung der Historie kann dieser neue Befehl auch automatisch alle lokalen Branches rebasen, die den bearbeiteten Commit zuvor enthielten. Das bedeutet, man kann sogar einen Commit bearbeiten, der nicht auf dem aktuellen Branch liegt, und alle Branches, die den Commit enthalten, werden umgeschrieben.

Es mag zunächst überraschend erscheinen, dass Git automatisch abhängige Branches rebast, da dies eine deutliche Abweichung von der Funktionsweise von git-rebase(1) darstellt. Dies ist aber Teil eines größeren Vorhabens, um bessere Unterstützung für Stacked Diffs in Git zu bringen – eine Methode, eine Reihe mehrerer abhängiger Branches zu erstellen, die unabhängig voneinander überprüft werden können, aber gemeinsam auf ein größeres Ziel hinarbeiten.

Dieses Projekt wurde von Patrick Steinhardt mit Unterstützung von Elijah Newren geleitet.

Ein nativer Ersatz für git-sizer(1)

Die Größe eines Git-Repositorys ist ein wichtiger Faktor, der bestimmt, wie gut Git und GitLab damit umgehen können. Aber die Größe allein ist nicht der einzige Faktor, da die Performance eines Repositorys letztlich eine Kombination aus mehreren verschiedenen Dimensionen ist:

  • Die Tiefe der Commit-Historie
  • Die Struktur des Verzeichnisbaums
  • Die Größe der im Repository gespeicherten Dateien
  • Die Anzahl der Referenzen

Das sind nur einige der Dimensionen, die berücksichtigt werden müssen, wenn man vorhersagen will, ob Git ein Repository gut verarbeiten kann.

Obwohl klar ist, dass die reine Repository-Größe nicht ausreicht, bietet Git selbst keine Tools, die einen einfachen Überblick über diese Metriken geben. Stattdessen ist man auf Drittanbieter-Tools wie git-sizer(1) angewiesen, um diese Lücke zu füllen. Dieses Tool leistet hervorragende Arbeit bei der Darstellung dieser Informationen, ist aber kein Bestandteil von Git und muss daher separat installiert werden.

Observability von Repository-Interna ist bei GitLab entscheidend, daher wurde in Git 2.52 ein neuer git repo structure-Befehl eingeführt, um Repository-Metriken anzuzeigen, der in Git 2.53 erweitert wurde, um inflated und Disk-Sizes für Objekte nach Typ anzuzeigen.

In Git 2.54 wird dieser Befehl weiter ausgebaut, sodass nicht nur die Gesamtgröße angezeigt wird, sondern auch die größten Objekte nach Typ:

      $ git clone https://gitlab.com/git-scm/git.git
$ cd git
$ git repo structure
Counting objects: 410445, done.
| Repository structure      | Value       |
| ------------------------- | ----------- |
| * References              |             |
|   * Count                 |    1.01 k   |
|     * Branches            |       1     |
|     * Tags                |    1.00 k   |
|     * Remotes             |       9     |
|     * Others              |       0     |
|                           |             |
| * Reachable objects       |             |
|   * Count                 |  410.45 k   |
|     * Commits             |   83.99 k   |
|     * Trees               |  164.46 k   |
|     * Blobs               |  161.00 k   |
|     * Tags                |    1.00 k   |
|   * Inflated size         |    7.46 GiB |
|     * Commits             |   57.53 MiB |
|     * Trees               |    2.33 GiB |
|     * Blobs               |    5.07 GiB |
|     * Tags                |  737.48 KiB |
|   * Disk size             |  181.37 MiB |
|     * Commits             |   33.11 MiB |
|     * Trees               |   40.58 MiB |
|     * Blobs               |  107.11 MiB |
|     * Tags                |  582.67 KiB |
|                           |             |
| * Largest objects         |             |
|   * Commits               |             |
|     * Maximum size    [1] |   17.23 KiB |
|     * Maximum parents [2] |      10     |
|   * Trees                 |             |
|     * Maximum size    [3] |   58.85 KiB |
|     * Maximum entries [4] |    1.18 k   |
|   * Blobs                 |             |
|     * Maximum size    [5] | 1019.51 KiB |
|   * Tags                  |             |
|     * Maximum size    [6] |    7.13 KiB |

[1] f6ecb603ff8af608a417d7724727d6bc3a9dbfdf
[2] 16d7601e176cd53f3c2f02367698d06b85e08879
[3] 203ee97047731b9fd3ad220faa607b6677861a0d
[4] 203ee97047731b9fd3ad220faa607b6677861a0d
[5] aa96f8bc361fd84a1459440f1e7de02ab0dc3543
[6] 07e38db6a5a03690034d27104401f6c8ea40f1fc

    

Mit diesen Informationen ist die Funktionsparität mit git-sizer(1) nahezu erreicht. Ganz fertig ist die Arbeit aber noch nicht – geplant sind weitere Features wie:

  • Severity Levels wie sie in git-sizer(1) existieren
  • Graphen, die die Verteilung der Objektgrößen visualisieren
  • Die Möglichkeit, Objekte zu scannen, die über eine Teilmenge von Referenzen erreichbar sind

Dieses Projekt wurde von Justin Tobler geleitet.

Neue Infrastruktur für Repository-Wartung

Beim Schreiben von Daten in ein Git-Repository entstehen in der Regel weitere Loose-Objekte. Ohne Verwaltung führt dies zu einer großen Anzahl separater Dateien im Verzeichnis .git/objects/, was mehrere Operationen verlangsamt, die auf viele Objekte gleichzeitig zugreifen wollen. Git packt diese Objekte daher regelmäßig in "Packfiles", um eine gute Performance sicherzustellen.

Das ist aber nicht die einzige Datenstruktur, die im Laufe der Zeit ineffizient werden kann: Das Aktualisieren von Referenzen kann Loose-Referenzen erzeugen, Reflogs müssen getrimmt, Worktrees können veralten, und Caches wie Commit-Graphen müssen regelmäßig aktualisiert werden.

All diese Aufgaben wurden historisch von git-gc(1) verwaltet. Dieses Tool hat jedoch eine monolithische Architektur, in der es im Grunde alle erforderlichen Aufgaben sequenziell ausführt. Diese Grundlage ist schwer erweiterbar und bietet wenig Flexibilität, wenn die Wartung leicht angepasst werden soll.

Das Git-Projekt führte in Git 2.29 das neue Tool git-maintenance(1) ein. Im Gegensatz zu git-gc(1) ist git-maintenance(1) nicht monolithisch, sondern um Tasks herum strukturiert. Diese Tasks sind frei konfigurierbar, sodass kontrolliert werden kann, welche Tasks ausgeführt werden, was eine deutlich feinere Kontrolle über die Repository-Wartung ermöglicht.

Schließlich wurde Git standardmäßig auf git-maintenance(1) umgestellt. Zu Beginn war allerdings der einzige standardmäßig aktivierte Task der git-gc(1)-Task, der – wie der Name vermuten lässt – einfach git gc ausführt. Um die Wartung manuell mit dem neuen Befehl auszuführen, kann git maintenance run aufgerufen werden, aber Git führt dies auch automatisch nach verschiedenen anderen Befehlen aus.

In den letzten Releases wurden alle einzelnen Tasks implementiert, die von git-gc(1) unterstützt werden, auch in git-maintenance(1), um Funktionsparität zwischen den beiden Tools sicherzustellen.

Darüber hinaus wurde ein neuer Task implementiert, der Gits moderne Architektur für das Repacking von Objekten mit Geometric Compaction nutzt. Geometric Compaction eignet sich deutlich besser für große Monorepos, und mit den Arbeiten zur Kompatibilität mit Partial Clones, die in Git 2.53 eingeflossen sind, stellen sie jetzt einen vollständigen Ersatz für die bisherige Repacking-Strategie in Git dar.

Mit Git 2.54 wurde nun ein weiterer bedeutender Meilenstein erreicht: Statt der bisherigen git-gc(1)-basierten Strategie wird jetzt standardmäßig Geometric Repacking mit feingranularen individuellen Wartungs-Tasks verwendet! Neben der höheren Effizienz für große Monorepos stellt dies auch eine einfachere Grundlage für zukünftige Weiterentwicklungen sicher.

Die git-maintenance(1)-Infrastruktur wurde ursprünglich von Derrick Stolee implementiert, und Geometric Maintenance wurde von Taylor Blau eingeführt. Die Arbeit zur Einführung der neuen feingranularen Tasks und die Migration zur neuen Wartungsstrategie wurde von Patrick Steinhardt geleitet.

Weiterlesen

Dieser Artikel hat nur einige der Beiträge hervorgehoben, die von GitLab und der breiteren Git-Community zu diesem aktuellen Release geleistet wurden. Weitere Informationen dazu finden sich in der offiziellen Release-Ankündigung des Git-Projekts. Außerdem lohnt sich ein Blick in die früheren Git-Release-Blogposts, um weitere vergangene Highlights der Beiträge von GitLab-Teammitgliedern zu sehen.

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.