Veröffentlicht am: 28. September 2026
11 Minuten Lesezeit
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:
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:
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:
| Release | Zeitpunkt |
|---|---|
| 2.56 | September 2026 (dieses Release) |
| 2.98 | Dezember 2026 |
| 2.99 und 3.0 | Frü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.
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.
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.autoSetupMergedie passende Einstellunginherit.
Dieses Feature hat Harald Nordgren eingereicht.
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.
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.
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.
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.
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.
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.
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.
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:
.git/objects angelegt. Diese Aufgabe liegt jetzt bei den einzelnen Backends.struct odb_stream vereint, sodass sich beliebige Objekttypen streamen lassen.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.
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.
Kostenlose 30-tägige
GitLab-Testversion starten
Keine Kreditkarte erforderlich.
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 teilenBeginne noch heute, schneller zu entwickeln
Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.