Version Control System
Git und co.
English version (translated by Gemini 2.5 Pro)
Der Ursprung von Git
Das Linux-Kernel-Projekt, eines der größten Open-Source-Projekte der Welt, nutzte bis 2005 ein proprietäres, verteiltes Versionskontrollsystem (VCS) namens BitKeeper. Die Lizenz zur kostenlosen Nutzung wurde dem Kernel-Team jedoch entzogen. Dies schuf ein akutes Problem: Man benötigte ein neues VCS, das die extremen Anforderungen des Projekts erfüllen konnte:
- Verteilt (Distributed): Tausende Entwickler weltweit mussten effizient zusammenarbeiten können.
- Performant: Operationen wie Branching und Merging mussten extrem schnell sein.
- Sicher: Die Integrität des riesigen Code-Repositorys musste jederzeit gewährleistet sein.
Da keine existierende Lösung diese Kriterien erfüllte, nahm Linus Torvalds, der Initiator von Linux, die Sache selbst in die Hand.
Innerhalb weniger Wochen entwickelte Linus Torvalds den Kern von Git. Seine Ziele waren nicht, ein benutzerfreundliches System zu schaffen, sondern ein extrem schnelles und robustes Fundament. Die erste Version war minimalistisch und bestand aus einfachen Kommandozeilen-Tools, die aber bereits die Kernprinzipien von Git umsetzten.
Linus Torvalds' Hauptinteresse galt weiterhin dem Linux-Kernel. Nachdem er das Fundament von Git gelegt hatte, übergab er das Projekt im Juli 2005 an Junio C Hamano, einen der frühen und wichtigsten Beitragenden.
Unter Hamanos Leitung wurde Git zu dem, was wir heute kennen.
Der eigentliche Durchbruch von Git in der breiten Masse kam mit dem Aufstieg von Code-Hosting-Plattformen, auch "Forges" genannt.
Diese Plattformen erweitern die reine Versionskontrolle um entscheidende Kollaborations-Features:
- GitHub (2008): Machte Git durch eine grafische Oberfläche zugänglich und popularisierte den "Pull Request"-Workflow, der heute Standard für Open-Source-Kollaboration ist.
- GitLab (2011): Positionierte sich als "complete DevOps platform" und bietet neben Code-Hosting auch integrierte CI/CD-Pipelines, Issue-Tracking und mehr. GitLab ist sowohl als SaaS als auch als Self-Hosted-Lösung sehr populär.
- Gitea, Bitbucket etc.: Es gibt viele weitere Player. Gitea ist eine beliebte, leichtgewichtige Self-Hosted-Alternative zu GitHub.
Mehr als nur Git
Sowohl vor, als auch nach Git, gibt es viele weitere VCSs.
- Subversion (SVN, 2000): Zentralisiertes VCS von der Apache Software Foundation, das Verzeichnisse und Dateien versioniert und als Nachfolger von CVS entwickelt wurde. Wird kaum noch verwendet.
- Perforce Helix Core (1995): Kommerzielles, zentralisiertes VCS, das sich durch hohe Performance in großen Mono-Repositories und feingranulare Zugriffskontrolle auszeichnet. Wird viel für Videospiele verwendet.
- Mercurial (2005): Verteilt arbeitendes VCS in Python, legt Wert auf Einfachheit, Geschwindigkeit und Konsistenz der Kommandozeilenoberfläche. Wird außer bei Meta kaum noch verwendet.
- Fossil (2006): In C implementiertes, integriertes System von D. Richard Hipp (SQLite-Autor) mit eingebautem Bug-Tracker, Wiki und Web-Oberfläche in einem einzigen Programm. Das gesamte Repository ist in einer SQLite-Datenbank gespeichert. Wird außer für SQLite, kaum verwendet.
- Pijul (2014): Experimentelles, verteiltes VCS in Rust, basiert auf der Theorie der Patches und zielt auf einfachere Merges und bessere formale Korrektheit ab. Wird kaum verwendet.
- Jujutsu (2021):Verteiltes, Git-kompatibles VCS in Rust, initiiert von Martin von Zweigbergk (Google), mit Fokus auf intuitivere Historienbearbeitung und erweiterte Merge-Strategien. Wird aktiv in einigen Git Repositories verwendet. Genaue Nutzerzahlen lassen sich aber aufgrund der Git-Kompatibilität schwer bestimmen.
Änderungen
Viele glauben, dass Git nur die Änderungen von einem Commit zum nächsten speichert. Das macht fast kein VCS, weil es ineffizient ist.
Die meisten VCSs speichern Snapshots. Das ist eine Liste von allen Dateien, die in einem Commit enthalten sind. Eine Datei in Git hat einen Namen (Pfad), eine executable Flag und einen Inhalt. Es werden also in jedem Commit alle Dateien gespeichert, nicht nur die, die sich verändert haben. Zudem ist es egal wie viel sich an einer Datei geändert hat, sie wird vollständig, neu gespeichert.
Dabei gibt es aber eine wichtige Optimierung: Es kommt ständig vor, dass ein Dateiinhalt mehrmals auftritt. Wenn sich eine Datei durch einen Commit nicht ändert, muss auch nicht der komplette Inhalt ein zweites mal gespeichert werden. Genauso, wenn zwei Dateien denselben Inhalt haben, muss dieser nur einmal gespeichert werden.
Das lässt sich mit PNPM vergleichen, dass NPM-Pakete zetral ablegt und
per Symlink im node_modules
-Verzeichnis referenziert,
anstatt sie dorthin zu kopieren, (unter anderem) um Speicherplatz zu
sparen.
Merge
Wenn zwei Commits zusammengeführt werden, muss das VCS einen Three-Way-Merge durchführen. Dabei wird die Commit-Historie als DAC (Directed Acyclic Graph) betrachtet. In einem DAC ist es einfach, den LCA (Lowest Common Ancestor) zu finden. Das ist der Commit, der ein Parent der beiden zusammenzuführenden Commits ist, der am tiefsten im DAC liegt, also am weitesten vom initial-Commit entfernt ist.
Das klingt kompliziert. Grafisch dargestellt sieht es aber ganz einfach aus:
Wenn die Commits B und C zusammengeführt werden sollen, benötigt es eine gemeinsame Basis, mit der die Änderungen der beiden Commits miteinander verglichen werden können. Diese gemeinsame Basis ist der neueste Commit, der ein Parent von B und C ist (der LCA).