# Git 3.0 Roadmap: RevTables, SHA-256 Migration, and Native Binary Support

**Podcast:** Engineering Kiosk
**Published:** 2026-03-31

## Transcript

Willkommen zu einer neuen Episode vom Engineering Cures Podcast.
Heute geht es um ein Tool, das wir alle täglich benutzen und gleichzeitig oft nur an der Oberfläche verstehen.
Git.
Git Commit, Push, Pull.
Fertig.
Oder?
Oder eben doch nicht.
Denn hinter den paar Befehlen, die im Alltag gefühlt automatisch aus den Fingern fallen, steckt ein ziemlich tiefes System mit jeder Menge Historie, Architekturentscheidungen und spannenden Baustellen für die Zukunft.
Dafür haben wir uns jemanden eingeladen, der nicht nur Git benutzt, sondern direkt daran mitarbeitet.
Patrick Steinhardt ist Git Maintainer, Contributor zu LibGit 2 und arbeitet im Git Team bei GitLab.
Mit ihm sprechen wir darüber, was auf der Serverseite eigentlich passiert, wenn du clonst, fetch oder pusht und warum große Repositories, Binärdateien und Millionen von Referenzen echte Herausforderungen sind.
Außerdem schauen wir auf die Zukunft von Git.
Es geht um Git 3.0, den Wechsel von Char 1 zu Char 265, RevTables und Large Object Promises.
Wenn du also dachtest, du kennst Git, weil du die sechs Befehle auswendig kannst, dann kommt jetzt der Reality Check.
Los geht's.
Lieber Wolfgang, wie viel CVS zu Subversion Migrationen hast du bereits in deinem Leben durchgeführt?
Du beleidigst mir allgemein sehr gerne, aber so alt, dass ihr jetzt schon Migrationen zu SVN durchgeführt habt.
Also ich war natürlich immer cool und hip und hab schon mit SVN gestaltet.
Das hat nichts mit Beleidigung zu tun.
Ich habe schon, ich glaube, als ich angefangen habe, also im Azubi-Bereich Fachinformatiker, Anwendungsentwicklung, nennt sich das ja in Deutschland zu gut Deutsch programmiere, habe ich, glaube ich, sechs CVS zu Subversion-Migration gemacht.
Dann die nächste Frage, wie viel SVN zu Git-Migrationen hast du gemacht?
Ich habe keine Strickelliste da mitgeführt, aber es waren auf jeden Fall einige.
CVS habe ich natürlich schon auch verwenden müssen.
Man muss ja hin und wieder mit Legacy-Systemen arbeiten.
Aber es dürften schon mehr gewesen sein, als jetzt Finger an meinen Händen habe, würde ich mal sagen.
Und jetzt die letzte Frage, bevor wir jetzt zum eigentlichen Thema kommen.
Was denkst du, ist der Hauptgrund, warum im heutigen Entwickleralltag Git über Subversion gewonnen hat?
Gewonnen in Airquots, was auch immer gewonnen jetzt heißt.
Also für mich war eigentlich der Hauptgrund, dass es einfach im Alltag wesentlich besser funktioniert hat.
Also dieses ganze Merchen und wirklich Arbeiten im Team, das hat sich einfach viel flüssiger angefühlt mit Git als mit SVN.
Das war in SVN immer eine Katastrophe, da irgendwie in einem Branch überhaupt zu machen oder irgendwas dann wieder rein zu migrieren.
Das war alles Katastrophe und hat irgendwie nie funktioniert.
Hat sich einfach automatisch immer viel besser angefühlt.
Ja, da frage ich mich natürlich gerade, ist das jetzt gerade so eine Art aktueller Zeitbias bei dir?
Weil Branching in Subversion war ja möglich, aber ich hatte immer das Gefühl, erst als Git, ich sag mal, populärer wurde, hat jeder gesagt, ah, Branching als First Class Citizen, wo bei Subversion ja eher Branching dran geklatscht wurde.
Aber wie dem auch sei.
Ja, wie gesagt, das war eigentlich das Arbeiten im Team.
Das war das Problem.
Es hat einfach immer Probleme gegeben bei SVN.
Und das war eigentlich dann der große Unterschied.
Der Hebel, der mir dann auch gezeigt hat, okay, Git funktioniert einfach im Team wesentlich besser.
Und wie kam ich auf diese Frage?
Diese Frage habe ich mir auch erst auf dem Rückweg von der FOSTEM-Konferenz gestellt, nachdem ich nämlich einen Talk von Patrick Steinhard zum Thema Evolving Git for the Next Decade gesehen habe.
Und da hat er mir ins Gedächtnis gerufen, dass Git ja auch schon 20 Jahre alt ist.
Und dann saß ich in diesem Vortrag und habe dem Patrick zugehört.
Dann haben wir so: Moment, der Akzent, der klingt so deutsch.
Wir machen doch einen deutschsprachigen Podcast.
Steht da vielleicht der nächste Podcastgast.
Und ich bin sehr, sehr froh, dass ich diese Frage jetzt mit Ja beantworten kann.
Deswegen herzlich willkommen, Patrick Steinhardt.
Ja, vielen Dank, dass ich heute Teil des Podcasts sein darf.
Fun Fact, was die Leute an der Audiobox gerade nicht sehen, der Patrick hat ein Subversion-T-Shirt on.
Kommt tatsächlich von einiger Zeit her, weil, wie ihr auch schon gesagt hatte, Subversion ist ja mittlerweile schon ein bisschen älter.
Aber bei einem meiner ersten Jobs hatte ich tatsächlich auch an einem Subversion-Hackathon teilgenommen, weil mein Arbeitgeber damals generell in allen möglichen Open Source Open Source Version Control Systemen unterwegs war.
Und Subversion war eins davon.
Und daher habe ich noch das T-Shirt und trage es auch immer noch gerne mit Stolz.
Kann ich verstehen.
Ich fand Subversion auch immer ein super Versionskontrollsystem und ich habe nie so ein Hass geschürt zu Branching in Subversion, wie der Wolfgang erst gerade hat.
Denn ich denke, es hat einigermaßen gut funktioniert, aber ich bin ehrlich, es hatte Quirks und man musste genau wissen, was man da tut.
Man musste definitiv wissen, was man tut.
Und ich würde auch nicht sagen, dass ich damals ein Fan von Subversion war.
Das Einzige, was ich an Subversion mochte, ist der Code tatsächlich, weil der deutlich besser geschrieben ist als Git.
Aber ich kann nur unterschreiben, dass gerade das Branching-Modell wirklich ein extremer Painpoint in Subversion war.
Ich kann mich noch gut erinnern, das war mein allererster Job.
Und da hatten wir einfach teilweise zwei Wochen lang Produktionsstopp bei jemand mergen musste.
Und das ist so extrem schmerzhaft und diese Probleme gibt es halt einfach mit Git so in dem gerade nicht mehr.
Jetzt kann es natürlich sein, dass der ein oder andere, der diesem Podcast gerade hört, dich nicht kennt.
Deswegen stelle ich dich einmal ganz kurz vor.
Und sage, warum du eigentlich qualifiziert bist, über Git zu sprechen.
Du kommst aus der Hauptstadt Deutschlands, nicht Österreich.
Du wohnst in Berlin.
Du bist seit 2015 Contributor und Maintainer zu Git selbst und zu LibGit2.
Aktuell verdienst du dein Geld als Safengineer und Engineering Manager im Git-Team bei GitLab selbst.
Und in letzter Zeit, besonders wenn man mal dein Namen bei YouTube eingibt, sprichst du sehr viel über die Themen Rev-Tables, File-Backends, beziehungsweise von Unterstützung von großen Files in Git.
Und das war auch unter anderem dein Thema oder ein Subthema von einem Talk auf der FOSDEM.
Und du sagtest gerade schon, du mochtest den Code von Subversion lieber als der von Git.
Ich meine, dass den Bereich Modernisierung von Git, ich hatte ja auch gerade gesagt, Git ist 20 Jahre alt, haben wir auf der Agenda.
Da bin ich mal gespannt, was da gleich noch so rumkommt.
Da gibt es definitiv einige Sachen, die sehr überarbeitungswürdig sind.
Darüber kann man wahrscheinlich alleine schon einen halben Tag reden.
Hast du gerade geglaubt, irgendwas ist kaputt?
Ja.
Siehst du, so geht's mir auch oft.
Und dann brauche ich unbedingt einen Kaffee.
Oder wie der Andi sagen würde, einen Kaffee.
Und für diese Koffeinenergie, die ihr uns durch diese Kaffee-Spenden bereitstellt und die es uns eigentlich erst ermöglichen, diese Episoden zu produzieren, möchten wir uns einmal bedanken.
Und zwar bei den letzten Spendern.
Daniel, Jakob, Peter, Alfred, Florian, Michel, Dimo, David, Lukas, Adrian, Nico, Matthias, Wolfgang, by the way, schöner Name.
Elias, Björn, Franco, Dominik, Paul und Fabian.
Und egal, ob ihr uns einen Kaffee sponsert oder vielleicht sogar ein Kaffee-Abo wieder Fabian oder einen ganzen Monatsbedarf an Kaffee wieder David, wir schätzen jeden einzelnen Kaffee und freuen uns wirklich über dieses ganze Koffein-Feedback.
Vielen Dank von Andi und von mir und jetzt geht es auch schon wieder zurück zur Episode.
Git ist ja doch schon jetzt einige Jahre alt und eigentlich komplexer als man das so denkt, weil im Alltag verwendet man das irgendwie so commit, push-pull, so die drei Standard-Befehle.
Ich hatte jetzt gerade das Vergnügen, mal auf der Universität Studierenden Git beizubringen und da habe ich erst wieder gemerkt, wie komplex eigentlich diese Grundlagen sind.
Wenn man sie so tagtäglich verwendet, ist das ja total easy und alles verständlich, aber sogar die Grundlagen sind schon schwierig, wirklich mal zu vermitteln.
Da steckt doch einiges dahinter.
Aber wenn wir jetzt noch eine Stufe weitergehen, was wäre denn ein cooles Feature, wo du sagst, die meisten Developer, die verwenden Push-Bull-Commit, aber das wäre ein cooles Feature.
Das sollte sich mal jeder mal irgendwie anschauen oder zumindest die Doku durchlesen, weil man könnte eigentlich noch viel mehr machen.
So ein cooler Tipp schon zu Beginn der Episode.
Das ist tatsächlich eine super Frage, muss ich sagen, weil ich habe natürlich einen extremen Bias.
Darum haben wir dich hier eingeladen.
Die Frage, oder das Problem ist quasi, dass ich gar nicht so wirklich einschätzen kann, was benutzt denn der Durchschnittsnutzer täglich.
Ich würde sagen, dass eines der wichtigsten Features von Git, dass ein bisschen fortschrittlicher ist, Interactive Rebases sind.
Einfach, weil du damit deine Historie relativ frei gestalten kannst, schön machen kannst, Commit-Messages nochmal überarbeiten kannst, oder einfach ein Commit beispielsweise aufsplitten kannst in zwei Commits.
Und das ist meiner Meinung nach eines der wichtigsten Features in Git, dass ich auch jeden Tag Dutzende Male benutze.
Ich würde auf jeden Fall jedem empfehlen, mit Interactive Rebases wirklich ein bisschen warm zu werden und die regelmäßig zu benutzen.
Ich benutze es öfters mal, aber immer wenn ich es benutze, muss ich auch immer nachgucken, okay, diese einzelnen Buchstaben, die ich im Interactive Rebase da eingeben muss.
Was heißt noch was?
Und zum Glück zeigt ihr das ja unten an.
Jetzt zwei Commit mergen möchte, wo muss ich das nochmal hinsetzt?
Das ist halt schon.
Also die UI ist ja ein bisschen tricky.
Ich muss mich jedes Mal nur dran erinnern.
Was?
Ist Squash nach oben oder nach unten oder so, diese Dinge, ja, kenne ich Andi.
Kann ich definitiv bestätigen und ich kann ja auch schon mal ein bisschen spoilern.
Das ist tatsächlich auch eine Sache, an der ich gerade arbeite, mit einem neuen Git-Kommando, das heißt Git History.
Und Git History ist genau dafür quasi, Interactive Rebases zugänglicher zu machen.
Ich hatte auch als Teil meines Post-Tem-Talks darüber geredet, dass relativ einfache Sachen deutlich zu kompliziert sind.
Wie beispielsweise ein Commit in zwei aufsplitten.
Ich weiß, wie das geht.
Ich weiß, wie man das gut mit einem Interactive Rebase macht.
Aber insgesamt sind das, ich glaube, das sind so sieben bis zehn Schritte, die du wirklich machen musst mit unterschiedlichen Git-Kommandos und auch mit unterschiedlichen Flags, die erstmal relativ scary wirken, würde ich sagen.
Und da ist wirklich die Idee, dass man einem beispielsweise sagt, Git History split.
Man gibt einfach den Commit, der aufgesplittet werden soll, kriegt man ein Editor, der zweimal nach den Commit-Messages fragt und fertig ist.
Das heißt, ja, es gibt definitiv Usability-Probleme, aber ich möchte die auch gerne beheben und das ganze Problem ein bisschen einfacher machen, sodass auch normale Leute quasi die Historie neu schreiben können.
Eins meiner Features, die ich wirklich jeden Tag nutze, ist Git add-p, also git add-patch.
Weil du kennst das.
Du hast eine Datei, du fährst dann da durch, editierst ein paar Sachen und dann siehst du da oben diesen einen Typo.
Diesen einen Typo oder was auch immer, diese eine kleine Sache, die du eben mitfixt.
Natürlich kannst du jetzt wieder zurückgehen, ein Commit machen, einen neuen Branch aufmachen, bla bla bla.
Aber ich editiere das einfach durch und wenn ich dann committen möchte, suche ich mir aus, welche Hunks ich denn da mit in den nächsten Commit nehme.
Also das nutze ich wirklich jeden Tag.
Ich weiß gar nicht, wie Leute ohne das können.
Kann ich dir auch definitiv beipflichten und das ist auch ein weiteres Unterkommando, was ich irgendwann in GitHistory noch nachziehen möchte, ist GitHistory Absorb.
Weil das ist nämlich genau der Nutzungsfall hier.
Du hast quasi eine Typo gehabt und der soll automatisch quasi dann nochmal in dem alten Commit behoben werden.
Das heißt, die Idee ist dahinter, dass man einfach sagt, Git History Absorb.
Und der nimmt da quasi alle lokalen Hunks oder alle lokalen Änderungen und guckt, wann wurde diese Zeile das letzte Mal geändert und wird dann quasi automatisch die Änderungen an diesen Commit mit ranflanschen.
Was auch durch andere Versionskontrolltrollsysteme wie beispielsweise Mercurial inspiriert ist.
Also, ich erfinde jetzt hier keine neuen Sachen, aber ich versuche quasi von anderen Versionskontrollsystemen auch ein bisschen zu lernen.
Gut, aber man muss ja nicht mal alles neu erfinden, ich meine, gut kopiert, ne?
Also ist ja auch aus so eine Suche.
Lass uns mal ein bisschen über Git sprechen.
Selbst tun wir natürlich, aber wenn du bis ja beruflich mehr auf der Serverseite von Git unterwegs und nicht auf der Client-Seite.
Jetzt spreche man natürlich mit Interactive Rebase und Git Add-Patch und GitHistory Absorb natürlich über Client-Seite-Features.
Aber mich würde mal interessieren, was sind denn aus deiner Sicht die wesentlichen Unterschiede von einem Git-Repository auf der Client-Seite und auf der Serverseite.
Es kommt sehr stark auf den einzelnen Server drauf an.
Das Wesentliche ist nämlich, dass auf der Serverseite haben wir deutlich mehr Freiheiten in der Art und Weise, wie wir unsere Git-Repositories quasi strukturieren.
Das heißt, es kann zwar genauso aussehen wie ein clientseitiges Repository.
Es muss aber nicht.
Wir können quasi komplett unser eigenes Ding machen, weil das einzige, was wirklich denn stimmen muss, ist das Protokoll, das zwischen der Serverseite und der Client-Seite gesprochen wird.
Das heißt, je nachdem, wie der Server aufgebaut ist, kann es ziemlich ähnlich aussehen.
Es kann aber auch wirklich komplett anders aussehen.
Im simpelsten Fall, wie das beispielsweise bei GitLab ist, in meiner Meinung oder meines Wissens nach auch bei GitHub, ist der wesentliche Unterschied, dass wir auf der Serverseite mit Bare-Repositories arbeiten.
Das heißt, in einem Repository, das kein Work Tree hat, also die ganzen Dateien quasi, die in deinen Commits drin stecken, die sind nirgendwo auf der Festplatte zu sehen, sondern wir haben wirklich nur die einzelnen Objektstrukturen von Git selber.
Das heißt, die Objekte, die Referenzen und noch ein paar Metadaten.
Du sagtest gerade, die können je nach Server unterschiedlich aussehen.
Kannst du das mal ein bisschen beleuchten?
Was heißt das unterschiedlich?
Bedeutet dann, dass die Struktur vom Bare-Repository auch komplett anders auf der Festplatte abgelegt wird oder andere Datenstrukturen oder worüber reden wir hier gerade, wenn wir sagen, die können anders aussehen?
Naja, prinzipiell muss es quasi das Git Repository an sich gar nicht erst geben.
Weil, wie gesagt, das Einzige, was wirklich stimmen muss, ist das Protokoll, was zwischen der Serverseite und der Client-Seite gesprochen wird.
Das heißt, ich weiß von anderen Firmen, die gar nicht erst einen Git Repository lokal rumzufliegen haben auf der Serverseite.
Sondern die haben wirklich ihre komplett eigene Logik, um die Daten quasi an den Client übertragen zu können.
Dementsprechend hast du quasi kein echtes Git-Repository, auf dem du mit einem normalen Git-Client arbeiten könntest.
Könnte dann beispielsweise so aussehen, dass man beispielsweise die Objekte alle in einem in einer verteilten Datenbank oder sowas zu stehen hat.
Der Client wird davon nichts mitbekommen, aber für den Server kann es unter Umständen deutlich effizienter sein, das so zu implementieren.
Und da ist quasi der Kreativität ziemlich viel Freiraum gegeben.
Und wenn du jetzt sagst, kein Work-Tree, das heißt aber, man kann den kompletten Source-Code über die Git-Objekte auch wieder herstellen sozusagen.
Das heißt, wenn ich jetzt auf den Download-Button drücke, dann wird es wirklich aus den Git-Objekten dann zusammengebaut oder wiederhergestellt, also wirklich ohne Work-Tree.
Korrekt.
Es gibt hier zwei wesentliche Datenstrukturen, die für die Client-Seite dann eigentlich wirklich von Relevanz sind.
Das sind einerseits die Referenzen.
Referenzen sind quasi einfach bestimmte Namen, die man einzelnen Objekten geben kann, um die Objekte relativ leicht wiederfinden zu können.
Und für den Client, um dann den Work-Tree wiederherstellen zu können, ist dann von wesentlicher Relevanz eigentlich nur das Commit-Objekt.
Und von dem Commit-Objekt hat man dann quasi die komplette Historie des Repositories, das dadurch auch gespannt wird.
Weil ein Commit-Objekt referenziert erstmal andere Commit-Objekte, das ist dann quasi deine Repository-History.
Und zusätzlich hat ein Commit-Objekt noch eine Referenz auf einen sogenannten Root-Tree.
Und dieser Tree ist dann die gesamte Dateistruktur, die du in deinem Repository eigentlich hast.
Und das ist dann das, was der Git-Client quasi benutzt, um den Work-Tree wiederherstellen zu können.
Aber das bedeutet, wenn ich jetzt einen Bare-Repository habe und dann nur mit den Commit-Objekten da agiere und damit gar nicht den aktuellen Stand der Dateien auf der Platte liegen habe.
Ich mache das jetzt einfach nur mal einfach.
Erst nicht in einer verteilten Datenbank oder sowas.
Dann würde das ja bedeuten, dass wenn ich den File-Tree wiederherstellen möchte, dass ich einfach von komplett Git-Commit 1 bis Git Commit-Head komplett replayen muss, oder?
Tatsächlich nicht.
Es gibt Versionskontrollsysteme, bei denen ist das so.
Ich glaube, Pijoule beispielsweise ist ein so ein Versionskontrollsystem, wo das genauso funktioniert.
Git ist aber anders aufgebaut, weil Git ist Snapshot-basiert.
Das heißt, jeder Commit referenziert quasi den kompletten Tree von allen Dateien, die existieren innerhalb dieses Repositories.
Das heißt, eigentlich brauchst du nur den einen Commit und den Root-Tree davon und dann weißt du sofort, was alle Dateien sind, die in dem Work-Tree ausgecheckt werden müssten.
Gibt es auf der Server-Seite Befehle, die eigentlich nur auf der Serverseite verwendet werden oder ist das eigentlich alles, was du im Client brauchst, brauchst du auch am Server oder umgekehrt.
Viele von den Befehlen, die du auf der Client-Seite benutzt, wirst du auch auf der Serverseite benutzen, aber es gibt schon wesentliche Unterschiede.
Es gibt auf jeden Fall ein paar Befehle, die wirklich nur auf der Serverseite von relevant sind.
Und die wichtigsten sind hier einerseits GitUpload-Pack, andererseits Git Receive-Pack.
GitUpload-Pack ist quasi für den Fall zuständig, wo der Client ein Fetch macht.
Das heißt, der Client möchte jetzt alle Dateien von der Serverseite bekommen oder alle Objekte von der Server-Seite bekommen.
Das heißt, der Client führt GitFetch aus.
Das wird dann an den Server geroutet und der Server wird dann Git Upload-Pack ausführen, wobei GitUpload-Pack dann dafür zuständig ist, zu gucken, welche Objekte benötigt der Client denn jetzt gerade in seiner momentanen Anfrage.
Und ausgehend davon wird er dann alle Objekte erstmal enumerieren, die benötigt werden.
Daraus dann eine Pack-File generieren.
Und diese Pack-File wird dann zurück an den Client gesendet, sodass der Client dann alle Objekte zur Verfügung hat und danach dann quasi seine Referenzen updaten kann und dann potenziell vielleicht auch noch den Work-Tree updatet.
Das ist GitUpload-Pack.
Git Receive-Pack ist dann quasi die andere Seite.
Der Client macht einen Push, wird dementsprechend dann alle seine Objekte, die der Server benötigt, lokal erstmal packen in eine Pack-File.
Die Pack-File wird rübergeschickt.
Die empfängt dann der Server über Git Receive-Pack und Git Receive-Pack guckt dann sich quasi erstmal die Pack-File an, guckt, sind alle Objekte, die mir der Client gesendet hat, konsistent oder gibt es irgendwelche Fehler beispielsweise in den Objekten.
Habe ich alle Objekte, die ich wirklich brauche, um auch meine Referenzen updaten zu können.
Und wenn das der Fall ist, dann wird der Server quasi die Änderungen committen und danach dann in den Git Repository persistieren, sodass andere Clients darauf zugreifen können.
Jetzt liest man immer mal wieder, dass große Repositories oder dass einige Repositories Herausforderungen beim GitHosting machen, nennen wir es mal.
Auf der Serverseite.
Zumindest dass das Git-Repository-Serverseite zur Verfügung zu stellen.
Ist da die Größe die einzige Herausforderung?
Also ich sag mal, File-Size oder Anzahl Commits oder gibt es da noch irgendwelche anderen Herausforderungen, die beim Git Server-Hosting eine Rolle spielen, weiß ich nicht, irgendwelche Operationen, die unglaublich viel CPU fressen, weil sie linear oder exponentiell mit der Größe skalieren und deswegen länger dauern oder oder oder.
Die Antwort ist prinzipiell erstmal, es ist kompliziert, muss ich sagen.
It depends.
It depends, richtig.
Die wesentliche Sache ist, es gibt nicht ein Skalierungsfaktor in Git Repositories.
Es gibt viele verschiedene Faktoren, die mit reinspielen, wie teuer es ist, ein gewisses Git Repository an den Clients zu serven, beziehungsweise das generell hosten zu können.
Einerseits ist natürlich die Dateigröße auf jeden Fall ein wesentlicher Faktor, also wie groß sind die einzelnen Blobs, die ich innerhalb meines Repositories habe.
Es kann wirklich massive Probleme verursachen, wenn man viele Blobs hat, die beispielsweise Gigabytes groß sind.
Weil ein Blob der Gigabyte groß ist, wird natürlich auch dementsprechend so in den Git Repository gespeichert werden müssen.
Was in einige Probleme, beispielsweise, wenn es um Repository Maintenance geht, führen wird.
Aber es gibt auch andere Probleme, die wir hier haben, beispielsweise, wie viel Historie gibt es insgesamt, wie viele Commits existieren in dem Repository.
Weil man jedes Mal, wenn beispielsweise der Client rankommt, den kompletten Tree einmal ablaufen muss, um zu gucken, welche Objekte braucht der Client überhaupt.
Klar, dafür gibt es Optimierungen, die wir natürlich auf der Serverseite benutzen, aber je größer die, oder je tiefer die Commit-Historie wird, desto mehr Probleme können wir hier auch bekommen.
Dann gibt es aber auch andere Probleme, wie beispielsweise, wie groß ist dein maximaler Tree, also wie groß ist dein maximales, ich sag mal, Verzeichnis quasi.
Wie viele Blobs hast du in einem Verzeichnis drin?
Sind es Millionen oder sind es nur ein paar Dutzend?
Das sind dann erstmal so die Probleme, die wir vor allem mit den Git-Datenstrukturen haben.
Und wo es immer keine wirkliche Antwort gibt, wird dein Repository jetzt funktionieren oder nicht, wenn du mir nur einfach eine Metrik gibt, sondern eigentlich brauchen wir quasi Zugriff auf die komplette Repository-Struktur, um zu sagen können, wird es wahrscheinlich funktionieren oder wird es wahrscheinlich nicht funktionieren.
Die zweite Seite, neben den Datenstrukturen, die wesentlich noch mit reinspielt, ist natürlich auch der Workflow, beziehungsweise die Use Cases, die der Kunde hat.
Je nachdem, wie oft beispielsweise auf einem Repository zugegriffen werden kann, werden wir unterschiedliche Probleme haben.
Das heißt, wenn jetzt das Repository zwar relativ unhandlich ist, aber wir wissen, dass nur einmal alle fünf Minuten beispielsweise ein Clone passieren wird, naja, dann werden wir damit schon umgehen können.
Aber andererseits, wenn wir ein Repository haben, das relativ groß ist und in einer Sekunde hundertmal gekloned wird, dann sieht das schon wieder ganz anders aus.
Aber das heißt, so ein Clone bedeutet schon viel mehr am Server, als jetzt nur ein ganz dummes Download.
Weil sonst wäre ja das relativ einfach abzufrühstücken.
Richtig, das ist definitiv deutlich komplizierter als einen Download.
Denn ich kann ja mal so ein bisschen runterbrechen, was eigentlich passiert.
Der Client wird erstmal an den Server rantreten und sagen, hey, ich möchte ein Fetch machen.
Das heißt, was er aufrufen wird, ist Git Upload-Pack auf der Serverseite.
Denn Git Upload-Pack ist dafür da, quasi die Pack-File zu generieren, die der Client benötigt, um seine bestimmte Anfrage erstmal beantworten zu können.
Wir wollen aber natürlich, dass nicht einfach nur die Objekte rüberschubsen oder dem Client einfach sagen, du kannst über HTTP direkt auf alle unsere Objekte zugreifen.
Sondern was stattdessen passiert, zumindest im modernen Git mit dem Smart-Protocol, ist, dass erstmal eine Pack-File-Negotiation passiert.
Das heißt, der Client sagt der Server-Seite, welche Objekte sind für mich überhaupt von Interesse.
Das heißt, der Server wird erstmal sagen, das sind alle meine Referenzen, die ich momentan habe, mit bestimmten Objekten, auf die die Referenzen zeigen.
Und dann wird der Client aussuchen, welche Referenzen davon er haben möchte, schickt das an den Server und schickt zusätzlich nochmal an den Server, welche Objekte der Client auch schon unter Umständen hat.
Bei einem Clone hat er natürlich erstmal gar keine Objekte.
Dementsprechend ist es da relativ einfach.
Aber wenn man beispielsweise einen Fetch haben möchte, wird der Client auch schicken, guck mal, das sind alle meine Referenzen, die ich habe und das sind die Objekte, zu denen diese Referenzen hinzeigen.
Und generieren wir mal bitte quasi eine Pack-File, die einfach nur der Div ist zwischen den Referenzen, die oder den Objekten, die ich schon habe und den Objekten, die ich haben möchte.
Und dann wird dann der Server dynamisch dann das Pack-File generieren und mit der minimalen Anzahl an Objekten, die der Client eigentlich nur benötigt.
Das heißt aber, du sprichst jetzt schon in einem späteren Schritt, wenn ich lokal Informationen schon liegen habe, dass sie eben nur in irgendeiner Form die richtigen dann herunterladen.
Bei einem klassischen Klon wird ja mal zuerst alles kopiert, oder?
Also da fließt ja dann mehr oder weniger alles zum Client.
Jein.
Es kommt auch nochmal sehr stark darauf an, wie man genau den Clone durchführen möchte.
Git hat da ja auch viele verschiedene Möglichkeiten, wie du den Clone durchführen kannst.
Du kannst beispielsweise sagen, ich möchte ein Shallow Clone haben, wo ich nur Historie bis Commit X runterladen möchte.
Ich kann aber auch sagen, ich möchte einen Partial Clone haben, wo ich beispielsweise alle Objekte klone, bis auf Blobs, die größer als einen Gigabyte groß sind, sodass die dann erst on dem Mann später heruntergeladen werden.
Zusätzlich dazu hat man aber natürlich auch nochmal den Fall, dass auf der Serverseite unter Umständen Objekte in den Repositories existieren, die der Client niemals haben möchte, weil die beispielsweise von den öffentlich sichtbaren Referenzen in dem Repository gar nicht erst erreichbar sind.
Weil wir beispielsweise Metadaten innerhalb des Repositories speichern, die für den Client nicht unter Umbeständen nicht relevant sind, die wir aber benötigen innerhalb des Repositories.
Dementsprechend passiert auch schon bei einem Clone in der Regel erstmal diese Packfile-Negotiation, wo wir gucken, der Client möchte diese Referenzen, hat zusätzlich noch diese Parameter gesetzt, also gucken wir, welche Objekte wir dann schicken müssen.
Das sind in der Regel nicht alle.
Ihr wollt ja jetzt nicht schon wieder so als Line-User dastehen von Git und ich habe mir gedacht, bei Klonen kann ich vielleicht Klonen kenne ich, das kann nur ein Befehl sein.
Aber sogar da gibt es irgendwie durch schon so viele Parameter jetzt wieder besprochen, die ich noch nie in meinem Leben gehört habe.
Also es ist wirklich so ein Rabbit-Hole, Git kommt mir immer wieder vor.
Man kann so tief gehen und findet irgendwie auch nach 15 Jahren Verwendung immer noch jeden Tag fast neue Befehle.
Ich verwende Git seit bestimmt auch ungefähr 15 Jahren.
Ich bin seit 10 Jahren Entwickler im Git-Ökosystem.
Ich würde behaupten, dass ich trotzdem noch jeden fünften Tag bestimmt einen neuen Command-Line-Switch kennenlerne, den ich vorher noch nie in meinem Leben gesehen habe, weil jeder einzelne Befehl in Git wirklich Dutzende, teilweise hunderte von Optionen hat.
Und ich glaube, man hat gar nicht die Möglichkeit, alles zu kennen.
Aber nur nochmal zur Einordnung, wir sprechen jetzt immer von Git, was Git an sich unterstützt.
Also wir sprechen nicht von GitLab, GitHub oder sonstigen Dinge.
Die ganzen Sachen sind standardmäßig in Git dabei und würden auch funktionieren, wenn ich jetzt mein Git einfach auf dem Server self-hosted irgendwo hinlegt, einfach Git Binary und dann kann ich über SSH bereits so kommunizieren und klonen und alle Befehle durchführen, die du jetzt genannt hast.
Genau.
Weil ja viele immer glauben, die sind irgendwelche Features, die dann eben von GitLab, GitHub und so weiter kommen, sondern das sind wirklich alles Core, Git Features und so wurde ja Git auch, ich glaube früher, keine Ahnung, kannst du wahrscheinlich besser beantworten, ob das heutzutage noch irgendwo so genutzt wird, dass man einfach irgendwo Git liegen hat und dann sich bei SSH connected.
Das wird auf jeden Fall noch so benutzt.
Ich glaube, wo das vor allem noch wirklich von Relevanz ist, ist im privaten Setup sehr viel.
Ich hatte selber jahrelang einfach nur einen Server gehabt, einen Git-Server gehabt, wo die Git Binaries einfach rumlagen und ich dann über SSH einfach angegangen bin, weil ich ansonsten auch nicht wirklich viel weiter benötigte für meine persönlichen Anwendungsfälle.
Aber auch bei Forges ist das mit einigen zusätzlichen Komplexitäten natürlich, die existieren.
Im Großen und Ganzen aber immer noch so der Fall.
Bilderbuchüberleitung zum nächsten Thema.
Und zwar habe ich mit Git immer ein Gedankenproblem.
Und zwar Beef solltest du sagen.
Mit Git habe ich nicht Beef, ne?
Das ist jetzt nicht.
Das ist nur ein Problem mit deinem Kopf.
Wenn Git und ich Probleme hätten.
Also wir haben auch Probleme zwischen unserer Beziehung.
Aber ich meinte eigentlich eher dieses Konzept von Git und dezentral.
Wir haben die ganzen Podcast hier mit Subversion gestartet.
Problemstatement, was ich jetzt aufmache, ist ähnlich wie Subversion.
Bei Subversion konnte man ja keinen einzigen Commit machen, ohne eine Konnectivität zum Server.
Also jeder Commit braucht eine Konnektivität zum Server.
Git hat das ja nicht.
Du kannst ein Git Commit machen, alles gut.
Aber irgendwie haben wir uns von den fundamentalen, ich würde mal sagen, Features von Git so ein bisschen wegbewegt.
So habe ich zumindest das Gefühl.
Wir hatten gerade geklärt, Wolfgang, du kannst ein Repository bei dir auf der Festplatte haben, du kannst mir irgendwie ein Netzwerk HTTP oder SSH-Konnektivität geben und ich kann von meiner Festplatte auf deine Festplatte pushen.
Das geht ja noch.
Aber irgendwie haben wir uns alle darauf geeinigt, dass wir einen zentralen Server haben, sei es mein lokal gehostetes GitLab oder irgendwie was in einem Software as a Service oder ist ja egal was oder ein Open Code.
Open Code, sag ich schon.
Wie heißt denn diese Plattform von Deutschland da?
Naja, ist ja auch egal.
Irgendwo ein Git-Server wird gehostet.
Und das nutzen wir als zentrales Repository.
Ihr kennt auch diese Comics.
Was machen die Entwickler da?
GitHub ist down.
Und dann kann ich gerade nicht arbeiten.
Und da sagt dann jeder, okay, obwohl es ja eigentlich totaler Blödsinn ist, weil wir haben ja alle eine komplette Kopie, also wie wir gerade gelernt haben, nicht eine komplette Kopie, aber eine zu arbeitende vollständige Kopie auf unserer Festplatte.
Und deswegen ist jetzt mein Problem, haben wir ein dezentrales Versionskontrollsystem wieder zentral gemacht.
Also prinzipiell würde ich erst mal sagen, auch wenn man mit einem zentralen Server arbeitet, dass man immer noch dezentral arbeitet.
Weil ja, wir haben zwar in einem normalen Clone unter Umständen nicht alle Objekte zur Verfügung.
Aber du kannst immer noch weiter arbeiten.
Du kannst immer noch auf die komplette Commit-Historie zugreifen, wenn GitHub, GitLab oder wie auch immer down sind.
Es funktioniert ja weiterhin.
Das heißt, das Problem wie früher mit Subversion, dass du wirklich nichts mehr machen konntest, weil du konntest ja auch nicht mal eben zwischen verschiedenen Branches wechseln.
Das existiert so nicht mehr.
Und dementsprechend ist es weiterhin dezentral.
Aber der Grad der Dezentralisierung ist natürlich in den meisten Setups nicht allzu hoch.
Und ja, in der Regel ist es schon so, dass wir mit einem einzigen wirklich klassischen zentralen Server arbeiten.
Ich denke, dass es prinzipiell aber erstmal kein riesiges Problem ist, weil das größtenteils eine Frage davon, wie organisieren wir eigentlich unsere Arbeit bei beispielsweise unserem Arbeitgeber.
Denn in der Regel ist es ja so.
Wir arbeiten für einen gewisses Unternehmen, das Unternehmen wird sowieso irgendwo die zentrale Serverstruktur bereitstellen.
Das heißt, warum sollten wir das nicht auch wirklich als zentralen Server benutzen?
Es hat halt einfach so ein bisschen praktikable Gründe, weil irgendwo wollen wir sowieso auch Issue-Tracking haben.
Wir wollen unsere Merge-Request irgendwo haben.
Quasi all die Metadaten, die noch um dieses Projekt rum existieren.
Es ist ja nicht nur das Git-Repository, das wirklich von Relevanz ist.
Und deswegen sehe ich das prinzipiell erstmal nicht als ein wesentliches Problem an.
Und zusätzlich dazu gibt es ja auch gerade in letzter Zeit einige Bestreben dahin, dass wir das auch wieder dezentraler machen.
Es gibt beispielsweise Projekte wie Tangled, die auf dem AT-Protokoll aufbauen, um wirklich eine dezentrale Entwicklungsstruktur basierend auf Git wieder bereitstellen zu können, wo dann quasi jeder mit jedem so ein bisschen interagieren kann.
Und das versucht halt das wesentliche Problem zu lösen, weil du meintest ja gerade so schön, prinzipiell könntest du einfach einen Repository bei dir auf der Festplatte haben und irgendjemand anderes kann darauf zugreifen.
Aber die Frage ist, willst du wirklich, dass irgendjemand mal eben auf die Repositories auf deiner Festplatte zugreifen kann?
Und ich würde behaupten, meistens wahrscheinlich eher nicht.
Du müsstest Ports öffnen, du hast eine gewisse höhere Attack-Service.
Und das macht dich natürlich einfach ein bisschen angreifbarer für andere Personen.
Ja, das bringt mich dann zu der Frage, okay, ist das denn ja eigentlich hier, dass wir uns alle um ein zentrales Repository organisiert haben.
Ist das denn ein technisches oder ist es erst eher so ein kulturelles oder bequemlichkeitsphänomen?
Und ich habe halt mit Gesprächen mit anderen Leuten herausgefunden, dass sie alle gar nicht wussten, dass man, dass wir drei uns jetzt hier Repositories hin und her pushen können, ohne einen GitHub, ohne einen GitLab, ohne einen zentralen Server.
Und da waren die, wie das geht?
Und ich denke mir so, hä?
Das ist doch der Kern von der ganzen Thematik.
Und deswegen frage ich mich, es scheint anscheinend kein technisches Problem zu sein.
Klar, die Sicherheitsbedenken, die du gerade aufgemacht hast, die existieren, die existieren immer, wenn du irgendwas aufmachst, so an Ports und Co.
Aber ist das eher nicht ein kulturelles oder ein, ja, vielleicht sind wir alle faul geworden.
Aber wie würdest du das managen?
Du arbeitest jetzt mit 15 Leuten zusammen, wo schiebst du dann die Gids hin und her oder so in dem Team?
Ich bin hier so eher gerade im Land- und Brecht-Moment, dass wir philosophisch über etwas sprechen, wofür ein dezentrales Versionskontrollsystem geschaffen wurde und wir als Menschen das wieder zentralisieren.
Und jetzt, ich will jetzt nicht in den Lösungsweg wechseln, weil ich habe keine Ahnung.
Ich habe keine Antwort darauf, gebe ich zu.
Aber im Endeffekt kann ich ja, ich kann dir mir ja ein Wolfgang-Remote einrichten, ja, dann kann ich mir ein Patrick-Remote einrichten und dann habe ich das Problem ja.
Die habt da bestimmt zu Hause dünn DNS oder ähnliches, ja.
Also, boff, Lösung parat.
Ist ein bisschen kompliziert, gebe ich zu.
Ich finde jetzt schön, dass du diese Wissenschaftliche Seite mal einnimmst, wo man sagt, man soll die Grundlagen verstehen und wie das eigentlich darunter funktioniert und nicht, wie es in der Praxis als Sorg einfach überall angewendet wird, sondern hardcore, die Leute müssen das noch verstehen, wie man das pusht zueinander.
Also ich sehe das alles entspannter, aber Patrick, vermisst du dieses direkte dezentrale Arbeiten?
Oder musst du jetzt als Arbeitnehmer von GitLab sowieso sagen, das zentrale ist cool.
Muss ich Prinzbase.
Nicht unbedingt sagen, ich arbeite ja vor allem auch in dem Git-Projekt selber und das Git-Projekt selber beispielsweise ist ja relativ dezentral aufgebaut.
Wir arbeiten mit keiner offiziellen Forge, das heißt, wir benutzen kein Issue-Tracking, wir benutzen keine Merge-Requests, sondern stattdessen arbeiten wir nur mit der Git Mailing-Liste.
Und das ist ziemlich dezentral.
Es gibt mehrere Forks von unserem Repository und natürlich gibt es ein paar offizielle Anlaufstellen.
Es gibt beispielsweise ein Fork bei GitLab, einen Fork bei GitHub, einen bei Kernel.org, weil wir aus der Kernel-Community kommen und so weiter.
Das ist ziemlich dezentral insgesamt.
Aber die Frage ist halt im Wesentlichen, was bringt es den meisten Projekten dezentral zu sein.
In dem Fall von dem Git-Projekt macht es durchaus schon Sinn, weil wir wollen beispielsweise kein bestimmtes Bias haben gegenüber einer der Hosting-Provider.
Das ist einer der großen Gründe, warum wir dezentral aufgestellt sind, damit wir nicht sagen, unser offizielles Projekt ist bei GitHub.
Dementsprechend ist GitHub quasi die Heimat von Git.
Würde halt so einen gewissen Bias erschaffen.
Und diesen Bias wollen wir halt vermeiden.
Aber ich würde behaupten, dass die meisten Projekte nicht unbedingt davon profitieren würden, wenn es wirklich dezentral ist.
Denn ich meine, man muss ja auch schon mal sagen, viele Entwickler haben schon alleine Probleme mit Git, wenn sie mit einem zentralen Server arbeiten.
Sie haben schon Probleme damit, was mache ich denn jetzt, wenn das Remote geupdatet wurde.
Wie rebase ich überhaupt meine Änderungen?
Was ist denn eine Rebase überhaupt?
Was ist eine Merge?
Und da kommen wirklich viele Probleme zueinander.
Und wenn man dann auch noch anfängt, dezentral zu arbeiten, sodass jeder einzelne Entwickler auf einmal mit drei Dutzend verschiedenen Remotes arbeiten muss.
Na herzlichen Glückwunsch.
Die werden auf jeden Fall Spaß haben, wenn sie schon den eigentlichen einfachen Workflow nicht so richtig verstehen.
Ja, vielleicht machst du da gerade ein gutes Fass auf, denn auch auf diesen zentralen Plattformen wie GitHub und GitLab, wenn du Projektmaner bist und dir mal ansiehst, wer eigentlich dein Repository forgt und da Änderungen macht, dass du, du hast ja dann Interesse natürlich auch zu gucken, okay, was machen denn dann die Forks, was machen denn die anderen Kopien, kann man davon inspiriert werden.
Das ist ja super schwierig.
Also du musst dich ja, du musst dich ja dann durch weggefolgte Repositories manuell fräsen, um zu gucken, wo ist denn welche sinnvolle Änderung, kann ich was zurückmergen und so weiter, weil nicht jeder hat das Konzept verstanden, ich mache einen Pull-Request oder einen Merge-Request auf und contribut zum Upstream, sondern die Leute beheben ihr Problem und gehen dann weiter, was ja völlig okay ist.
Ich meine, das ist ja der Sinn von Open Source, ja, alles super.
Aber wenn man natürlich versucht, sein Upstream-Repository zu maintain, dann mit den 20, 30 verschiedenen Forks oder Remotes zu arbeiten, das stimmt schon.
Genau.
Es muss halt am Ende immer noch irgendwo eine zentrale Autorität geben, die quasi sagt, das ist jetzt der eigentliche Stand von dem Projekt.
Und diese Person ist dann dafür zuständig, das alles wieder zu reintegrieren, was passiert in den einzelnen, in den einzelnen Forks.
Das sieht man beispielsweise in der Linux-Community ganz gut.
Da funktioniert es ja genauso.
Wo Linus mehr oder weniger ganz oben sitzt, er hat quasi das offizielle Repository, aber dann gibt es ja ganz viele verschiedene Forks von diesem Repository, die die einzelnen Lieutenants von ihm quasi müssen, also die einzelnen Subsystem-Mainers.
Die werden dann quasi in ihren eigenen Forks erstmal die ganzen Änderungen von ihren Delegates oder von ihren Entwicklern sammeln und gehen dann irgendwann ihre Änderungen nach oben weiter zu Linus.
So dass Linus irgendwann am Ende dann quasi alles zusammen mercht und das ist dann die offizielle Version von dem Projekt mehr oder weniger.
Aber es gibt halt nicht quasi die eine Version von Linux, sondern es gibt halt ganz viele verschiedene Repositories, die auch unterschiedliche Stände haben.
Und das funktioniert in dem Projekt sehr gut, aber es funktioniert halt nicht unbedingt in jedem Projekt sehr gut.
Und da muss man halt auch immer sehen, was braucht das Projekt eigentlich.
Du machst mir schon wieder die beste Überleitung der Welt.
Und da frage ich mich natürlich, wenn du sagst, was braucht das Projekt eigentlich?
Du hast gerade gesagt, oder ich habe gesagt in der Einleitung, dass Git inzwischen 20 Jahre alt ist.
Und da frage ich mich, wieso hat Git eigentlich initial Pearl gebraucht, ja?
Lass uns mal ein bisschen über die Modernisierung von Git bzw.
der Git-Codebase sprechen, denn wenn ich mir mal die Source-Code-Verteilung vom aktuellen Git-Repository ansehe, dann hat man da immer noch so circa 5% Pearl rumfliegen.
Circa 50, 51, 52 Prozent C, eine ganze Menge Shell-Kram.
Aber Pearl, wundervoll.
Mein Liebling ist das auch nicht, sagen wir es mal so.
Ich kann bis heute kein Pearl schreiben.
Ich kann es gerade mal so lesen, wenn ich mich wirklich anstrenge, aber für mich ist das größtenteils eigentlich nur irgendeine esoterische Sprache mit sehr eigenartiger Syntax.
Pearl war für mich nie eine Programmiersprache.
Pearl ist die Kunst, das richtige Zeichen zu finden.
Also Pearl war meine erste Programmiersprache, Andi.
Wenn ich den nochmal anmerken.
Also bist du künstlern?
Wenn man das Programmieren nennen hat, kann, dann weiß ich nicht, das war zumindest kopieren und irgendwas ändern und dann versuchen, ob die Änderung funktioniert hat, aber ja, das war meine Pearl-Erfahrung.
Aber lass uns mal wirklich jetzt über die Modernisierung von Git sprechen.
Also meines Wissens nach ist die ganze Sache größtenteils in C gebaut.
Und mittlerweile.
Mittlerweile.
Okay, da habt ihr euch die letzten 20 Jahre hin entwickelt.
Richtig, ganz am Anfang sah das alles noch ein bisschen anders aus.
Wir hatten von Anfang an quasi zwei unterschiedliche Layer.
Das sind einerseits das Plumbing-Layer und andererseits das Porzellan-Layer.
Plumbing ist quasi, das sind die wesentlichen Tools, die sehr stark runtergebrochen sind, um relativ einfache Operationen auf dem Git Repository zu machen.
Das heißt, das ist dann sowas wie, gib mir ein einzelnes Objekt raus.
Oder Update da eine einzelne Referenz.
So ein Zeugs.
Porzellan ist dagegen das Layer, das für den Nutzer das direkte Interface ist.
Das heißt, du würdest in der Regel nicht mit dem Plumbing-Layer arbeiten, weil das viel zu low-level ist und ihr keine gute Usability geht.
Und ja, man kann darüber streiten, ob die Usability von unserem Porzellan-Layer in Git so super ist, aber es ist zumindest deutlich besser.
So viel kann ich versprechen.
Und ursprünglich war das so, dass viele von den einzelnen Kommandos, die heutzutage existieren und Teil des Porzellan-Layers sind, also User-Facing sind, im Pearl geschrieben wurden und einfach nur quasi in das Plumbing-Layer reingereicht haben.
Das heißt, sie haben die Plumbing-Commands ausgeführt, die in C geschrieben waren, größtenteils.
Und Pearl war dann oftmals quasi das, worin dann die Higher-Level-Commands geschrieben wurden.
Was wahrscheinlich einfach den Anwendungsfall hatte, dass es halt relativ schnell und einfach quasi zu implementieren war.
Und man dadurch ein bisschen schneller iterieren konnte.
Aber ich muss auch dazu sagen, dass es vor meiner Zeit im Git-Projekt.
Also ich bin mir auch nicht so hundertprozentig sicher, wie es dazu kam.
Jetzt gibt es diese populäre Diskussion, AC, muss sich selbst an den Memory kümmern und Memory Buffer Overflows und so die ganze Thematik.
Und dann wird immer spätestens nach drei Sätzen tief in der Diskussion Rust erwähnt.
Ja, sollte man das eine nicht mit dem anderen ersetzen.
Im Linux-Kernel findet Rust jetzt nach langer Diskussion da langsam irgendwie eine Anwendung und wo, glaube ich, jetzt auch partiell akzeptiert als zweite Sprache.
Wie sieht es in Git aus?
Habt ihr über sowas auch schon gesprochen oder sagt ihr, nee, wir sind alle happy mit C, weil wir da den Plumbing-Layer so stabil haben, dass wir da gar nicht mehr ran müssen, oder?
Also prinzipiell muss ich erstmal sagen, dass ich persönlich mit C sehr zufrieden bin, weil C eine super einfache Sprache ist und relativ wenig Zeugs passiert, wo ich nicht nachvollziehen kann, was passiert.
Aber wir hatten natürlich in der Git-Community schon seit Jahren die Diskussion, ob wir vielleicht doch mal irgendwann Rust benutzen wollen.
Weil man sieht es ja überall, dass alle möglichen Projekte anfangen, Rust zu akzeptieren und es gibt definitiv auch gute Gründe dafür.
Memory Safety ist das eine.
Borrow-Checking und dadurch Fearless Concurrency ist natürlich ein anderes wesentliches Thema, was auch für das Git-Projekt von einer großen Relevanz ist.
Und außerdem haben wir halt auch noch deutlich besseres Tooling teilweise mit der ganzen Rust-Compiler-Tool-Chain.
Und das ist natürlich sehr lukrativ und sehr attraktiv für das Git-Projekt.
Die Diskussion existierte, wie gesagt, schon seit einigen Jahren, dass wir vielleicht doch mal so ein bisschen mit Rust warm werden wollen, sodass wir dann, lass mich lügen, ich glaube, vor vier oder fünf Jahren hatten wir quasi den ersten Rust-Code im Git-Projekt drin.
Das war aber erstmal quasi ein Wrapper um die C-Bibliotheken, die wir haben, sodass man quasi die C-Bibliotheken in Rust-Code relativ einfach aufrufen kann.
Allerdings ist es extremst eingeschränkt.
Das Einzige, was du damit machen kannst, ist eine Git-Konfiguration, also die Git-Config quasi parsen und darauf Zugriff haben.
Das heißt wirklich, viel kannst du damit nicht so richtig tun.
Die Diskussion ist allerdings dann Mitte letzten Jahres nochmal sehr stark aufgeflammt und führte dann im Endeffekt dahin, dass wir gesagt haben, wir akzeptieren jetzt auch Rust in unserem Core von Git.
Also quasi direkt im Code drin, sodass es zentral in Git selber ist.
Wir haben das jetzt allerdings sehr, sehr schrittweise eingeführt.
Das heißt, anfangs haben wir erstmal gesagt, wir akzeptieren Rust-Code im Kern von Git, aber werden erstmal diesen Code nur als optional betrachten.
Das heißt, es ist noch nicht möglich, zu sagen, wir führen wirklich zwingendermaßen Rust ein, weil sich auch das ganze Ökosystem anpassen muss.
Das sind die ganzen Downstream-Distributions, die dann auf einmal noch eine Rust-Compiler-Toolchain mit reinfügen müssen, wenn sie Git kompilieren wollen.
Das sind esoterische Plattformen, die vielleicht gar nicht erst Rust-Support haben.
Also so etwas wie HPUX Nonstop oder irgendwie solche Plattformen, die halt super esoterisch sind, die aber auch Git benutzen.
Deswegen ist es momentan tatsächlich noch optional.
Unser Ziel ist es allerdings, voraussichtlich mit Git 3.0 zu sagen, es wird jetzt zwingendermaßen notwendig sein, Rust in der Toolchain zu haben und Git damit zu kompilieren, sodass wir dann quasi Rust auch deutlich mehr in der Git Codebase benutzen können.
Kannst du mal kurz umreißen, was Git 3 bedeutet oder in welchen Sphären bewegen wir uns da?
Ist es so die Zukunftsmusik von 100 Jahren oder ist das schon was konkretes und was für Änderungen gibt es dort?
Ich kann nur sagen, es ist halbwegs konkret, was jetzt nicht so unbedingt konkret ist.
Git 3.0 ist jetzt mittlerweile seit eineinhalb, zwei Jahren ungefähr bei uns in der Diskussion.
Da geht es dann um einige Änderungen, die nicht rückwärtskompatibel sein werden.
Es geht beispielsweise darum, dass wir ein anderes Backend haben, um Referenzen zu speichern.
Es geht darum, dass wir eine große Änderung haben, dass wir beispielsweise SHA-1 als Default-Hashing-Algorithmus ersetzen durch Shar 256 und auch ein paar andere Themen.
Halt wirklich große Änderungen, die der Nutzer auch wirklich merken werden.
Wir müssen an diese Änderung natürlich extremst konservativ rangehen, weil uns natürlich bewusst ist, dass das auch einen wesentlichen Impact auf das gesamte Ökosystem haben wird.
Und naja, Git sitzt halt sehr zentral in allen Softwareentwicklungen.
Und dementsprechend können wir halt nicht einfach mal eben sagen, so, ja, wir haben jetzt mal eben Lust hier, das alles zu ändern und machen das einfach mal morgen, sondern das muss halt gut geplant sein und es muss vor allem auch gut kommuniziert sein.
Konkreter heißt es allerdings, dass wir anstreben, ganz lose vielleicht Ende diesen Jahres, vielleicht irgendwann Mitte nächsten Jahres Git 3.0 auch wirklich veröffentlichen zu können.
Da warten wir aber auch noch auf ein paar Faktoren im Ökosystem, sodass wesentliche Bibliotheken beispielsweise Support für Shard 256 haben oder dass beispielsweise einen GitHub auch Shards 256 unterstützen kann.
Weil es bringt nichts, wenn wir unsere Defaults ändern, ohne dass die ganzen Code-Hosting-Forages das eigentlich unterstützen.
Es ist natürlich schon ein bisschen schade, dass wir das Ökosystem schon eine zentrale Power hat eigentlich, über eure Entwicklungsiterationen.
Ich würde sagen, es ist Blessing und Curse gleichzeitig.
Weil es ist natürlich schön, dass quasi jeder Entwickler heutzutage Git benutzt.
Das fühlt sich für einen selber natürlich wahnsinnig toll an, wenn man Entwickler im Git-Ökosystem ist.
Weil man auch weiß, dass man einen riesigen Impact hat.
Es kann aber auch wirklich wahnsinnig frustrierend sein, wenn schon seit Jahren große Themen wie Shard 256 beispielsweise anstehen, aber einfach nichts passiert in dem Kontext und man halt immer geblockt ist durch die ganzen großen Code-Forages, weil die sich halt einfach nicht bewegen.
Das ist teilweise halt so ein bisschen ein Chicken- und Egg-Problem.
Dass man sagt, niemand wechselt auf Shard 256 beispielsweise, weil die Forges das nicht unterstützen, aber die Forges unterstützen das nicht, weil niemand auf Chart 256 wechseln möchte.
Und das ist teilweise schon wirklich, es zieht sich dadurch halt extremst in die Länge.
Also da mal kurz tiefer einsteigen.
SHAR256 hast du jetzt als große Änderung angekündigt.
Warum sind Hashes überhaupt ein zentrales Design-Element von Git bzw.
von Git-Objekten?
Man bezeichnet GitA so schön als Content Addressable File System.
Das heißt, jedes Objekt ist durch den Inhalt von dem Objekt eindeutig identifizierbar.
Ein bisschen weniger abstrakt gesagt heißt es einfach, ich habe irgendeinen Inhalt, irgendeine Datei beispielsweise, ich hashe die Datei und dann habe ich den Objektnamen.
Und das ist quasi eine der wesentlichen Design-Kriterien von Git.
Dementsprechend ist das ganze Objektmodell darauf aufgebaut.
Ein Objekt wird ein anderes Objekt dadurch referenzieren, dass es einfach sagt, das hier ist der Hash von dem anderen Objekt.
Und wenn man sich dann quasi einfach nur einen Commit irgendwo nimmt, hat man einen kompletten Merkle-Tree, der dann eindeutig alle anderen Objekte in der Abhängigkeit identifizieren.
Das heißt, über die Hashes kannst du den kompletten Objektgrafen ablaufen und alle anderen Objekte referenzieren, das heißt alle vorherigen Commits, alle Dateien, die ausgecheckt werden müssen, alle Verzeichnisstrukturen und so weiter.
Und dadurch ist dieser Objekt-Hash sehr stark eingebettet in das komplette Datenmodell und von wesentlicher Relevanz.
Und das natürlich zu ändern, ist relativ schwierig, weil das heißt, dass man alle Objekte neu schreiben müsste.
Aktuell nutze ich ja SHA-1, wenn ich mich recht erinnere.
Und ihr wollt jetzt auf Chart 256 wechseln.
Da geht es aber dann nicht um das Thema Security, sondern eher um Integrität.
Schwieriges Wort, oder?
Ja und nein.
Integrität ist erstmal das Wesentliche, wofür wir diese Hashes benutzen.
Denn man hat natürlich eine schöne Eigenschaft, wenn jedes Objekt eindeutig durch den Hash identifizierbar ist, kann man auch relativ einfach überprüfen, ist denn dieses Objekt, was dahinter steht, eigentlich doch konsistent, indem man einfach nochmal neu hasht.
Und dann wirst du ja sofort sehen, hat sich der Hash geändert von dem Objekt, dann muss da ja irgendwas faul sein.
Dann hat sich beispielsweise ein Bit auf der Festplatte geflippt oder sowas.
Oder die Datenstrukturen, die ich habe, sind irgendwie korrupt oder was weiß ich was.
Das ist eine der wesentlichen Designkriterien, warum wir dieses Hashing haben.
Und ja, es wurde gerade am Anfang von dem Git-Projekt gesagt, dass Sicherheit keine wesentliche Relevanz für dieses Hashing hat.
Aber man muss im Endeffekt auch sagen, es stimmt nicht so wirklich.
Denn wenn du in der Lage bist, relativ leicht Hash-Collisions herbeizuführen, wo quasi das gleiche Objekt oder nee, unterschiedliche Objekte auf den gleichen Namen gehasht werden können, dann wirst du daraus folgend schon ein paar Sicherheitsimplikationen haben.
Beispielsweise sowas wie Commit-Signaturen.
Also, also wenn man eine kryptografische Signatur auf einem gewissen Commit macht, ist ja davon auszugehen, die Person weiß, was sie signiert hat.
Aber wenn du jetzt in der Lage bist, eine Hash-Kollision herbeizuführen, dann ist ja die Commit-Signatur nicht mehr wirklich eindeutig, sondern kann vielleicht das eine Objekt referenzieren oder das kollidierende Objekt.
Und dementsprechend verliert diese ganze kryptografische Signatur so ein bisschen an Wert.
Aber habe ich in der Realität wirklich Kollisionen?
Also, ich könnte mir vorstellen, dass da ja sogar irgendein MD-5-Hash ohne Probleme ausreichen würde, weil wir sprechen da jetzt nicht irgendwie von dem ganzen Internet, sondern von einem Repository.
Ohne, dass man sie bewusst herbeiführt, hat man eigentlich keine Kollision.
Meines Wissens nach gab es bisher weltweit noch keine einzige Kollision mit ShaWan.
Mit MD5 hätte das vielleicht anders ausgesehen, weil MD5 halt deutlich schwächer ist, als es mit Shawan der Fall ist, weiß ich aber ehrlich gesagt nicht so ganz.
Was man aber auf jeden Fall sagen kann, ist, dass mit MD5 es viel, viel einfacher ist, bewusst Kollisionen herbeizuführen, als es mit Shawan der Fall ist.
Und das heißt, wenn es irgendwo einen Angreifer beispielsweise geben möchte, der deinen Git Repository kompromittieren möchte, ist er mit ShaWan ziemlich trivial in der Lage, dann halt Kollisionen zu erschaffen und dadurch zumindest einiges an Schaden herbeizuführen.
Sha1 ist allerdings auch nicht mehr so wirklich Kollisionsresistent.
Es gab ja vor einem paar Jahren den ersten praktisch durchgeführten Angriff, der shattered heißt.
Und da wurde dann ja die erste wirkliche Kollision herbeigeführt mit zwei unterschiedlichen PDF-Dokumenten, die beide syntaktisch valide sind, unterschiedliche Inhalte haben, aber den gleichen Objekt-Hash haben.
Dementsprechend kann man schon davon ausgehen, dass Shawan mittlerweile kryptografisch nicht mehr sicher ist.
Und man kann auch vor allem davon ausgehen, dass es über die nächsten Jahre wahrscheinlich irgendwann auch mal den nächsten Angriff geben wird, der es vielleicht noch schwächer macht, als es momentan schon der Fall ist.
Und vor allem auch mit dem allseits beliebten Thema Artificial Intelligence, sieht man natürlich momentan, dass die Datenzentrenstrukturen immer weiter ausgebaut werden und immer mehr GPUs beispielsweise bereitgestellt werden.
Und GPUs sind auch ein wesentlicher Bestandteil oder ein wesentlicher Faktor, mit dem man relativ gut Hashes berechnen kann.
Und je mehr GPU-Kapazitäten wir haben, desto einfacher wird es quasi einen Hash-Collision auch herbeizuführen.
Das heißt, ich würde behaupten, für einen wirklichen Angreifer, der es möchte, wäre er auch in der Lage, heutzutage relativ kostengünstig Hash-Kollisionen herbeizuführen mit Shawnee.
Wieder was gelernt.
Ich glaube, ich muss mal ein bisschen lokal bei mir experimentieren, ob ich auch Hash-Collisions herbeiführen kann.
Interessant.
In deinem Fostam-Talk hast du aber von einer weiteren großen Änderung gesprochen, und zwar sogenannten Rev-Tables.
Erklär mir mal bitte, was Rev-Tables sind oder wofür diese genutzt werden oder welches Problem sie überhaupt lösen sollten.
Ich glaube, um das zu erklären, muss ich erstmal ein bisschen erklären, wie eigentlich momentane Referenzen gespeichert werden.
Ich habe ja schon gesagt, was eine Referenz überhaupt ist.
Eine Referenz ist quasi einfach nur ein Name, der mit einer bestimmten Objekt-ID verknüpft wird.
Sodass du halt nicht jedes Mal die Objekt-ID merken musst in einem Git Repository, sondern dass du einfach sagen kannst, ich möchte jetzt beispielsweise den Main-Branch auschecken und dann sagst du halt einfach nur GitCheckout Main anstatt GitCheckout-Objekt-ID.
Die sind quasi einfach so ein gewisser Shorthand.
Das wurde Ewigkeiten über das sogenannte Files-Backend gemacht.
Das heißt, vereinfacht gesagt, ist jede Referenz erstmal als eine einzelne Datei abgespeichert.
Dein Main-Branch beispielsweise ist in dem .git slash Refs hats Main als Datei abgespeichert.
Und diese Datei wird einfach nur die Objekt-ID beinhalten.
Es skaliert natürlich so erstmal nicht unbedingt gut, weil es durchaus Repositories gibt, wo du Millionen von Referenzen hast.
Und du willst nicht 20 Millionen einfache Dateien auf deiner Festplatte haben, um die Referenzen alle lesen zu können, weil es natürlich erstmal ineffizient ist, was die CPU-Zeit angeht, weil du unter Umständen halt alle Referenzen laden musst und du keine 20 Millionen Dateien öffnen willst.
Andererseits ist natürlich auch vom Storage Space halt relativ ineffizient, weil es oftmals so ist, dass halt eine Referenz den kompletten Disk-Sektor beispielsweise braucht im Dateisystem.
Deswegen packt Git regelmäßig schon im Files-Backend diese losen Referenzen in die Pack-Drefs-File.
Das heißt, das ist dann eine einzelne Datei, die alle deine Referenzen beinhaltet mit der jeweiligen Objekt-ID.
Das ist natürlich deutlich effizienter.
Wir speichern oder wir haben eine deutlich geringere Festplattenbelastung.
Wir müssen nicht mehr alle Dateien einzeln öffnen und so weiter.
Aber auch in Pack-References haben wir einige Probleme.
Wir haben beispielsweise eine meiner Lieblings-Repositories da draußen, hat ungefähr 25 Millionen Referenzen und 25 Millionen Referenzen summieren sich auf zu einer Pack-Dress-File, der ungefähr eineinhalb Gigabyte groß ist, was schon relativ viel ist.
Das Problem ist jetzt, jedes Mal, wenn du deine Referenzen packen möchtest, musst du die komplette Pack-Refs-Datei neu schreiben.
Das heißt 1,5 GB neu schreiben.
Das größere Problem ist allerdings, jedes Mal, wenn du eine Referenz löschen möchtest in deinem Repository, beispielsweise, weil du in einem Branch löscht, musst du das auch aus der Packdraf-Datei rauslöschen.
Heißt, eine einzelne gelöschte Referenz wird es dafür sorgen, dass du 1,5 GB an Daten neu schreiben musst, was jetzt vielleicht nicht unbedingt effizient ist.
RevTables sind dafür quasi so ein bisschen die Lösung.
Denn mit RevTables haben wir quasi ein komplett anderes Datenformat.
Wir haben erstmal quasi die individuelle Table.
In den Table haben wir quasi ein Binärdateien-Format, was die einzelnen Referenzen auflistet, was schon mal ein bisschen effizienter ist, was den Festplattenspeicher angeht.
Weil du halt weniger Daten speichern musst, weil es halt in einem Binärformat ist.
Zusätzlich haben wir sowas wie Prefix Compression beispielsweise, sodass wir nicht die kompletten Referenzen haben jedes Mal speichern müssen, sondern wenn du jetzt RevsHats 1 hast, Revs Hats 2, kannst du bei den zweiten Mal das Revs Hats weglassen, durch Prefix Compression.
Macht es auch nochmal ein bisschen effizienter, wodurch wir halt insgesamt dann, ich glaube, fast die Hälfte weniger an Festplattenspeicher benötigen dafür.
Zusätzlich haben wir aber nicht nur eine Rev-Table, sondern wir haben mehrere Rev-Tables, die dann in einem sogenannten Stack organisiert sind.
Und vor allem kannst du dann quasi in einer zukünftigen Rev-Table einfach nur einen sogenannten Tombstore-Marker drin haben, der sagt, ich lösche jetzt Referenz 1, sodass du nicht mehr alles neu schreiben musst.
Jedes Mal, wenn du eine einzelne Referenz löschen möchtest.
Wir benutzen dann noch ein paar weitergehende technische Sachen, wie beispielsweise Netschain Geometric Compaction.
Das heißt, wir gucken quasi, wie müssen wir diese einzelnen Tabellen zusammen mergen, um nicht jedes Mal quasi alles neu schreiben zu müssen, aber um trotzdem möglichst wenig Tabellen insgesamt zu haben, sodass wir quasi dann eine geometrische Sequenz haben an Tables.
Das heißt, jede Table muss mindestens doppelt so groß sein wie die nächstkleinere Table, sodass du quasi erstmal eine Tabelle hast, die hat zehn Referenzen, dann hast du eine Tabelle, die hat acht Referenzen, dann hast du noch eine Tabelle, die hat zwei Referenzen.
Und wenn du dann quasi eine weitere Referenz hinzufügen würdest, sodass die unterste dann drei hätte, dann würdest du quasi nach oben hinweg mergen.
Ist relativ technisch, aber das erlaubt uns quasi einige Probleme zu lösen, wenn es um Effizienz geht.
Ein weiteres Problem, was wir außerdem mit Ref Tables lösen wollen, ist, dass Dateisysteme erstaunlicherweise relativ komplex sind.
Und vor allem die Art und Weise, wie Dateisystemen Pfade repräsentiert werden, je nach Betriebssystem auch ziemlich unterschiedlich sind.
Wir haben ja das Problem, dass eine einzelne Referenz als tatsächliche Datei gespeichert wird.
Das heißt, du hast Punkt Git, slash Ref, slash Head, Slash Main beispielsweise.
Das heißt, der Name der Referenz ist im Dateisystemen als Pfad abgespeichert.
Funktioniert unter Linux relativ gut.
Wenn du jetzt aber beispielsweise einen Windows oder Mac OS hast, wo du einen Dateisystem hast, das Case-Insensitive ist, funktioniert das nicht mehr so gut.
Weil du dann beispielsweise keine zwei Branches haben kannst, wo einfach nur das Casing unterschiedlich ist.
Unter Linux kannst du das haben.
Und dementsprechend kannst du das auch beispielsweise auf GitHub oder GitLab hochpushen.
Aber wenn dann jemand jemand unter Windows das runterfetchen möchte, dann hat er ein bisschen Problem, weil er die halt nicht mehr in seinem Dateisystem strukturieren kann.
Und das ist halt auch ein wesentliches Problem, was mit RevTable jetzt nicht mehr existieren wird, weil dort die Referenznamen in dem Binärformat gespeichert sind und nicht mehr als Teil des Dateisystempfades.
Ich wollte gerade fragen, und die Frage hast du mir eigentlich schon beantwortet, auch mit deinem letzten Kommentar, ob das etwas ist, was EntwicklerInnen aktiv merken oder ob das eher so ein unter der Haube Thema ist.
Ganz lange habe ich gedacht, unter der Haube, bis zu dieser Case-Insensibilität.
Da würde ich sagen, okay, cool, das ermöglicht ja ein neues Feature.
Auf der anderen Seite frage ich mich gerade, fixt ihr damit Sachen, die in Filesystemen eigentlich gar nicht möglich sein sollten.
So Case-Ins-intive Filesysteme finde ich ein bisschen schwierig.
Ich meine, ich bin auf einem Mac, ich kenne dieses Problem und das ist, das nervt mich tierisch.
Viel schlimmer ist ja auch noch Windows, muss man sagen, weil unter Windows hast du nicht nur das Problem, dass du Case-Insensitive bist, sondern dass Windows dir auch gar nicht erlaubt, viele verschiedene Dateinamen überhaupt erst zu erstellen.
Ist dann beispielsweise sowas wie Com1 oder LPT, weil es irgendwann mal zu DOS-Zeiten spezielle Dateinamen waren, die für bestimmte Funktionalitäten reserviert waren.
Das heißt, du kannst kein Branch haben, der Com1 heißt.
Okay, also reservierte Keywords haben die.
Das wusste ich jetzt auch noch nicht.
Richtig.
NTFS ist ein sehr, sehr interessantes Dateisystem, würde ich insgesamt sagen.
NTFS ist auch immer noch das Fallsystem, was auf Windows aktiv genutzt wird, oder?
Aktuell?
Soweit ich weiß, ja.
Ich weiß, dass es mittlerweile auch Möglichkeiten gibt, bestimmte Features in NTFS zu ändern, sodass beispielsweise reservierte Dateinamen oder sowas nicht mehr existieren, meines Wissens nach, aber ich benutze in meinem Alltag immer nur Linux.
Dementsprechend bin ich da auch so ein bisschen out of my depth, wie man so schön sagt.
Ja, eher gut, aber ich meine, Default-Settings werden ja von den meisten Leuten nicht geändert, besonders nicht auf Fallsysteme-Ebene.
Also deswegen würde ich sagen, die kann man halt schon als Standard setzen.
Ja, ja, auf jeden Fall.
Ein weiterer großer, dritter Punkt, den du in deinem Post-Em-Talk angesprochen hast, waren große Dateien oder besserer Support für größere Dateien in Git-Repositories.
Und auf Basis meines Wissens nach haben da besonders Leute, die irgendwie Spiele entwickeln, ein Riesenproblem, weil die natürlich die ganzen Grafik-Assets und Co.
oder generell Binary-Dateien in Git-Repositories.
Binary-Dateien kann man ja auch nicht so wirklich gut diffen, würde ich mal sagen.
Also geht bestimmt, willst du uns gleich sagen.
Aber meines Wissens nach, ich versuche immer Large Binary-Files zu verhindern, weil dieses ganze Gehässel mit, was nutzt man heutzutage, Git LFS und Co.
Das klingt immer wie so ein Plugin da dran.
Und das war immer so ein bisschen so, ah, muss das jetzt sein.
Erklären wir uns mal bitte, was ihr da vorhabt, beziehungsweise welches Kernproblem die ihr eigentlich identifiziert habt.
Also erstmal zu Git LFS, ja, es ist genau das.
Es ist ein Plugin.
Es ist halt nicht offizieller Bestandteil von Git, sondern ist komplett extern entwickelt.
Und dafür muss man sagen, funktioniert Git LFS erstaunlich gut.
Was es nämlich macht, ist, dass es quasi, anstatt die einzelnen Binärdateien wirklich in die Commit-Historie reinzuspeichern und dadurch in dem einzelnen Git-Repository zu speichern, speichert es einfach nur ein Pointer auf diese Datei und lädt diese Datei dann auf einen separaten LFS-Server nach oben.
Sodass das eigentliche Repository gar nicht mehr deutlich größer wird durch diese Binärdateien und trotzdem in der Lage ist, zu einem späteren Zeitpunkt sich on-demand die großen Dateien runterzuladen, wenn es möchte.
Hat aber halt einige Probleme, wie du schon meintest, es ist halt erstmal ein Add-on.
Das heißt, dein Server muss es unterstützen, auch wenn es die meisten Server mittlerweile tun.
Aber wenn du jetzt, wie wir vorhin schon gesagt hatten, wenn du einfach nur eine Git-Executable auf deinem eigenen Server rumzufliegen hast und dann einfach per SSH reingehst, dann wirst du damit kein LFS-Support bekommen.
Und das ist natürlich nicht so prickelnd.
Zusätzlich musst du dann noch Sachen machen, wie beispielsweise deine Git-Attributes pflegen, sodass du Git LFS sagst oder Git im Endeffekt sagst, welche Dateien überhaupt mit Git LFS gespeichert werden sollen und welche nicht.
Das heißt, du hast dann noch einen wesentlichen Overhead, weil du halt konfigurieren musst.
Und das größte Problem ist, wenn die Konfiguration nicht stimmt, dann hast du jetzt aus Versehen doch eine Binärdatei in deinem Repository, was das Repository für immer größer machen wird.
Und wenn es dann aus Versehen mal eben 500 Megabyte waren und dann an einem Tag, an einem anderen Tag nochmal aus Versehen 500 Megabyte und das läppert sich dann über die Zeit, dann hast du halt irgendwann auch wieder eine Repository, das viele, viele Gigabyte groß ist und du bekommst diese Binärdatei nicht mehr raus aus Git.
Ohne dass du die komplette Historie einmal komplett neu schreibst und quasi eine Migration machst.
Und das ist halt super, super schmerzhaft, sowas zu machen.
Deswegen ist halt unser Ansatz, dass wir wollen, dass so Tools wie Git LFS gar nicht mehr nötig sind, sondern dass du stattdessen in der Lage bist, einfach eine Binärdatei in Git reinzuschmeißen und Git damit umgehen kann.
Dazu gehören erstmal ziemlich viele verschiedene Komponenten.
Es ist nicht ein einziges Projekt und dann ist alles getan, sondern da müssen wir in Git einige Änderungen machen.
Das fängt einerseits an beim Festplattenformat.
Das heißt, wie speichern wir überhaupt Objekte, sodass sie auch effizient gespeichert werden können, auch wenn die einzelnen Dateien Gigabytes groß sind oder Dutzende von Gigabytes teilweise sogar.
Geht dann aber auch weiter hin bis, wie handeln wir sowas überhaupt effizient auf der Serverseite.
Wie schaffen wir das, dass wir effizient so eine großen Binärdatei zwischen der Client-Seite und der Serverseite überhaupt austauschen können.
Beispielsweise, wenn sich jetzt nur ein Byte oder sowas in einer sehr großen Binärdatei geändert hat, willst du nicht die komplette neue Version nochmal rüberschieben müssen.
Sondern du willst im Idealfall quasi nur eine minimale Änderung rüberschieben können.
Und da brauchen wir halt auch nochmal Änderungen in Git selber und quasi das Remote-Protokoll, also das, wie der Client und der Server miteinander reden, dass wir das ein bisschen adaptieren können.
Aber das ist ja auch das Grundproblem grundsätzlich, dass du den DIF hier bei Binär-Daten eigentlich gar nicht machen kannst, oder?
Also bei den klassischen, bei den meisten Binärformaten zumindest ändert sich ja wirklich die gesamte Datei.
Das ist ja auch das große Problem bei den Spielern, die halt irgendwelche Shader oder sonstige Dinge haben, die da änderst du halt ein Pixel und die gesamte Binärdatei ändert sich.
Also du bräuchtest ja dann sogar irgendwie Div-Tools, die tiefer reinblicken könnten in die Binärdateien, damit du es effizient überhaupt hinbekommst.
Stimmt, hundertprozentig.
Und hier muss man auch sagen, es kommt wieder sehr stark darauf an, was für eine Arten von Binärdateien du hast.
Es gibt Binärdateien, da hast du das Problem nicht.
Da kannst du quasi einfach ganz vorne irgendwo einen Byte ändern und dann wird sich der Rest trotzdem nicht verändern.
Und das ist unser erstes Ziel, erstmal daran zu gehen und quasi zu schaffen, dass solche Binärdateien effizient auch übertragen werden können.
Aber das andere Problem, dass sich dann wirklich die komplette Datei ändert.
Da musst du dann ja schon irgendwie anfangen, mit semantischen Divs zu arbeiten.
Weil ansonsten kannst du gar nicht, oder ansonsten kann Git gar nicht effizient ein Div berechnen.
Aber das ist dann quasi nochmal ein Problem, was ich erstmal bewusst in die Zukunft schiebe, weil das dann nochmal deutlich komplexer werden wird.
Also ihr plant jetzt keine externen semantischen Div-Dools irgendwie einbindbar zu machen oder so.
Also soweit geht das Ganze noch nicht, oder?
Naja, es gibt schon Support in Git für semantische Div-Tools, die du einbinden kannst.
Es gibt sogenannte Div- und Merge-Driver, die du in Git haben kannst, die sind aber clientseitig.
Das heißt, du kannst in Git eine GitAttributes-Datei quasi so schreiben, dass du sagst, eine bestimmte Datei, beispielsweise eine PNG-Datei, soll mit einem Image-Diffing-Tool gedifft werden.
Das ist dann aber wie gesagt erstmal ein kleinseitiges Feature, sodass du quasi als Endanwender sehen kannst, was hat sich denn jetzt eigentlich geändert in meiner PNG-Datei, sodass dann quasi ein kleiner Bereich in der PNG-Datei irgendwie gehighlightet wird, und jetzt zeigen, das hier hat sich geändert.
Ändert aber erstmal nichts an dem anderen Problem, dass wir quasi immer noch schaffen müssen, irgendwie auch die Objekte, also die Objektives effizient berechnen zu können und auch zwischen Client- und Server-Seite austauschen zu können.
Und das Ganze ist auch für Git 3.0 geplant oder ist das komplett separates Projekt?
Das ist erstmal ein separates Projekt, weil, wie ich schon meinte, das sind viele verschiedene Sachen, die wir angehen müssen.
Und ich habe jetzt seit eineinhalb Jahren dabei am Arbeiten, nennt sich Pluggable Object Databases.
Ist quasi die Möglichkeit, das Backend, wie Objekte gespeichert werden, komplett auszutauschen.
Woran ich jetzt quasi konkret arbeite, ist erstmal ein ordentliches Interface in Git zu schaffen, um zu sagen, wir haben erstmal ein Layer, das abstrahiert, wie wir auf Objekte jetzt zugreifen können, sodass wir dann im Nachhinein sagen können, wir tauschen dieses Layer aus, gegen ein anderes Layer, sodass wir ein anderes Dateiformat haben können.
Und sobald wir diese Möglichkeit haben, haben wir erst quasi einfache Möglichkeiten, auch ein für Binärdateien effizienteres Format zu implementieren.
Ich stelle mir gerade die Frage, und die ist sehr wahrscheinlich sehr simpel gestellt und deutlich komplexer unter der Haube, aber wäre es nicht möglich, dass man komplett auf Binary-Dateien oder auf Dateien größer, 1 MB oder irgendeinem Schwellenwert, sagt, ab hier arbeiten wir nur noch mit Lazy Loading.
Das bedeutet, dass auch beim Clone, Fetch und Co.
einfach die Dateien initial einfach mal gar nicht übertragen werden, sondern die liegen irgendwo auf einem Object Storage, bei euch auf dem Server oder bei dem Forge auf dem Server.
Und wenn der Client drauf zugreift, dann findet das Lazy Loading, das Fetching statt, weil dann könnte man sagen, okay, man reduziert die Netzwerkbandbreite enormst und die Annahme wäre jetzt hier, dass die großen Binary-Dateien selten angefasst werden oder dass kleinere Dateien mehr angefasst werden.
Und das ist auch genau eine der Sachen, eine der großen Projekte, die wir momentan angehen.
Und da gehen wir auch wieder ein bisschen zurück zu dem eigentlichen Thema, wird Git eigentlich immer zentraler, wird es.
Genau durch solche Probleme.
Je größer deine Repositories werden, desto mehr muss Git halt ein bisschen zentraler werden, weil du halt irgendwann quasi den Load nicht mehr handeln kannst.
Du kannst keine Repositories lokal haben, die 500 Gigabyte groß sind.
Das passt bei vielen Entwicklern gar nicht mehr auf die Festplatte rauf.
Und das, was du gerade beschreibst, gibt es tatsächlich schon im Git.
Das nennt sich erstmal Promisser Remotes bzw.
Partial Clones.
Das heißt, du kannst sagen, git Clone-Object Filter, nee, ich glaube, das ist das-Filter, nicht Object Filter.
Und dann kannst du quasi sagen, welche Objekte herausgefiltert werden sollen beim initialen Clone.
Kann beispielsweise, genauso wie du gerade gesagt hast, jede Blobdatei, die größer als ein Megabyte ist, soll rausgefiltert werden.
Das heißt, sie sagt, git Clone-Filter equals Blob Colon Limit gleich 1m.
Und dann würdest du genau so einen Clone bekommen, wo erstmal alle Objekte größer als 1 Megabyte rausgefiltert worden sind.
Und jedes Mal, wenn du dann beispielsweise einen anderen Commit auscheckst, wo genau so ein Blob jetzt benötigt wird, dann wird Git automatisch diesen Blob von dem Remote fetchen und dann reinlegen.
Das Problem hier ist allerdings, dass es noch relativ komplex ist.
Und ich würde behaupten, dass die wenigsten von Partial Clones überhaupt schon mal gehört haben.
Und die Frage ist vor allem auch, wie genau soll dieser Filter jetzt eigentlich aussehen.
Weil je nach Server kann es ja beispielsweise auch unterschiedlich effektiv sein.
Der eine Server kann beispielsweise vielleicht ein gewisses Special Casing haben für sehr große Binärdateien, sodass die vielleicht irgendwo ganz woanders liegen.
Das heißt, der Server weiß eigentlich, was ist der beste Filter für dich.
Und da gehen wir jetzt an die Large Object Promises ran.
Das ist ein Feature, was wir gerade sind, in Git dabei sind, in Git zu implementieren.
Und die Idee dahinter ist, dass der Server, wenn er Client einen Fetch oder einen Clone macht, dir mitteilt, guck mal, das sind meine Promise-Remotes, die ich kenne.
Und das sind die jeweiligen Filter, die in diesem Promisser-Remotes dranhängen.
Du kannst dich jetzt dazu entscheiden, einen von dieser Promiser oder alle von denen zu benutzen.
Das heißt, du würdest dann auf der Client-Seite nur noch sagen, Git Clone, Filter, Auto und da wirst du automatisch quasi einen idealen Filter benutzen, der dann in deiner Konfiguration von Git gespeichert wird.
Und von da aus gehend wirst du dann immer die Remotes benutzen, die der Server dir, oder die Promisser-Remotes benutzen, die der Server dir genannt hat.
Das ist noch nicht komplett fertig.
Die Partial Clones funktionieren, aber die Large Object Promises machen wir jetzt gerade noch so die finalen Schritte, sodass quasi dann auch die Konfiguration wirklich auf der Client-Seite auch persistiert wird, wenn der Server dir sowas announzt, mehr oder weniger.
Diese Episode gibt mir einen ganz komischen Vibe, muss ich sagen.
Auf der einen Seite habe ich gerade ganz kurz gedacht, ich bin an was ganz Großem dran.
Somit, dass der Patrick gesagt hat, Anni hat recht, das wird jetzt als zentraler und so weiter.
Ich habe gesagt, wow, ich bin hier an was ganz Großem dran.
Auf der anderen Seite kommt er damit Features um die Ecke und ich habe gerade so das Gefühl, ich habe keine Ahnung, was Git ist.
Ich benutze es irgendwie jeden Tag, meine sechs, sieben, acht Befehle.
Und du haust hier Partial Clones, kannte ich, Shallow Clones kannte ich, Bare Repositories, all die Thematiken kannte ich.
Aber das, was du da gerade erzählst, da bin ich einfach raus.
Also schon faszinierend.
Aber du gibst mir auch ein gutes Gefühl, nachdem du nämlich gerade gesagt hast, okay, du arbeitest schon mit Git so lange und du lernst immer noch irgendwelche Command-Line-Flex oder ähnliches kennen.
Was ich aber auch interessant fand, dass du gerade zum Beispiel bei den Rev Tables Tombstones erwähnt hast, jetzt kommst du mit Pluggable Object Databases um die Ecke.
Das gibt mir so ein bisschen so, ich nenne es mal Object Storage Vibes, ja, so Amazon S3 und Co.
Also das bedeutet, habt ihr dann vielleicht irgendeine Art Tiered Storage als File-Backend späten hinterten dran im Git?
Und da frage ich mich natürlich, und nicht frage ich, ich finde das schön zu sehen, dass ziemlich viele Elemente, die weiß ich nicht, aus verschiedenen Bereichen kommt.
Tombstones kommt, glaube ich, aus der aus der Datenbankwelt, um Delites ebenfalls effizienter zu gestalten.
Object Storage, keine Ahnung.
Zumindest alle Datenbanken binden das jetzt gerade auch ein.
Also du kannst fast Tabellen auf Object Storage legen oder Tier Storage, gibt es ja schon seit Ewigkeiten in der Datenbank.
Da finde ich schon interessant, dass auch sowas mehr oder weniger Cleintseitiges Lokales.
Und natürlich, wie Git das anbindet.
Klar, das ist jetzt alles auf Serverseite hier.
Aber interessant, interessant.
Wie viel Inspiration nehmt ihr euch denn aus aus der Datenbankwelt oder aus der aus anderen Segmenten der Entwicklung Informatik?
Ich würde sagen, zu wenig.
Deutlich zu wenig.
Eines der wesentlichen Probleme, die wir vor allem hatten, ist, dass Git relativ lange Zeit ziemlich stagnant war in seiner Entwicklung.
Das heißt, ich würde, ich würde behaupten, wir haben ein bisschen zu lange geschlafen.
Wir haben quasi gesehen, dass es Skalierungsprobleme gibt.
Aber wir haben immer weiter daran rumgeschraubt, unser lokales Optimum, was wir hatten, weiter zu optimieren.
Hier vielleicht nochmal eine wesentliche Optimierung zu machen in der Art und Weise, wie wir alles handeln.
Da nochmal eine kleine Optimierung.
Und es hat dann auch oftmals geholfen, die Probleme, die wir dann akut hatten, zu beheben.
Aber es hat halt nicht so wirklich geholfen, wirklich auch die langfristigen Probleme zu, also handeln zu können.
Quasi mit der wachsenden Größe an Repositories auch weiterhin umgehen zu können.
Weil mit lokalen Optimierungen kommst du halt nur so weit.
Und deswegen kommen halt vor allem so eine Sachen wie REFTables und jetzt halt auch Pluggable Object Databases.
Und da ist natürlich meine Idee auch, ich möchte nicht immer das Rad neu erfinden.
Ich möchte halt auch einfach mal Technologien benutzen, die schon existieren.
Wie du schon meintest, Blob Storage oder Object Storage, S3.
Warum benutzen wir sowas nicht?
Warum können wir sowas nicht mal eben benutzen?
Naja, weil Git halt dafür ursprünglich nicht designt wurde.
Es ist halt 20 Jahre alt und vor 20 Jahren gab es das Zeugs alles noch nicht so wirklich.
Klar, ich meine, Datenbanken gab es natürlich schon und wahrscheinlich gab es auch schon Tombstones.
Aber gerade am Anfang wurde halt erstmal quasi alles sehr speziell nur für Git entwickelt.
Und da sind wir es halt gerade.
Das heißt, wir müssen jetzt erstmal aufschließen, quasi mit der Industrie, um uns die Möglichkeit zu geben, dann auch aktuelle Trends vielleicht für Git zu benutzen und dadurch besser skalieren zu können.
Wobei ich muss ja da jetzt als Datenbank-Fan nach einwerfen, es gibt ja auch die umgekehrte Seite, so wie Git Butler zum Beispiel, die dann Git als Datenbank verwenden.
Also was die an Metadaten und so weiter haben, speichern die alles, also die missbrauchen fast Git, um dort drin dann alle Daten zu speichern.
Ich muss sagen, ich freue mich sehr darüber, dass Git Butler genannt wird, weil ich die Firma super gerne mag.
Ich habe mit denen viel zu tun und auch mit dem Scott habe ich schon regelmäßig über die ganzen Thematiken gequatscht.
Und sie gehen halt auch viele neue Wege im Git-Projekt und versuchen auch wieder so ein bisschen Innovation reinzubringen.
Und ja, man sieht es definitiv, dass viele Projekte, auch GitButler, versuchen, alle möglichen Metadaten in Git reinzuspeichern.
Und man sieht auch beispielsweise auf der Git Mailingliste, kommen immer mal wieder Leute ran, die sagen, hier, guck mal, ich will eine Datenbank implementieren in Git, weil Git mir schon so viele Sachen gibt, beispielsweise Versionierung und dann brauchen wir mich ja um so viel anderes gar nicht mehr zu kümmern.
Man muss aber auch dazu sagen, Git ist keine universelle Datenbank.
Du wirst halt Probleme haben in Git, die du halt mit einer ordentlichen Datenbank Lösung nicht haben würdest.
Weil Git halt einfach nicht dafür gemacht ist.
Git ist halt eine sehr, sehr spezielle Datenbank, die für ein ganz konkretes Problem gebaut würde.
Und zwar halt Versionskontrollsysteme und Versionierung davon.
Dementsprechend ist, man kommt wahrscheinlich bis in einem gewissen Grad auch wirklich voran, wenn man Git als Datenbank benutzen möchte.
Aber ideal ist es dafür nicht und ich rate immer jeden davon, davon auch wirklich Abstand zu nehmen und vielleicht eine ordentliche Datenbank zu benutzen für das Problem, was sie lösen möchten, weil sie ansonsten sehr schnell auch an Skalierungsprobleme rankommen werden, wenn sie halt so sehr Datenbankspezifische Probleme lösen wollen.
Jetzt hast du ganz am Anfang schon gesagt, was wir uns wirklich anschauen sollten, ist Interactive Rebase.
Wenn du jetzt in die Zukunft blickst, 2027, auf welches Feature freust du dich am meisten, dass dann alle Entwickler sich anschauen müssten.
Ich hatte es ja schon einmal ganz kurz erwähnt.
Git History ist so eines der neuen Tools, die ich sehr interessant finde, weil wir mit Git History versuchen, die Usability so ein bisschen gerade zu ziehen in Git.
Git ist ja ziemlich bekannt dafür, dass das User-Interface jetzt nicht unbedingt das gelbe vom Ei ist, sondern doch viele, viele verschiedene Stellen hat, wo man denkt, könnte ja durchaus besser sein, könnte durchaus konsistenter sein und so weiter.
Und Git History wird jetzt nicht alles auf einmal konsistent machen.
Es geht gar nicht so wirklich, weil naja, Git ist halt organisch gewachsen über viele Jahre.
Und mit einem weiteren Command wird man jetzt nicht alles andere konsistent machen.
Aber was wir mit Git History machen wollen, ist halt ein einfaches Tool bereitstellen, mit dem du deine Repository History anpassen kannst.
Das heißt, es wird Subcommands bereitstellen, wie beispielsweise, ich möchte die Commit-Message anfassen, ich möchte einen Commit aufsplitten in zwei, ich möchte Commits reordern, ich möchte mehrere Commits zusammen mergen in eins und so weiter.
Und zusätzlich eine weitere Sache, die Git History auch anders macht als Git Rebase, ist, dass die Idee dahinter ist, dass es Stack Branch Workflows erlauben soll.
Stack Branch ist quasi, dass man mehrere Branches hat, die aufeinander aufbauen, wo man quasi gleichzeitig ist, die alle zu entwickeln und irgendwann dann quasi nach und nach die einzelnen Branches abstreamt.
Das heißt es allerdings, wenn ich jetzt quasi mehrere Branches habe, die aufeinander aufbauen und ich im untersten Branch irgendwie was anpasse, muss ich alle Branches, die darauf aufbauen, auch nochmal rebasen, was natürlich super, super nervig ist für einen Nutzer.
Und GitHistory geht da quasi einen anderen Weg und sagt, wenn du die Commit-Message von einem Commit im ersten Branch anpasst, werden automatisch alle anderen Branches auch gerebased, sodass du dann quasi den neuen Commit auch mit beinhalten.
Der Nutzer muss sich nicht mehr damit selber auseinandersetzen.
Da wird es noch einige weitere Sachen geben, an dem wir arbeiten werden.
Vor allem sind viele Features da von Jiu Jitsu ein bisschen inspiriert, was ein relativ neuer Git-kompatibler Command-Line-Client ist.
Heißt, wir wollen beispielsweise so etwas wie First Class Conflicts haben, dass du quasi Konflikte auch direkt in der GitHistory erstmal abspeichern kannst und direkt weitermachen kannst, sodass du die Konflikte erst zu einem späteren Zeitpunkt wirklich beheben kannst.
Change-IDs werden da unter Umständen auch schon mal von relevant sein, wo eine Change-ID quasi ein Identifier von einem bestimmten Commit ist, der sich aber nicht ändert.
Weil wir haben ja vorhin schon gesagt, wir haben erstmal die Objektnamen, also die Object-IDs, die von dem Hash ausgehen.
Das heißt aber auch, wenn du den Commit irgendwann änderst, wird sich natürlich den Name des Objektes auch ändern.
Die Change-ID allerdings wird konstant bleiben, sodass du den gleichen Commit dann über die Change-ID referenzieren kannst, ohne dass sich das irgendwie ändert.
Das heißt, wenn ich dem beispielsweise umgeschrieben habe, kann ich weiterhin die gleiche Change-ID benutzen.
Wann werden wir Git History verwenden können?
2027 habe ich schon gesagt, das sollte ja dann halten.
Geht es früher auch noch?
In zwei Wochen kommt die nächste Git-Version raus und da ist der erste Stand von Git History mit drin.
Okay, perfekt.
Das ist ja eine Anzeige.
Ich glaube, es sind tatsächlich drei Wochen, keine zwei Wochen.
Aber auf jeden Fall bald.
Aber Git History wird anfangs erstmal sehr eingeschränkt sein.
Es gibt anfangs erstmal nur zwei Subcommands sein.
Das ist einerseits Git History ReWord, um halt die Commit-Message um ändern zu können.
Und dann ist es andererseits Git History Split, um einen Commit in zwei Commits aufzusplitten.
Das ist es erstmal.
Wir werden im nächsten Release-Zyklus aber weiter daran arbeiten und mehr Commands implementieren.
Aber das ist noch der normale Zweier-Branch, Git 2.
Ganz normale Version.
Es ist ja keine rückwärts-inkompatible Änderung, sondern es ist ja einfach nur ein weiterer Befehl, der hinzugefügt wird.
Und das kann man ja auch einfach in einem ganz normalen Release machen.
Wolfgang, nicht immer fordern, ja, auch mal machen.
Ich bin mir sicher, dass wenn du den Patrick fragst, ob der dir mal eine Stunde Code-Einführung in Git gibt, in Pearl wolltest du jetzt sagen.
In was auch immer, ja.
Du hast gerade hier gesagt, Pearl war deine erste Programmiersprache und du bist fast fluent da drin.
Also da würde ich sagen, du bist willkommen als neue.
Ja, ich hätte das Add-Symbol, ja.
Als Git-Contributor von daher.
Also ich würde mich auf jeden Fall freuen.
So, Wolfgang.
Pressure ist da.
Aber ich würde auch mal sagen, in einer Stunde kommt man da nicht allzu weiter, als die Git-Codebasis dann doch ein bisschen zu kompliziert und komplex.
Ja, gut, also ich würde dem Wolfi schon vom Wolfi schon erwarten, dass der dann einmal Cloud Code rüber jagt und sagt, erklär mir mal ein bisschen die Grundpfeile hier von der Codebase und dass da dann für die Stunde mit gezielten Fragen auf dich zukommt.
Jetzt habe ich mir gedacht, wir schaffen eine Episode ohne den Wort irgendwas mit AI.
Aber jetzt hast du es wieder versaut, Andi.
Nee, ich habe es nicht versaut.
Ich motiviere dich jetzt endlich mal zu Git zu kontribüten, damit wir nämlich Git History schneller bekommen können.
So sieht's aus.
Welches Wochenende ist da eine andere Sache?
Das Lustige ist, und wir kommen jetzt auch zum Ende dieser Episode.
Das Lustige ist, der Patrick und der Wolfgang und ich, wir hatten im Vorgespräch so darüber gesprochen, sag mal, wir haben noch gar keine Episode zum Einstieg zu Git.
Was ist Git eigentlich?
Wie funktioniert Git unter der Haube?
So, wie speichert Daten, wie machst du eigentlich dein eigenes Git-Repository mit fünf Shell-Befehlen und so Thematiken und was ist eigentlich ein Git, was passiert dann so?
Da haben wir gesagt, ja, nee, da haben wir den Patricker hier, da können wir ja keine Git-Basis-Folge machen.
Dann lass uns mal ein bisschen tiefer gehen.
Und jetzt komme ich aus dieser Episode raus und fühle mich wie ein totaler Anfänger.
Ich habe das Gefühl, das war so die Git-Basis-Folge für mich.
Aber Wahnsinn.
Und ich habe mich auch immer gefragt, warum hat Git als Command-Line-Parameter bei manchen Befehlen Porzellan drin?
Hä?
Und jetzt habe ich es verstanden.
Ich habe auch noch nie das Git-Internals-Buch mit Plumber und Porzellan und mit der Befehlsstruktur und so weiter gelesen.
Wahnsinn.
Das ist auf jeden Fall etwas, was ich nicht mehr vergessen werde.
Und Patrick, vielen lieben Dank.
Und ich denke, wir haben auch ein paar gute Themen auf der Server-Seite gecovert, die die meisten Leute, glaube ich, gar nicht so auf dem Schirm haben.
Denn ich würde sagen, ja, 99, weiß ich nicht, wie viel Prozent der Leute arbeiten kleinseitig.
Vielleicht hostet der ein oder andere vielleicht einen Forge, aber ich glaube, mit den ganzen Themen, über die wir gesprochen haben, kommen die meisten dann auch nicht in Berührung, wenn man das die ganze Sache nicht zumindest professionell anbietet oder in einem sehr großen Stil.
Patrick, vielen lieben Dank, dass du dir die Zeit genommen hast, mit uns über Git zu sprechen.
Eins deiner Lieblingsthemen.
Und wir haben natürlich auch in den Shownotes etliche Links vergraben, unter anderem auch zu deinem Fosselem-Talk, Evolving Git for the Next Decade, wo, ja, ich würde fast sagen, ziemlich viele oder fast alle der Themen, die wir heute besprochen haben, auch Anklang finden.
Vielleicht nicht die Diskussion über das zentrale Repositories.
Aber nur gut.
Ja, vielen Dank.
Hast du noch einen letzten Satz für unsere Hörerinnen und Hörerinnen?
Ich glaube, das Wesentliche, was ich gerne noch mitgeben möchte, ist, dass Git sich nach wie vor verändert.
Denn viele, wie du schon meintest, viele Leute sagen einfach nur, ja, ich bin jetzt meine fünf Befehle und ansonsten ändert sich ja ein Git absolut gar nichts.
Stimmt aber nicht so ganz.
Wir arbeiten daran, viele Sachen effizienter zu machen, neue Use Cases zu erlauben und Git ist auf jeden Fall nicht eingestaubt und nicht komplett eingerostet, sondern es gibt Fortschritt.
Super.
Ich werde das ab dieser Folge das Changelog vermehrt lesen.
Das habe ich nämlich vorher zumindest nicht so gemacht, wie ich es tun sollte, glaube ich.
Ich kann nur sagen, Vorsicht, denn der Changelog, der offizielle Changelog vom Git-Projekt ist relativ technisch.
Es ist meistens leichter, die Blogposts von GitLab und GitHub zu lesen, weil die ein bisschen tiefer reinsteigen in die einzelnen Themen und auch so ein bisschen Kontext geben.
Das ist doch mal ein wundervoller Tipp für neuen Lesestoff.
Patrick, vielen lieben Dank an alle anderen.
Ihr wisst, wo ihr uns findet.
Falls ihr Feedback zu dieser Folge habt oder Feedback auch direkt an Patrick, schickt uns das einfach, wir leiten das sehr, sehr gerne weiter.
Ansonsten würde ich sagen, wir hören uns nächste Woche wieder.
Und tschüss.
Ciao.
Ciao.
