Schnipsel aus dem Zettelkasten


Versionsverwaltung

Sinnvoll nicht nur für Quellcode

Inhalt

Was ist das Problem?

  • Die Entwicklung von Software, aber auch von Texten, geschieht selten linear, ohne Umwege, in einem Rutsch.
  • Es gibt immer Zwischenstände, Arbeitseinheiten, die abgehakt werden.
  • Nicht selten kommt es allerdings vor, dass eine anfangs einleuchtende Idee sich als letztendlich doch nicht sinnvoll herausstellt. Änderungen, die durch das Verfolgen dieser Idee vorgenommen wurden, müssen dann zurückgerollt werden.
  • Größere Projekte entstehen als Gruppenarbeit, wobei alle Beteiligten bestimmte Aufgaben (Software-Module, Textkapitel) übernehmen.
  • Die Beteiligten müssen dazu Dateien und Verzeichnisse teilen. Daraus ergibt sich aber die Notwendigkeit, dass die Arbeiten daran koordiniert werden, um zu verhindern, dass Änderungen gegenseitig überschrieben werden.

Lösungsvorschläge

  • Um Zwischenstände festzuhalten, kann das Haupt-Verzeichnis des Projekts bei Bedarf kopiert und der Name der Kopie mit einem Datum, einer Versionsnummer oder einer anderen hilfreichen Bezeichnung ergänzt werden. Problematisch ist hierbei allerdings der Platzverbrauch, da immer der komplette Datenbestand kopiert wird, auch wenn sich nur wenige Dateien geändert haben. Bei den mittlerweile verfügbaren Speichervolumina könnte das jedoch vernachlässigt werden.
  • Um Dateien in einer Gruppe zu teilen, ist der einfachste Weg, sie in einem für alle zugreifbaren Verzeichnis vorzuhalten, bspw. einem Netzlaufwerk.
  • Die Koordination der Änderungen kann auf organisatorischer Ebene erfolgen (niemand ändert Dateien, die anderen zugeordnet sind). Das ist aber nur für überschaubare Projekte ein gangbarer Weg, selten für Software-Projekte.
  • Sinnvoller ist eine Unterstützung auf technischer Ebene. Beispielsweise könnten die verwendeten Betriebssysteme verhindern, dass eine Datei gleichzeitig von mehreren Personen geöffnet und bearbeitet werden kann.
  • Alternativ könnten die Systeme das mehrfache Öffnen und auch Schreiben erlauben. Dann muss nur dafür gesorgt werden, dass alle Änderungen an derselben Datei passend dort ankommen und sich nicht gegenseitig überschreiben.

Entwicklung freier Werkzeuge für die Versionsverwaltung

  • Die ersten Systeme zur Verwaltung von Dateiversionen werden auf Wikipedia IBM zugeordnet; das erste Source Code Control System (SCCS) datiert auf 1972.
  • RCS folgte danach, wobei beide Werkzeuge auf Einzelsysteme beschränkt waren. Erst mit CVS, einem Frontend zu RCS, stand ein als Client-Server-Architektur aufgebautes System zur Verfügung, das die Zusammenarbeit größerer Gruppen ermöglichte.
  • Subversion beerbte CVS und erfreut sich auch heute noch großer Beliebtheit als Vertreter zentralisierter Versionsverwaltungen.
  • Dezentrale Systeme lösen das strikte Client-Server-Modell auf, bei dem eine zentrale Einheit, der Server, die Dateien verwaltet. Sie arbeiten nach einem Peer-to-Peer-Ansatz, bei dem alle Beteiligten sämtliche Versionen auf ihren Rechnern vorhalten und Änderungen untereinander tauschen.
  • Das bekannteste dezentrale Versionsverwaltungssystem ist derzeit Git, das zunächst für die Verwaltung des Linux-Kernels gedacht war. Weiterhin gibt es Mercurial und Fossil, ältere Systeme sind GNU Arch (abgelöst durch Bazaar), Monotone und Darcs.
  • Pijul ist einer der neuesten Vertreter, der einige der Probleme von Git lösen möchte.

Begriffe und Arbeitsweise

  • Versionsverwaltungssysteme verwenden ein sogenanntes „Repository“, in dem die Dateien und ihre Änderungen gespeichert werden. Die Befehle ähneln sich weitgehend, einige Werkzeuge beherrschen zusätzliche Fähigkeiten wie Staging.
  • Ein neues Repository kann mit init oder einem ähnlichen Befehl erzeugt werden. Mit clone lässt sich ein bestehendes Repository kopieren.
  • Dateien, die verwaltet werden sollen, werden mit add zum Repository hinzugefügt. Mit rm oder forget können Dateien auch aus der weiteren Verwaltung herausgenommen werden.
  • Ist eine Arbeitsphase oder ein Kapitel beendet, führt ein commit zu einem neuen Zwischenstand des Projekts, einer neuen Version. Die meisten Werkzeuge inkrementieren einen Zähler oder nutzen einen Hashwert, um diese zu identifizieren. Zusätzlich lassen sich mit Tags eingängigere Bezeichner wie v1.0 oder final setzen.
gitGraph commit id:"initial commit" commit commit id:"added section" commit commit id:"finished article draft" commit commit tag:"final release"
  • Dezentrale Systeme wie Mercurial oder Git können Änderungen an entfernte Repositorien mittels push senden bzw. dortige mit pull in das lokale Repository einfügen. Auf diese Weise lassen sich alle oder auch nur bestimmte Änderungen verteilen.
  • Kommt es zu konkurrierenden Änderungen an derselben Datei, entsteht ein Konflikt. Viele Änderungen können automatisch durch einen merge zusammengeführt werden, andernfalls müssen sich die Beteiligten darauf verständigen, welche Änderung wie einzufügen ist.
gitGraph commit id:"initial commit" commit commit id:"added section" commit branch conflict checkout conflict commit commit checkout main merge conflict commit id:"merged" commit id:"finished article draft"
  • Paralleles Arbeiten ist gerade bei größeren Projekten die Regel. Es gibt verschiedene Strategien, wie sich die verschiedenen Entwicklungszweige, die Forks oder Branches, organisieren lassen. Der Hauptzweig, oftmals trunk, master oder main genannt, kann beispielsweise als konsolidierende Version des Projekt fungieren, die sämtliche neuen Features, die in eigenen Zweigen parallel entwickelt werden, aufnimmt.
gitGraph commit commit branch feature-1 checkout feature-1 commit checkout main merge feature-1 commit id:"merged feature-1" branch feature-2 checkout feature-2 commit commit checkout main merge feature-2 commit id:"merged feature-2" tag:"final"
  • Die Entwicklung der Zweige kann in getrennten Repositorien stattfinden. Abgeschlossene Arbeiten lassen sich über Pull- oder Push-Aktionen verteilen und in den Hauptzweig mischen.
  • Vom Hauptzweig können Release-Zweige abgespalten werden, die anschließend für eine gewisse Zeit gepflegt und damit weitere Commits erhalten. Je nach Strategie können sich komplizierte Verläufe bilden; nachfolgend ein Beispiel aus der mermaid-js-Dokumentation:
gitGraph commit branch hotfix checkout hotfix commit branch develop checkout develop commit id:"ash" branch featureB checkout featureB commit type:HIGHLIGHT checkout main checkout hotfix commit type:NORMAL checkout develop commit type:REVERSE checkout featureB commit checkout main merge hotfix checkout featureB commit checkout develop branch featureA commit checkout develop merge hotfix checkout featureA commit checkout featureB commit checkout develop merge featureA branch release checkout release commit checkout main commit checkout release merge main checkout develop merge release

Verwendung abseits von Quellcode

  • Systeme zur Versionierung sind auch attraktiv für andere Arten von Dateien: Dokumente in Klartext-Formaten (Markdown, restructuredText, LaTeX etc.) Konfigurationsdateien (sog. dot-Dateien), Webseiten, buchstäblich alles, was als „Text“ gespeichert wird
  • Auch Binärdateien werden von vielen Systeme verarbeiten, obwohl sich viele damit schwer tun. Durch die fehlende Diff-Möglichkeit können bei Änderungen immer nur die kompletten Dateien gespeichert werden, was zu einem hohen Speicherbedarf führt.
  • Die Verwaltung des eigenen HOME-Verzeichnisses über mehrere Computer hinweg, die sog. dot-Dateien, liegt durch die einfache Übertragung der Repositorien auf andere Rechner ebenfalls nahe. Aber Vorsicht: Einige dieser Dateien enthalten sensible Informationen wie Passwörter, die auf keinen Fall in öffentliche Repositorien gehören (ebenso Schlüssel in ). Derartige Fälle gehen leider immer wieder durch die Fachpresse.
  • Quasi als Beifang kommt die Funktion eines Backups: Einzelne Versionen als Backup-Stände, räumliche Trennung durch entfernte Repositorien. Neben den anderen Vorteilen ist das IMHO eine wichtigsten Eigenschaften dezentraler Versionsverwaltungssysteme.

Fazit

  • Geeignet nicht nur für kleine, persönliche Projekte wie Dokumente oder Quellcode, auch für Konfigurationsdateien bieten Versionsverwaltungssysteme eine einfache Möglichkeit, Dateien und Verzeichnisse über Versionsstände hinweg als Einzelperson oder im Team zu verwalten.
  • Dezentrale Systeme machen die verschiedenen Versionsstände auf allen beteiligten Rechner verfügbar und erlauben so eine flexible Arbeitsweise auch ohne permanenten Netzzugang. Verzweigungen erlauben eine an Projektphasen angelegte Organisation der Dateien
  • Die Verteilung auf mehrere Rechner bieten zudem eine Form eines dezentralen Backups, dass sich bei Netzzugang und einem „Pull“ quasi automatisch synchronisiert.

In einem weiteren Schnipsel geht es um Fossil, einem Vertreter der verteilten Versionsverwaltungssysteme, der durch eine Reihe weiterer Features aus der Menge heraussticht.