Das Versionskontrollsystem Git wurde am 7. April 2005 vom "Vater" des Linux-Kernels, Linus Torvalds, veröffentlicht. Heute feiern wir den 20. Jahrestag dieses wichtigen Projekts, das mittlerweile von fast allen Entwickler(inne)n verwendet wird. Zu diesem Anlass habe ich mit Linus über die Geschichte von Git und darüber gesprochen, warum er die Rolle des Chefentwicklers von Git abgegeben hat und was seiner Meinung nach die wichtigsten Meilensteine sind.
2005 warst du bereits Betreuer des aufstrebenden Linux-Kernels. Warum hast du dich entschieden, ein neues Versionskontrollsystem zu entwickeln?
Anfangs habe ich Versionskontrolle wirklich gehasst.
Ich habe herkömmliche Versionskontrollsysteme (CVS/RCS/SCCS) sowohl als Endbenutzer (z. B. beim Nachverfolgen von Open-Source-Projekten wie GCC) als auch als Entwickler (bei Transmeta haben wir für alles CVS genutzt) kennengelernt und hatte wirklich eine tiefe Abneigung dagegen.

Damals wechselten die meisten Projekte, die CVS verwendeten, vermutlich zu SVN, aber für mich war das ehrlich gesagt nur Schönrederei. SVN war ja nichts als CVS in einer anderen Form und mit einem geringfügig besseren UI, aber die grundlegenden Dinge waren nicht besser und es wurden sogar einige neue Probleme hinzugefügt.
Es gibt zu viele Probleme mit CVS und den anderen Lösungen, um sie hier alle aufzulisten. Glücklicherweise wurden sie alle zum Großteil obsolet und junge Entwickler(innen) müssen sich wahrscheinlich nie mit einem dieser Systeme beschäftigen. Ich weigerte mich also kategorisch, für den Kernel damit zu arbeiten, auch wenn wir für die Nachverfolgung des Codes einiger Untersysteme (vor allem beim Netzwerk) in den 90ern tatsächlich CVS verwendeten.
Damals lebte ich in der Bay Area. Larry McVoy, den ich von früheren Projekten kannte (vor allem von Imbench), hatte BitMover gegründet, bei dem ein neues Versionskontrollmodell namens BitKeeper, oder kurz BK, verwendet wurde.
BK war zwar nicht Open Source, aber Larry hatte eine Vorliebe für Open-Source-Projekte und hatte das Gefühl, dass die fehlende Versionskontrolle die Entwicklung des Kernels wirklich ausbremste. Er hatte nicht unrecht, aber die traditionelle Quellcodeverwaltung funktionierte für mich einfach nicht. Larry verbrachte einige Zeit damit, mir und David Miller (einem Netzwerkbetreuer und bestehendem CVS-Benutzer) zu zeigen, was BitKeeper alles konnte.
BK war nicht perfekt und basierte wie so viele andere Systeme zur Quellcodeverwaltung auf dem Source Code Control System (SCCS) und setzte daher wie alle anderen auf dasselbe unzureichende Modell mit „dateibasiertem Verlauf“. Dieses verursachte riesige, fundamentale Probleme, wenn Dateien umbenannt und gelöscht wurden.
Andererseits war BK nicht nur reine Schönrederei. Es basierte zwar grundlegend auf SCCS, aber auf höherer Ebene behob es einige wirklich fundamentale Probleme und ermöglichte eine echte verteilte Entwicklung. Zudem hatte es einen echten globalen – keinen reinen dateibasierten – Verlauf, sodass es tatsächlich Code von verschiedenen Entwicklungszweigen zusammenführen konnte.
Mit CVS war das Erstellen von Branches und deren Zusammenführung etwas, das man mit anderen planen und besprechen musste – also ein großes Ereignis. Mit BK war jedes Repository ein Branch. Heute halten wir das für selbstverständlich, und natürlich ist Git noch viel weiter gegangen: Es gibt viele Branches pro Repository. Doch auch das viel eingeschränktere Modell von BK war zu diesem Zeitpunkt ein echter Wendepunkt.
Aber wie gesagt, BK war nicht perfekt. Es nutzte einen dateibasierten Verlauf, was ein fundamentales Problem ist, denn dadurch können Dateien einfach nicht zuverlässig umbenannt und zusammengeführt werden, was unvermeidlich zu Chaos und Probleme führt (alle, die CVS kennen: Denkt an Attic …). Außerdem gab es Einschränkungen bei der Skalierbarkeit. Diese wurden aber nur langsam etwas problematischer.
Das größte Problem bei BK war die Lizenzierung. Auch wenn im Laufe der Jahre (wir verwendeten BK von 2002 bis 2005) viele Kernel-Betreuer(innen) zu diesem System wechselten, gab es immer wieder Schwierigkeiten damit. Diese Schwierigkeiten spitzten sich Ende 2004 zu, als der Einsatz von BK für den Kernel einige Monate später praktisch nicht mehr möglich war.
Ich war nun in der Situation, dass ich drei Jahre lang endlich eine Versionskontrolle verwendet hatte, die tatsächlich funktionierte und viele Probleme gelöst hat. Ich wollte also keinesfalls wieder zum Zustand vor der Versionskontrolle zurückkehren, doch in den Jahren, in denen wir BK eingesetzt hatten, war von der Open-Source-Community nicht wirklich eine bessere Lösung gekommen.
Sicher, die Leute wussten, dass CVS und SVN nicht wirklich gut funktionierten, und es gab Projekte, in denen alternative Ansätze verfolgt wurden, doch diese waren teilweise sogar noch schlechter (sie waren im Grunde einfach nur schick verpacktes Patch-Tracking). Einige dagegen hatten zwar gute Ideen, machten aber schreckliche Entwicklungsfehler (siehe Monotone).
Ich sah mich also eine Weile um und erkannte dann, dass es nur einen Ausweg gab: Ich musste meine eigene Lösung programmieren.
Technisch gesehen dauerte es nur wenige Tage, die erste Version von Git zu erstellen – das kann man alles im Git-Commit-Verlauf nachlesen. Dort sieht man wunderbar, wie es von quasi Null zu einer gerade so nutzbaren Lösung wurde, für die ich dann eine Woche später Patches veröffentlichte (und die dann einige Tage danach aktiv für den Kernel verwendet wurde).
Dabei wird aber die Tatsache außer Acht gelassen, dass ich bis zu diesem Zeitpunkt schon eine Weile über das Problem nachgedacht hatte. Programmieren ist einfach. Ein gutes Konzept ist das, was zählt. Hinter diesen wenigen Tagen steckt also einiges an Vorarbeit, die sehr wichtig ist – und das sieht man im Verlauf nicht.
Diese erste Version war sehr, sehr einfach und konnte vieles von dem nicht, was später noch kommen sollte. Man kann aber auch in diesen ersten Tagen schon viel vom Kernkonzept sehen.
Kannst du uns einen kurzen Rückblick über die ersten Tage und Wochen des Git-Projekts geben?
Ich hatte im Grunde beschlossen, die Kernel-Entwicklung einzustellen, bis ich eine Alternative hatte, die für mich funktionierte. Das Resultat sollte eine verteilte Entwicklung und Höchstleistung ermöglichen sowie ein System sein, mit dem man absolut verlässlich jegliche Beeinträchtigung verhindern kann.
Ich möchte betonen, dass ich mich nicht wirklich für Quellcodeverwaltungssysteme interessierte. Ich war am Endergebnis interessiert, nicht am Prozess. Git war mir also nie so wichtig wie der Kernel: Ich arbeite an Linux, weil ich Kernels spannend finde. Ich habe an Git gearbeitet, weil ich es musste.
Damit wären wir dann auch schon bei deiner nächsten Frage.
Du hast die Rolle des Chefentwicklers von Git nach einigen Monaten an Junio Hamano übergeben, der dies noch immer ist. Warum hast du deine Position abgegeben, und warum an Junio?
Die Übergabe der Rolle war keine schwierige Entscheidung. Es war vielmehr so: „Sobald ich jemanden finde, dem ich das Projekt anvertrauen kann, gehe ich wieder zurück und arbeite nur noch am Kernel.“
Das soll nicht heißen, dass ich einfach alles hingeworfen und auf das Beste gehofft habe. Ich war rund vier Monate lang Chefentwickler von Git, weil ich spürte, dass ich jemanden finden musste, der gekommen war, um zu bleiben, und der diesen ominösen „guten Riecher“ hatte.
Junio war als einer der Ersten dabei – quasi ab der ersten Woche. Aber ich bin nicht einfach zu ihm hin gerannt und habe gesagt: „Du bist dran.“ Es braucht eine Weile, bis man sieht, wer wirklich dabei bleibt und wer sinnvollen Code schreibt und sinnvolle Entscheidungen trifft.
Und ich denke, Junio war ein echtes Vorbild. Ich bekomme viel zu viel Lob für die paar Monate, die ich in Git gesteckt habe – besonders angesichts des 20-jährigen Jubiläums. Ich bin zwar dafür verantwortlich, dass das Kernkonzept richtig umgesetzt und das Projekt zum Laufen gebracht wurde, aber Junio hat das Projekt wirklich geleitet (damit will ich nicht die hunderten anderen Beteiligten vergessen).
Die erste Version des Versionskontrollsystems Mercurial wurde 12 Tage nach der ersten Version von Git am 19. April 2005 veröffentlicht. Viele Leute behaupten, dass die User Experience von Mercurial der von Git überlegen war, aber heute ist Git deutlich beliebter. Warum glaubst du, hat Git sich gegen Mercurial durchgesetzt?
Oh, ein großer Teil davon sind offensichtlich nur Netzwerkeffekte, und Quellcodeverwaltungssysteme haben sehr starke Netzwerkeffekte. Deshalb hat CVS trotz all seiner Einschränkungen so lange überlebt.
Der Kernel verwendete Git und es wurde irgendwann in der Community von Ruby on Rails sehr beliebt – und dann setzte es sich überall durch.
Aber ich bin wirklich überzeugt, dass das Konzept von Git besser ist. Das Kernmodell ist sowohl sehr einfach als auch sehr leistungsfähig, und ich denke, das machte es einfacher, es in andere Umgebungen zu übertragen. JGit war ein frühes Beispiel dafür, aber es gibt natürlich Implementierungen wie das virtuelle Dateisystem MSgit usw.
Während Git anfangs berühmt-berüchtigterweise schwierig zu nutzen war, glaube ich, dass vieles davon darauf zurückzuführen ist, dass die Leute Dinge zuvor „richtig“ machen mussten. Die Leute kamen nämlich von anderen Umgebungen und fanden Git nicht intuitiv, da Git ein paar harte Entscheidungen getroffen hatte, die Nutzer(innen) von herkömmlichen Quellcodeverwaltungssystemen niemals gemacht hätten.
Das Git-Projekt ist nie stehengeblieben, seit du die Rolle des Chefentwicklers an Junio übergeben hast, und die Community arbeitet kontinuierlich an neuen Funktionen. Was waren deiner Meinung nach die wichtigsten Meilensteine, nachdem du das Projekt verlassen hast?
Das ist schwer zu beantworten, da ich Git ja so entwickelt hatte, dass es für mich funktionierte. Die Dinge, die ich verwende, haben also quasi vom ersten Tag an funktioniert. Ein offensichtliches Beispiel: Für viele Leute war es offensichtlich ein riesiger Schritt, Git auf Windows zum Laufen zu bringen, aber mich betraf das überhaupt nicht. ;-)
Git hat ja auch eine ganze Infrastruktur, mit der es einfacher zu nutzen ist. Die größten Meilensteine entstanden meiner Meinung nach aber, als die Menschen die Git-Infrastruktur heranzogen und Dinge darauf aufbauend entwickelten. Diese fließen natürlich oft auch wieder in Git-Funktionen ein, aber gleichzeitig ist der Meilenstein etwas Externes.
Ein offensichtliches Beispiel: Alle großen Git-Hosting-Websites waren große Meilensteine. Dadurch, dass Git verteilt war, waren diese viel einfacher zu entwickeln, aber der Meilenstein war dann, dass das Hosting es den Benutzer(innen) so einfach machte, Git für verschiedenste Projekte zu nutzen.
Wenn du wieder in der Lage wärst, hauptberuflich an Git zu arbeiten, gäbe es etwas, das du gerne implementieren würdest?
Auf keinen Fall. Git hat von Anfang an alles getan, was ich brauchte – ich nutze es tatsächlich nur ziemlich eingeschränkt, und mir ist nur ein Projekt wichtig.
Und ich sage „Auf keinen Fall“, weil ich mich auf eine meiner früheren Antworten beziehe: Ich war noch nie wirklich an Quellcodeverwaltungssystemen interessiert. Ich denke, ein wichtiger Grund dafür, dass Git sich von anderen Quellcodeverwaltungssystemen so sehr unterscheidet – größtenteils im positiven Sinne – ist, dass ich Git eher wie ein verteiltes Journaling-Dateisystem angegangen bin und nicht wie eine herkömmliche Quellcodeverwaltung.
Gibt es eine Funktion oder eine konzeptionelle Entscheidung in Git, die du im Nachhinein bereust?
Konzeptionelle Entscheidungen? Nein. Ich bin immer noch überzeugt, dass das übergeordnete Konzept sehr gut ist. Man kann verschiedene Git-Konzepte diskutieren, ohne auf die kleinteilige Komplexität der eigentlichen Implementierung eingehen zu müssen.
Und ich denke, das ist wichtig in einem Projekt. Man benötigt ein bestimmtes übergeordnetes Prinzip, dem die konzeptionelle Ausrichtung eines Projekts folgt.
Manchmal treiben die Leute das zu weit und denken, dass das übergeordnete Konzept bedeutet, dass die Implementierung dann sklavisch einem Kernprinzip folgen muss. Das ist aber auch falsch – die Implementierung hat viele hässliche Grenzfälle, da die Realität nun einmal hart ist und Menschen seltsame Dinge wollen. Es ist schon eine Art übergeordnetes Konzept nötig, auf das man sich beziehen kann und über das man auf übergeordneter Ebene argumentieren kann, bevor man sich die Hände an der harten Realität schmutzig macht.
Ich denke, Git hat da ein gutes Gleichgewicht gefunden. Ein sehr geradliniges Objektspeicher-Konzept („strukturierte Merkle-Bäume“, wenn du aus dem CS-Bereich kommst, oder stell sie dir einfach als „inhaltsadressierbaren Speicher“ vor, wenn du aus dem Dateisystem-Bereich kommst). Dieses Kernkonzept ist da, ist aber gleichzeitig in der Realität nur ein winziger Teil des eigentlichen Codes. Der größte Teil des Codes betrifft all die Dinge, die man mit dem Kernkonzept machen kann. Diese grundlegende konzeptionelle Klarheit gibt dem Projekt trotzdem eine Art übergeordnete Struktur.
Es ist die gleiche Art von übergeordneter Struktur, die Unix selbst hatte, von „alles ist eine Datei“ bis hin zur Prozessabwicklung. Es gibt zwar ein paar übergeordnete „Konzepte“, aber bei 99 % des Codes geht es ganz einfach darum, das, was man auf diesem Design aufgebaut ist, so zu gestalten, dass es uns in der realen Welt nutzt.
Ich habe zwei Mantras hinsichtlich der Technologie: „Wenn ich weiter geblickt habe, so deshalb, weil ich auf den Schultern von Riesen stehe“ (Newton) und „Genie ist 1 % Inspiration und 99 % Prozent Transpiration“ (Edison).
Aber da wir schon über die 99 % Transpiration sprechen: Obwohl ich mit dem Gesamtdesign sehr zufrieden bin, gibt es sicherlich verschiedene Details, die ich anders gemacht hätte, wenn ich Git heute entwickeln würde.
Ehrlich gesagt, sind sie aber nicht so wichtig. Viel wichtiger sind all die guten Details, die in den letzten zwei Jahrzehnten entwickelt wurden.
Im Linux-Kernel wurde Rust als Programmiersprache für einige der Subsysteme eingeführt. Glaubst du, dass es sinnvoll ist, solche neueren Programmiersprachen auch in Git zu verwenden?
Ich vermute, dass es bei Git weniger Gründe gibt, Sprachen zu mischen, was immer etwas schwierig ist.
Im Kernel ist das Endergebnis eine einzige Kernel-Binärdatei – auch wenn der Großteil davon dynamisch als Module geladen werden kann, sind sie immer noch effektiv in einer einzige Binärdatei verbunden.
Das macht die Verwendung mehrerer Sprachen komplexer. Andererseits gibt es für den Kernel auch mehr Gründe, sich mit der Speichersicherheit und folglich mit neueren Sprachen zu befassen.
Wenn jemand Teile von Git in Rust oder einer anderen Programmiersprache schreiben möchte, ist es vermutlich viel sinnvoller, einfach eine separate Implementierung zu erstellen, anstatt zu versuchen, in einer Binärdatei mehrere Sprachen zu mischen.
Die Kernideen von Git sind im Grunde so einfach, dass es vermutlich nicht allzu schwierig ist, einfach parallele Implementierungen des Kernel zu haben. Dann kann man bestimmte Problembereiche gezielt angehen, in denen unterschiedliche Sprachen sinnvoll sind.
Das haben wir natürlich schon in Git gesehen: Genau das ist JGit. Hier wurde eine andere Programmiersprache verwendet, die sinnvoller für die webbasierte Umgebung war.
Ich weiß, dass es bereits Rust-Implementierungen einiger der Kernfunktionen von Git gibt. Hier ist die Situation vermutlich ähnlich: Sie werden in bestimmten Situationen sinnvoller sein als einfach alles in Rust umzuwandeln.
Allen, die sich für die Implementierung mit Rust interessieren, empfehle ich, nach Bereichen Ausschau zu halten, in denen die Vorteile von Rust offensichtlicher sind. Ich glaube nicht, dass die Verwendung von C für den Standard-Quellcode von Git wirklich so problematisch ist.
Alle paar Jahre tauchen neue Versionskontrollsysteme auf. Glaubst du, dass Git auch in Zukunft vorne dabei bleiben wird?
Ich habe bereits die Netzwerkeffekte bei Quellcodeverwaltungssystemen erwähnt. Meiner Meinung nach muss ein neues System daher nicht einfach nur ein bisschen, sondern viel, viel besser sein, um Git zu ersetzen. Oder aber so kompatibel, dass es dann eigentlich nur eine neue Implementierung von Git ist.
Ich denke, dass sich die Situation in der Quellcodeverwaltung geändert hat: Git hat nicht die riesigen, fundamentalen Lücken, die Quellcodeverwaltungssysteme vor Git hatten. Es ist also ziemlich schwer, „enorm besser“ zu sein.
Also, ja, ich gehe davon aus, dass Git auf absehbare Zeit vorne dabei bleibt und die Leute eher an Verbesserungen an Git arbeiten als an Ersatzlösungen.
Hinweis: Dieses Interview wurde aus Platzgründen und zur besseren Übersichtlichkeit bearbeitet.