Nach drei Monaten Entwicklung wurde die Version 2.41 des verteilten Systems zur Verwaltung von Quelltexten Git veröffentlicht. Git gehört zu den beliebtesten, zuverlässigen und leistungsstärksten Versionsverwaltungssystemen und bietet flexible Werkzeuge für die nicht-lineare Entwicklung, die auf Zweigen und deren Zusammenführung basieren. Um die Integrität der Historie und die Widerstandsfähigkeit gegen nachträgliche Änderungen sicherzustellen, wird ein implizites Hashing der gesamten vorherigen Historie in jedem Commit verwendet. Zudem ist die Verifizierung einzelner Tags und Commits durch digitale Signaturen der Entwickler möglich.
Im Vergleich zur vorherigen Version wurden in die neue Version 542 Änderungen aufgenommen, die von 95 Entwicklern vorbereitet wurden, von denen 29 erstmals an der Entwicklung beteiligt waren. Zu den wichtigsten Neuerungen zählen:
- Die Verarbeitung von unerreichbaren Objekten wurde verbessert. Dies sind Objekte, zu denen im Repository keine Verweise bestehen (keine Branches oder Tags verweisen darauf). Unerreichbare Objekte werden vom Garbage Collector entfernt, verbleiben jedoch für eine gewisse Zeit im Repository, um Rennbedingungen auszuschließen. Um den Zeitraum zu verfolgen, in dem die unerreichbaren Objekte vorhanden sind, ist es notwendig, sie mit Zeitstempeln zu versehen. Dies erschwert die Speicherung in einer einzelnen Pack-Datei, in der alle Objekte einen gemeinsamen Änderungszeitpunkt haben. Frühere Versionen speicherten jedes unerreichbare Objekt in einer separaten Datei, was bei einer großen Anzahl neuer unerreichbarer Objekte, die noch nicht zur Löschung fällig sind, zu Problemen führte. In der neuen Version wird standardmäßig der Mechanismus "cruft packs" zum Verpacken der unerreichbaren Objekte verwendet. Dadurch können alle unerreichbaren Objekte in einer einzigen Pack-Datei gespeichert werden, während die Änderungsdaten jedes Objekts in einer separaten Tabelle erfasst werden, die in einer Datei mit der Erweiterung ".mtimes" gespeichert ist und über eine Indexdatei mit der Erweiterung ".idx" verbunden ist.

- Die Verwendung von Reverse-Indexierung (revindex) für Pack-Dateien ist standardmäßig aktiviert. Bei Tests im Repository torvalds/linux hat die Anwendung der Reverse-Indexierung ressourcenintensive Vorgänge wie „git push“ um das 1,49-Fache beschleunigt, während einfache Vorgänge wie die Berechnung der Größe eines Objekts mit „git cat-file —batch='%(objectsize:disk)'“ um das 77-Fache schneller waren. Die Dateien („.rev“) mit der Reverse-Indexierung werden im Repository im Verzeichnis „.git/objects/pack“ gespeichert.
Zur Erinnerung: Git speichert alle Daten in Form von Objekten, die in separaten Dateien abgelegt sind. Um die Effizienz der Arbeit mit dem Repository zu erhöhen, werden die Objekte zusätzlich in Pack-Dateien gespeichert, in denen die Informationen als Strom von aufeinanderfolgenden Objekten dargestellt sind (ein ähnliches Format wird beim Übertragen von Objekten mit den Befehlen git fetch und git push verwendet). Für jede Pack-Datei wird eine Indexdatei (.idx) erstellt, die es ermöglicht, den Offset im Pack-Datei anhand der Objekt-ID sehr schnell zu bestimmen, an dem dieses Objekt gespeichert ist.
Der in der neuen Version eingeführte umgekehrte Index zielt darauf ab, den Prozess zur Identifizierung von Objekten anhand ihrer Platzierungsinformationen im Pack-Dateiformat zu optimieren. Früher wurde eine solche Umwandlung während des Parsens der Pack-Datei in Echtzeit durchgeführt und nur im Speicher gehalten, was eine Wiederverwendung solcher Indizes verhinderte und dazu zwang, den Index jedes Mal neu zu erzeugen. Der Indexierungsprozess besteht darin, ein Array von „Objekt-Position“-Paaren zu erstellen und es nach Position zu sortieren, was bei großen Pack-Dateien viel Zeit in Anspruch nehmen kann.
Zum Beispiel wurde die Operation zur Ausgabe des Inhalts von Objekten, bei der ein direkter Index verwendet wird, 62-mal schneller ausgeführt als die Operation zur Anzeige der Größe von Objekten, bei der die Positionsverknüpfungsdaten nicht indiziert wurden. Nach der Verwendung des umgekehrten Index benötigten die angegebenen Operationen ungefähr die gleiche Zeit. Umgekehrte Indizes ermöglichen auch eine Beschleunigung der Objektübertragungsoperationen bei Ausführungen von Fetch- und Push-Befehlen, indem bereits vorbereitete Daten direkt von der Festplatte übertragen werden.

- Im Protokoll „Credential Helper“, das zur Übertragung von Anmeldeinformationen beim Zugriff auf Repositories mit eingeschränktem Zugang verwendet wird, wurde die Unterstützung für die Übertragung von WWW-Authenticate-Headern zwischen dem Anmeldeinformationen-Handler und dem Dienst, in dem die Authentifizierung erfolgt, hinzugefügt. Die Unterstützung des WWW-Authenticate-Headers ermöglicht die Übertragung von Scope-Parametern für eine granularere Trennung des Benutzerzugriffs auf die Repositories und die Abgrenzung der Bereiche, die für Anfragen verfügbar sind.
- Im Befehl for-each-ref wurde die Formatierungsoption „%(ahead-behind:)“ hinzugefügt, mit der Sie auf einfache Weise Informationen darüber abrufen können, wie viele Commits in einem bestimmten Branch im Vergleich zu einem anderen Branch vorhanden oder nicht vorhanden sind (inwiefern ein Branch dem anderen hinsichtlich der Commits voraus oder hinterherhinkt). Früher war es erforderlich, zwei separate Befehle auszuführen, um solche Informationen zu erhalten: „git rev-list --count main..my-feature“ für die Anzahl der spezifischen Commits und „git rev-list --count my-feature..main“ für die Anzahl der fehlenden Commits. Jetzt können solche Berechnungen auf einen einzigen Befehl reduziert werden, was das Schreiben von Skripten vereinfacht und die Ausführungszeit verkürzt. Zum Beispiel können Sie eine Einzeilige verwenden, um nicht zusammengeführte Branches anzuzeigen und deren Rückstand oder Vorsprung im Vergleich zu ihrem Hauptbranch zu bewerten: $ git for-each-ref --no-merged=origin/HEAD \ --format='%(refname:short) %(ahead-behind:origin/HEAD)' \ refs/heads/tb/ | column -t tb/cruft-extra-tips 2 96 tb/for-each-ref--exclude 16 96 tb/roaring-bitmaps 47 3 anstelle des zuvor verwendeten Skripts, welches 17-mal langsamer ausgeführt wird: $ git for-each-ref --format='%(refname:short)' --no-merged=origin/HEAD \ refs/heads/tb | while read ref do ahead="$(git rev-list --count origin/HEAD..$ref)" behind="$(git rev-list --count $ref..origin/HEAD)" printf "%s %d %d\n" "$ref" "$ahead" "$behind" done | column -t tb/cruft-extra-tips 2 96 tb/for-each-ref--exclude 16 96 tb/roaring-bitmaps 47 3
- Das Kommando „git fetch“ hat die Option „—porcelain“ hinzugefügt, mit der eine Ausgabe im Format „ “ generiert wird. Dieses Format ist zwar weniger lesbar, aber besser für die Analyse in Skripten geeignet.
- Die Einstellung „fetch.hideRefs“ wurde hinzugefügt, um die Operationen „git fetch“ zu beschleunigen, indem einige Referenzen im lokalen Repository während der Überprüfung des vollständigen Objektsatzes durch den Server verborgen werden. Dadurch wird die Zeit gespart, indem die Prüfung auf Server, die direkt abgerufen werden, beschränkt wird. Zum Beispiel hat das Ausschließen aller Referenzen, außer denen, die auf das Ziel $remote gerichtet sind, die Ausführungszeit des „git fetch“-Befehls von 20 Minuten auf 30 Sekunden verkürzt. Server $ git -c fetch.hideRefs=refs -c fetch.hideRefs=!refs/remotes/$remote \ fetch $remote
- Im Befehl „git fsck“ wurde die Möglichkeit implementiert, Beschädigungen, die Übereinstimmung von Prüfziffern sowie die Korrektheit der Werte in den Verfügbarkeits-Bitkarten und Rückwärtsindizes zu überprüfen.
- Im Befehl „git clone —local“ wurde die Ausgabe eines Fehlers bei dem Versuch implementiert, aus einem Repository zu kopieren, das symbolische Links innerhalb von $GIT_DIR enthält.
Quelle: opennet.ru


