Veröffentlicht am: 28. September 2026

11 Minuten Lesezeit

Was ist neu in Git 2.56.0?

Git 2.56.0 steckt den Weg zu Git 3.0 ab und bringt neue Werkzeuge für den Alltag: Commits mit git-history(1) entfernen, Referenzen mit git-refs(1) ändern und Historie mit git-replay(1) linearisieren.

Das Git-Projekt hat Git 2.56.0 veröffentlicht. Dieser Artikel stellt die wichtigsten Neuerungen vor, darunter Beiträge des Git-Teams bei GitLab.

Die Themen:

Git Merge 2026 und der Zeitplan für Git 3.0

Der Release-Zyklus fiel mit der Git Merge 2026 in Lissabon zusammen. Die Konferenz erstreckte sich über drei Tage: einen JJ-Con-Tag, einen Tag mit Git-Vorträgen sowie einen Tag mit Unconference und Git Contributor Summit. Die Aufzeichnungen der Git-Vorträge folgen in Kürze.

Ein zentrales Thema des Git Contributor Summit war die Planung von Git 3.0. Das Dokument Documentation/BreakingChanges.adoc beschreibt die für 3.0 erwarteten Änderungen, allerdings mit dem Hinweis, dass es für diese Version noch kein geplantes Veröffentlichungsdatum gebe. Das hat sich mit den Diskussionen auf dem Summit geändert.

Zu den größten für Git 3.0 geplanten Änderungen gehören:

  • SHA-256 als Standardformat für Objekt-Hashes
  • reftable als Standardformat für die Speicherung von Referenzen
  • Rust als feste statt optionale Abhängigkeit

Der Code für diese Änderungen ist in aktuellen Git-Versionen bereits vorhanden. Im übrigen Git-Ökosystem, also in Git-Bibliotheken, Anwendungen und Hosting-Plattformen (Forges), ist die Unterstützung jedoch unterschiedlich weit. Fehlt sie, entsteht ein Schwebezustand: Einige Werkzeuge beherrschen die neuen Funktionen, andere scheitern daran.

Bei SHA-256 lag eines der größten Hindernisse bei den Forges. GitLab unterstützt SHA-256 seit rund einem Jahr. GitHub hat auf der Git Merge eine Private Beta angekündigt, und die allgemeine Verfügbarkeit soll in einigen Monaten folgen.

Vor diesem Hintergrund einigte sich der Summit auf folgenden Zeitplan für Git 3.0:

ReleaseZeitpunkt
2.56September 2026 (dieses Release)
2.98Dezember 2026
2.99 und 3.0Frühjahr 2027

Der Plan sieht vor, direkt von 2.56 auf 2.98 zu springen. Der große Versionssprung signalisiert Downstream-Maintainer(inne)n wie Nutzer(inne)n, dass eine größere Änderung bevorsteht. Danach erscheinen 2.99 und 3.0 gemeinsam. Der einzige Unterschied: In Git 3.0 ist das Feature-Flag für die Breaking Changes aktiviert. So bleiben 2.99 und 3.0 funktional gleich, und die Änderungen in 3.0 bleiben klein und überschaubar.

Version 2.99 wird ein LTS-Release, damit Plattformen ohne Rust-Toolchain weiterhin Updates erhalten. Die Details werden wie üblich auf der Mailingliste weiter diskutiert.

git-history(1) lernt drop

Im Beitrag zu Git 2.55 ging es um den Unterbefehl fixup von git-history(1). In diesem Release kommt der Unterbefehl drop hinzu.

Um einen bestehenden Commit zu löschen, führte der Weg bisher über git rebase -i: Im Editor wurden einzelne Commits interaktiv zum Entfernen markiert. Mit drop gelingt das in einer einzigen Zeile.

      $ git history drop <commit>

    

Der angegebene Commit wird entfernt, und seine Nachfolger werden per Rebase auf seinen Parent-Commit gesetzt. Wie bei den anderen Unterbefehlen von git-history(1) zeigen anschließend alle Branches, die vom ursprünglichen Commit abstammen, auf den neu geschriebenen Commit.

Dieser Patch stammt von Patrick Steinhardt.

git-branch(1) kann jetzt gemergte Branches löschen

Um gemergte Branches aufzuräumen, habe ich bisher meist eine Variante dieses Befehls verwendet:

      $ git branch --merged main | grep -v main | xargs git branch --delete

    

Er löscht allerdings nur Branches, die in den angegebenen Branch gemergt wurden. Branches, die von main abgezweigt und in origin/main gemergt wurden, erfasst er nicht. Dieses Release führt dafür zwei neue Flags ein.

Das erste ist --forked, ein Filter für die Branch-Liste. Er zeigt Branches, deren konfigurierter Upstream zur angegebenen Ref, zum Remote-Namen oder zum Branch passt.

      $ git switch --create feature-a origin/main
Switched to a new branch 'feature-a'
branch 'feature-a' set up to track 'origin/main'.

$ git branch --forked origin
  feature-a
  feature-b
* main

    

So wird sichtbar, welche Branches von einem bestimmten Integrations-Branch ausgegangen sind. Auch der Status jedes Branches lässt sich anzeigen:

      $ git branch -vv
  feature-a b3ebf58 [origin/main: behind 1] Add feature A
  feature-b 34c0403 [origin/main: ahead 1, behind 1] Add feature B
* main      230a3b0 [origin/main] Document the parser

    

feature-a liegt hinter origin/main und wurde also bereits in origin/main gemergt. feature-b steht dagegen noch aus. Hier setzt die neue Option --delete-merged an. Diese löscht alle Branches, deren Spitze von ihrem konfigurierten Upstream aus erreichbar ist, und entfernt damit jeden Feature-Branch, der bereits in den Integrations-Branch gemergt wurde.

      $ git branch --delete-merged origin
Deleted branch feature-a (was b3ebf58).

    

Tipp: Diese Optionen setzen voraus, dass die eigenen Branches einen Integrations-Branch tracken. Wer neue Branches üblicherweise vom lokalen Integrations-Branch abzweigt, findet in der Konfiguration von branch.autoSetupMerge die passende Einstellung inherit.

Dieses Feature hat Harald Nordgren eingereicht.

git-refs(1) kann jetzt Referenzen ändern

git-refs(1) kam mit Git 2.46 hinzu und ist seitdem die zentrale Anlaufstelle für Operationen rund um Referenzen. Der Befehl hat bereits mehrere Unterbefehle erhalten: um Referenzen zwischen Speicher-Backends zu migrieren, Konsistenzprüfungen durchzuführen, bestehende Referenzen aufzulisten oder zu prüfen, ob eine Referenz existiert. Mit diesem Release kann er Referenzen außerdem anlegen (create), löschen (delete), aktualisieren (update) und umbenennen (rename).

      $ git refs list
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/branch-d
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/branch-r
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/branch-u
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/main

$ git refs create refs/heads/branch-c main
$ git refs update refs/heads/branch-u main~1
$ git refs rename refs/heads/branch-r refs/heads/foo
$ git refs delete refs/heads/branch-d

$ git refs list
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/branch-c
c4e9b6bafb7ac9a96c5d9337cd60a0ec6d5a240d commit refs/heads/branch-u
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/foo
689f6e8164e070ed133d5176806ad69e31d22142 commit refs/heads/main

    

Die Unterbefehle update und delete akzeptieren zudem einen optionalen erwarteten alten Wert und prüfen ihn, bevor sie die Operation ausführen.

Diese Patches hat Patrick Steinhardt umgesetzt.

Google Summer of Code 2026

Mit diesem Release sind auch alle vier Projekte aus dem Google Summer of Code erfolgreich abgeschlossen. Jedes Projekt wurde von jemandem aus dem Engineering-Team von GitLab mitbetreut.

remote-object-info für git-cat-file(1)

In einem Partial Clone arbeitet ein Repository, ohne jedes Objekt herunterzuladen. Git lädt Objekte erst bei Bedarf nach. git-cat-file(1) kann zwar Objektinformationen zu einem Objekt-Hash lesen, überträgt dafür bisher aber das gesamte Objekt. Git 2.56 ergänzt den Modus --batch-command von git-cat-file(1) um den Befehl remote-object-info, der über Version 2 des Git-Protokolls nur die Metadaten abfragt. Ein Beispiel ist ein Blobless Clone, der überhaupt keine Blobs enthält:

      $ git rev-parse HEAD:model.weights
42ec5fc0f485f764cdf0eaa85ab061c055f5f518

$ git cat-file --batch-all-objects --batch-check | grep -c blob
0

$ echo "remote-object-info origin 42ec5fc0f485f764cdf0eaa85ab061c055f5f518" |
    git cat-file --batch-command
42ec5fc0f485f764cdf0eaa85ab061c055f5f518 blob 3000000

$ git cat-file --batch-all-objects --batch-check | grep -c blob
0

    

So lässt sich die Größe des Blobs ermitteln, ohne den Blob selbst zu übertragen. Im Beispiel entfallen damit 3 Millionen Byte Datenübertragung.

An dem Projekt arbeitete Pablo Sabater und setzte damit Vorarbeiten von Eric Ju und Calvin Wan fort. Mentoren waren Karthik Nayak und Chandra Pratap.

Freigabe von Speicherplatz in Partial Clones

Partial Clones sparen viel Speicherplatz, weil sie Blobs erst bei Bedarf nachladen. Mit der Zeit summieren sich diese Nachladevorgänge jedoch. Das Repository wächst, und der Vorteil geht verloren. Im Rahmen dieses GSoC-Projekts erhielt git-repack(1) die neue Option --drop-filtered. Diese findet große Promisor-Blobs oberhalb des angegebenen Filters und entfernt sie lokal.

Ein Beispiel ist ein gefilterter Clone eines Repositorys, dessen Historie einen Blob von 3 MB enthält. Direkt nach git clone ist das Repository klein, doch schon ein Blick auf den Blob lädt ihn auf die lokale Festplatte:

      $ du -sh .git
144K    .git

$ git cat-file -s b8086a678595c9fce29d980f7a12ca069b466f6c
3000000

$ du -sh .git
3.1M    .git

    

Obwohl der Blob im Arbeitsverzeichnis nicht gebraucht wird, bleibt er liegen. --drop-filtered entfernt ihn wieder, und Git kann ihn bei Bedarf später erneut nachladen.

      $ git repack -a -d --filter=blob:limit=1k --drop-filtered
$ du -sh .git
156K    .git

    

An dem Projekt arbeitete Siddharth Shrimali, betreut von Christian Couder und Siddharth Asthana.

Verbesserungen am neuen Befehl git repo

Der Befehl git-repo(1) liefert Informationen über das Repository. Im Rahmen des GSoC-Projekts erhielt der Unterbefehl git repo info die Schlüssel path.gitdir und path.commondir, jeweils als absolute und als relative Angabe.

      $ git repo info --all
layout.bare=false
layout.shallow=false
object.format=sha1
path.commondir.absolute=/home/karthik/code/git/.git
path.commondir.relative=.git
path.gitdir.absolute=/home/karthik/code/git/.git
path.gitdir.relative=.git
references.format=reftable

    

Weitere Patches mit zusätzlichen Pfadangaben liegen derzeit auf der Mailingliste.

An dem Projekt arbeitete K Jayatheerth, betreut von Justin Tobler und Lucas Seiki Oshiro.

Weniger globaler Zustand in Git

Der Kerncode von Git stützt sich noch stark auf globalen Zustand, von der bekannten Variable the_repository bis zu zahlreichen Konfigurationsoptionen. Das bremst die Bemühungen, Git als Bibliothek nutzbar zu machen (Libification). Das Projekt verschiebt einige globale Konfigurationsvariablen in die neue Struktur repo_config_values innerhalb von struct repository. Aufrufstellen übergeben struct repository nun explizit, statt auf das globale the_repository zuzugreifen.

An dem Projekt arbeitete Tian Yuchen, betreut von Christian Couder, Ayush Chandekar und Bello Caleb Olamide.

Linearisierte Historie mit git-replay(1)

git-replay(1) ist ein experimenteller Git-Befehl für Rebases auf dem Server, der kein Arbeitsverzeichnis benötigt:

      $ git log --oneline --graph --all
* 1756840 (main) main: unrelated upstream work
| * 286e7f1 (topic) topic: add two
| * 4324bcd topic: add one
|/
* 9497867 Initial commit

$ git replay --ref-action=print --onto main topic
update refs/heads/topic a144de2fc13ac40c8a481052be5e4d42071c4908 286e7f186f229ac4dd5ecb68a372951003f16224

$ git log --oneline --graph a144de2fc13ac40c8a481052be5e4d42071c4908
* a144de2 topic: add two
* 6422f37 topic: add one
* 1756840 (main) main: unrelated upstream work
* 9497867 Initial commit

    

Ein Problem gab es bisher: Mit Commit-Bereichen, die Merge-Commits enthalten, funktionierte der Befehl nicht. Ein Beispiel: In einem feature-Branch wird gearbeitet, und ein bugfix, der in main landet, wird auch in den Feature-Branch gemergt. Der feature-Branch enthält dadurch einen Merge-Commit:

      $ git log --graph --oneline --decorate --all
* cb996b6 (HEAD -> feature) feature: handle the empty-input edge case
*   4f76f3d Merge branch 'bugfix' into feature
|\
| * 4959734 (main, bugfix) bugfix: do not crash on null input
* | 829b62c feature: add parser tests
* | 7fd60db feature: add the parser
|/
* 9497867 Initial commit

$ git replay --onto main main..feature
fatal: replaying merge commits is not supported yet!

    

git-replay(1) verweigert den Rebase also wegen des Merge-Commits. Git 2.56 bringt dafür --linearize, vergleichbar mit der Option --no-rebase-merges, die bei git-rebase(1) bereits Standard ist.

      $ git replay --linearize --onto main main..feature
$ git log --graph --oneline --decorate --all
* da8df6e (HEAD -> feature) feature: handle the empty-input edge case
* f68889f feature: add parser tests
* f13885b feature: add the parser
* 4959734 (main, bugfix) bugfix: do not crash on null input
* 9497867 Initial commit

    

Dieses Feature hat Toon Claes eingereicht.

Weitere Schritte zu Pluggable Object Databases

Im Beitrag zu Git 2.54 ging es darum, was Pluggable Object Databases sind und wie sie funktionieren. Zur Erinnerung: Git speichert seine Objekte (Blobs, Trees und Commits) unter .git/objects in zwei Formaten. Loose Objects sind einzelne Dateien, Packfiles fassen mehrere Objekte komprimiert zusammen. Da es keine Abstraktionsschicht gab, griffen verschiedene Subsysteme direkt auf die Speicherebene zu. Mit 2.54 wurde diese Abstraktionsschicht schließlich eingeführt.

Dieses Release geht weitere Schritte, um in den Backends die Schnittstellen bereitzustellen, die sie wirklich austauschbar machen:

  • Anlegen der Datenstrukturen auf der Festplatte. Beim Initialisieren des Repositorys wird der Ordner .git/objects angelegt. Diese Aufgabe liegt jetzt bei den einzelnen Backends.
  • Konsistenzprüfungen. Die Konsistenzprüfungen aus git-fsck(1) sind in die Ebene der Objektquellen gewandert, sodass Backends eigene Prüfungen umsetzen können.
  • Housekeeping. Die Housekeeping-Logik des Files-Backends in git-gc(1) und git-maintenance(1) (inkrementelles Repacking, geometrisches Repacking und Pruning) wurde aus dem Befehl in die Files-Objektquelle verlagert.
  • Erzeugen von Packfiles. Beim Fetch und Push erzeugt Git als Teil des Protokolls Packfiles, indem es git-pack-objects(1) aufruft. Backends können Packfiles jetzt selbst bereitstellen.
  • Eigene Objektquellen. Nach dem Backend für Loose Objects im letzten Release hat jetzt auch das Backend für gepackte Objekte eine eigene Objektquelle.
  • Lese- und Schreib-Streams. Die getrennten Streams zum Lesen und Schreiben von Objekten sind jetzt in einer gemeinsamen struct odb_stream vereint, sodass sich beliebige Objekttypen streamen lassen.
  • ODB-Transaktionen. git-receive-pack(1) nutzt jetzt ODB-Transaktionen und schreibt Objekte damit über die Schnittstelle, ohne Annahmen über das Backend zu treffen.

Dazu kommt noch einiges mehr. So viele Änderungen dieses Release auch enthält: Aus Sicht der Nutzer(innen) bleibt alles beim Alten, und genau so ist es gewollt. GitLab erhält damit die Infrastruktur, um Git im großen Maßstab zu betreiben. Das Backend lässt sich bei Bedarf austauschen, und zwar im Rahmen der Git-Community. Weitere Details folgen.

Diese Änderungen haben Justin Tobler und Patrick Steinhardt gemeinsam eingereicht.

Weiterlesen

Dieser Artikel stellt nur einige der Neuerungen vor, zu denen GitLab und die Git-Community beigetragen haben. Mehr dazu steht in der offiziellen Release-Ankündigung des Git-Projekts. Die bisherigen Beiträge zu Git-Releases zeigen weitere Highlights aus der Arbeit des GitLab-Teams.

Feedback erwünscht

Hat dir dieser Blogbeitrag gefallen? Hast du Fragen oder Feedback? Erstelle ein neues Diskussionsthema im GitLab-Community-Forum und lass andere an deinen Eindrücken teilhaben.

Feedback teilen

Beginne noch heute, schneller zu entwickeln

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