Blog Open Source Was gibt es Neues in Git 2.47.0?
Veröffentlicht am: October 7, 2024
9 Minuten Lesezeit

Was gibt es Neues in Git 2.47.0?

Erfahre, was dich in der neuesten Version von Git erwartet, darunter neue globale Variablen zum Konfigurieren von Referenz- und Objekt-Hash-Formaten. Entdecke Beträge des Git-Teams von GitLab und der gesamten Git-Community.

git 2 - cover

Das Git-Projekt hat kürzlich Git v2.47.0 veröffentlicht. Werfen wir einen Blick auf die wichtigsten Highlights dieser Version, die Beiträge des Git-Teams von GitLab und der gesamten Git-Community enthält.

Neue globale Konfigurationsoptionen

Wenn du die letzten Git-Releases verfolgt hast, kennst du wahrscheinlich auch das Referenz-Backend „reftable“, das mit der Git-Version 2.45 eingeführt wurde. Weitere Informationen findest du in unserem Anfängerleitfaden zum reftables-Format von Git. Um ein Repository im reftables-Format zu initialisieren, musste früher die Option --ref-format an git-init(1) übergeben werden:

$ git init --ref-format reftable

Mit Release 2.47 gibt es in Git nun die Konfigurationsoption init.defaultRefFormat, die Git sagt, welches Referenz-Backend bei der Initialisierung eines Repositorys verwendet werden soll. Damit kann das Standard-Backend „Files“ überschrieben werden und du kannst beginnen, das reftables-Backend zu nutzen. Die Konfiguration funktioniert folgendermaßen:

$ git config set --global init.defaultRefFormat reftable

Wie einige vielleicht wissen, ist auch das von Git-Repositories verwendete Objekt-Hash-Format konfigurierbar. Standardmäßig werden Repositories so initialisiert, dass sie das SHA-1-Objektformat verwenden. Eine Alternative ist das SHA-256-Format, das sicherer und zukunftssicherer ist. Weitere Informationen hierzu findest du in einem unserer früheren Blogbeiträge zum SHA-256-Support in Gitaly. Ein SHA-256-Repository kann erstellt werden, indem die Option `--object-format' an git-init (1) übergeben wird:

$ git init --object-format sha256

In dieser Git-Version wurde init.defaultObjectFormat als weitere Konfigurationsoption hinzugefügt. Diese Option sagt Git, welches Objektformat bei der Initialisierung eines Repositorys standardmäßig verwendet werden soll. Die Konfiguration funktioniert folgendermaßen:

$ git config set --global init.defaultObjectFormat sha256

Bemerkenswert ist, dass SHA-256-Repositories nicht mit SHA-1 kompatibel sind und nicht alle Forges das Hosting von SHA-256-Repositories unterstützen. GitLab hat kürzlich experimentelle Unterstützung für SHA-256-Repositories angekündigt, wenn du diese ausprobieren möchtest.

Diese Optionen bieten eine gute Möglichkeit, diese Repository-Funktionen zu nutzen, ohne bei jeder Initialisierung eines neuen Repositorys bewusst daran denken zu müssen.

Dieses Projekt wurde von Patrick Steinhardt geleitet.

Neuer Unterbefehl für git-refs(1)

In der vorherigen Git-Version wurde der Befehl git-refs (1) eingeführt, um einen Low-Level-Zugriff auf Referenzen in einem Repository zu ermöglichen und den Unterbefehl „migrate“ einzuführen, um zwischen den Referenz-Backends zu wechseln. In dieser Version wird der neue Unterbefehl „verify“ eingeführt, mit dem Benutzer(innen) die Referenzdatenbank auf Konsistenz überprüfen können. Um die Konsistenz eines Repositorys zu überprüfen, führen wir oft git-fsck(1) aus.

Dabei ist bemerkenswert, dass dieser Befehl die Referenzdatenbank des Repositorys jedoch nicht explizit verifiziert. Mit der Einführung des reftables-Referenzformats, das ein Binärformat ist und daher schwerer manuell zu überprüfen ist, ist es jetzt noch wichtiger, dass Werkzeuge zur Verfügung stehen, um diese Lücke zu schließen. Um das zu zeigen, wollen wir ein Repository mit einer ungültigen Referenz einrichten:

# Da das Backend "files" verwendet wird, können wir einfach eine ungültige Referenz erstellen.
$ git init --ref-format files
$ git commit --allow-empty -m "init"
# Ein einzelnes '@' ist kein gültiger Referenzname.
$ cp .git/refs/heads/main .git/refs/heads/@
$ git refs verify
error: refs/heads/@: badRefName: invalid refname format

Wir sehen hier, dass eine ungültige Referenz erkannt wurde und daher eine Fehlernachricht ausgegeben wird. Diese Werkzeuge werden zwar eher nicht von Endbenutzer(innen) ausgeführt, aber trotzdem sind sie insbesondere serverseitig praktisch, um sicherzustellen, dass Repositories konsistent bleiben. Das Ziel ist schlussendlich, diesen Befehl als Teil von git-fsck(1) zu integrieren und dadurch eine vereinheitlichte Möglichkeit zu schaffen, Konsistenzüberprüfungen von Repositories durchzuführen.

Dieses Projekt wurde von Jialuo She im Rahmen des Google Summer of Code geleitet. Weitere Informationen findest du im GSoC-Bericht von Jialuo.

Laufende reftables-Arbeit

Diese Version enthält auch Korrekturen für einige Fehler, die im reftables-Backend gefunden wurden. Einer dieser Fehler ist besonders interessant, denn er beeinflusst, wie die Tabellenkomprimierung durchgeführt wurde.

Du erinnerst dich vielleicht daran, dass das reftables-Backend aus einer Reihe von Tabellen besteht, die den Status aller Referenzen im Repository enthalten. Jeder atomare Satz an Referenzenänderungen führt dazu, dass eine neue Tabelle geschrieben und in der Datei „tables.list“ erfasst wird. Um die Anzahl der vorhandenen Tabellen zu reduzieren, werden die Tabellen nach jeder Referenzaktualisierung komprimiert und geometrisch nach Dateigröße geordnet. Nachdem die Tabellen komprimiert wurden, wird die Datei „tables.list“ mit dem neuen Status der reftables auf dem Laufwerk aktualisiert.

Das System ist so konzipiert, dass es gleichzeitig möglich ist, Tabellen zu schreiben und zu komprimieren. Die Synchronisation an bestimmten Punkten wird durch Lock-Dateien gesteuert. Wenn beispielsweise eine Komprimierung gestartet wird, wird die Datei „tables.list“ von vorneherein gesperrt, sodass die Datei konsistent gelesen werden kann und auch die Tabellen, die komprimiert werden müssen, gesperrt werden können. Da die eigentliche Tabellenkomprimierung etwas dauern kann, wird die Sperre aufgehoben, sodass gleichzeitige Schreibvorgänge fortgesetzt werden können. Das ist sicher, da gleichzeitige Schreiber(innen) wissen, dass sie die nun gesperrten Tabellen, die komprimiert werden sollen, nicht verändern dürfen. Wenn die neu komprimierten Tabellen fertig geschrieben wurden, wird die Datei „tables.list“ wieder gesperrt und wird dieses Mal aktualisiert, damit der neue Tabellenzustand angezeigt wird.

Es gibt jedoch ein Problem: Was passiert, wenn bei einer gleichzeitigen Referenzaktualisierung eine neue Tabelle in die „tables.list“ geschrieben wird, während eine Tabellenkomprimierung läuft, nachdem die ursprüngliche Sperre aufgehoben wurde, aber bevor die neue Listendatei geschrieben wird? Wenn diese Situation eintreten würde, würde der Komprimierungsprozess nichts von der neuen Tabelle wissen und daher die Datei „tables.list“ ohne die neue Tabelle neu schreiben. Das verhindert in weiterer Folge die gleichzeitige Aktualisierung und könnte dazu führen, dass Referenzen nicht wie erwartet hinzugefügt, aktualisiert oder entfernt werden.

Glücklicherweise ist die Lösung dieses Problems ziemlich einfach. Wenn der Komprimierungsvorgang die Sperre erhält, um in die „tables.list“ zu schreiben, muss er zuerst überprüfen, ob Aktualisierungen an der Datei vorgenommen wurden und dann die Datei neu laden. Auf diese Weise wird sichergestellt, dass alle gleichzeitigen Tabellenaktualisierungen auch entsprechend einbezogen werden. Weitere Informationen zu diesem Fix findest du im entsprechenden Mailinglisten-Thread.

Dieses Projekt wurde von Patrick Steinhardt geleitet.

Fixes für git-maintenance(1)

Wenn ein Repository wächst, ist es wichtig, dass es ordnungsgemäß gewartet wird. Standardmäßig führt Git git-maintenance(1) nach bestimmten Operationen aus, damit der Zustand des Repositorys gesund bleibt. Um unnötige Wartung zu vermeiden, wird die Option --auto angegeben. Sie nutzt definierte Heuristiken, um zu bestimmen, ob Wartungsaufgaben ausgeführt werden sollen. Der Befehl kann so konfiguriert werden, dass er verschiedene Wartungsaufgaben durchführt. Standardmäßig führt er aber einfach git-gc(1) im Hintergrund aus und ermöglicht es den Benutzer(innen), mit ihren Aufgaben fortzufahren.

Dies funktioniert wie erwartet, bis die Wartung für nicht standardmäßige Wartungsaufgaben konfiguriert ist. Wenn das passiert, werden die konfigurierten Wartungsaufgaben im Vordergrund ausgeführt und der ursprüngliche Wartungsprozess wird erst beendet, wenn alle Aufgaben abgeschlossen sind. Nur die Aufgabe „gc“ wird wie erwartet in den Hintergrund verschoben. Es hat sich gezeigt, dass sich git-gc(1), wenn es mit --auto ausgeführt wird, aus Versehen selbst verschob und andere Wartungsaufgaben keine Möglichkeit dazu hatten. Dies hatte das Potenzial, bestimmte Git-Befehle zu verlangsamen, da die automatische Wartung erst vollständig abgeschlossen werden musste, bevor sie beendet werden konnten.

In dieser Release wird das Problem behoben, indem git-maintenance(1) nun die Option --detach beigebracht wird, mit der der gesamte git-maintenance(1)-Prozess im Hintergrund läuft und nicht mehr nur einzelne Aufgaben. Die von Git durchgeführte automatische Wartung wurde ebenfalls aktualisiert, um diese neue Option zu verwenden. Weitere Informationen zu diesem Fix findest du im entsprechenden Mailinglisten-Thread.

Weiter oben wurde erwähnt, dass die automatische Wartung eine Reihe von Heuristiken verwendet, um festzustellen, ob bestimmte Wartungsvorgänge durchgeführt werden sollen oder nicht. Leider gibt es für das „files“-Referenz-Backend, wenn git-pack-refs(1) mit der Option --auto durchgeführt wird, keine solche Heuristik und lose Referenzen werden bedingungslos in eine „packed-refs“-Datei verpackt. Bei Repositories mit vielen Referenzen kann das erneute Schreiben der Datei „pack-refs“ ziemlich lange dauern.

In dieser Version wird daher eine Heuristik eingeführt, die entscheidet, ob lose Referenzen im „files“-Backend verpackt werden sollen. Diese Heuristik berücksichtigt die Größe der bestehenden „packed-refs“-Datei sowie die Anzahl der losen Referenzen im Repository. Je größer die „packed-refs“-Datei wird, umso höher wird die Schwelle für die Anzahl der losen Referenzen, bevor diese verpackt werden. Dadurch wird die Referenzverpackung im „files“-Backend weniger aggressiv und das Repository bleibt trotzdem gewartet. Sieh dir den entsprechenden Mailinglisten-Thread an, um mehr darüber zu erfahren.

Dieses Projekt wurde von Patrick Steinhardt geleitet.

Code-Refactoring und Verbesserungen der Wartbarkeit

Neben funktionalen Änderungen wird auch an der Refaktorisierung gearbeitet und der Code wird bereinigt. Diese Verbesserungen sind wichtig, da sie dazu beitragen, dem Ziel des Projektes – die Libifizierung der internen Komponenten – näherzukommen. Hier findest du einen aktuellen Update-Thread zum Thema Libifizierung.

Ein Verbesserungsbereich war, Speicherlecks zu beheben. Das Git-Projekt weist einige Speicherlecks auf. In den meisten Fällen verursachen diese Lecks keine großen Probleme, da ein Git-Prozess normalerweise nur für eine kurze Zeit läuft und das System danach bereinigt wird, aber im Zusammenhang mit der Libifizierung sollte dies behoben werden. Tests im Projekt können mit einem Leck-Erkenner kombiniert werden, um Lecks zu erkennen. Aufgrund bestehender Lecks kann es jedoch schwierig zu validieren und durchzusetzen sein, dass neue Änderungen keine neuen Lecks einführen. Wir arbeiten kontinuierlich daran, alle Speicherlecks, die durch bestehende Tests im Projekt aufgedeckt werden, zu beheben. Leckfreie Tests werden anschließend mit TEST_PASSES_SANITIZE_LEAK=true gekennzeichnet, um anzuzeigen, dass sie in Zukunft voraussichtlich leckfrei sind. Vor dieser Release hatte das Projekt 223 Testdateien, die Speicherlecks enthielten. Mit dieser Version wurde die Zahl jetzt auf nur noch 60 gesenkt.

Außerdem arbeiten wir weiterhin daran, die Verwendung globaler Variablen im gesamten Projekt zu reduzieren. Eine solche berüchtigte globale Variable ist the_repository, die den Status des Repositorys enthält, auf dem gearbeitet wird, und auf die im gesamten Projekt verwiesen wird. Diese Release enthält eine Reihe von Patches, mit denen the_repository entfernt und der Wert bei Bedarf direkt weitergegeben wird. Für Subsysteme im Git-Projekt, die immer noch von the_repository abhängig sind, ist USE_THE_REPOSITORY_VARIABLE definiert, sodass es global verwendet werden kann. Jetzt sind die Subsysteme refs, config und path nicht mehr auf deren Verwendung angewiesen.

Dieses Projekt wurde von Patrick Steinhardt mit Unterstützung von John Cai und Jeff King geleitet.

Weiterlesen

In diesem Blogbeitrag werden nur einige der Beiträge von GitLab und der breiteren Git-Community für diese neueste Release vorgestellt. Mehr darüber erfährst du in der offiziellen Release-Ankündigung. Sieh dir auch unsere letzten Blogbeiträge zu Git-Releases an, um weitere wichtige Beiträge von GitLab-Teammitgliedern zu entdecken.

Wir möchten gern von dir hören

Hat dir dieser Blogbeitrag gefallen oder hast du Fragen oder Feedback? Erstelle ein neues Diskussionsthema im GitLab Community-Forum und tausche deine Eindrücke aus. Teile dein Feedback

Bist du bereit?

Sieh dir an, was dein Team mit einer einheitlichen DevSecOps-Plattform erreichen könnte.

Kostenlose Testversion anfordern

Finde heraus, welcher Tarif für dein Team am besten geeignet ist

Erfahre mehr über die Preise

Erfahre mehr darüber, was GitLab für dein Team tun kann

Sprich mit einem Experten/einer Expertin