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. Mitclone
lässt sich ein bestehendes Repository kopieren. - Dateien, die verwaltet werden sollen, werden mit
add
zum Repository hinzugefügt. Mitrm
oderforget
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 wiev1.0
oderfinal
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 mitpull
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
odermain
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, einen Vertreter der verteilten Versionsverwaltungssysteme, der durch eine Reihe weiterer Features aus der Menge der VCS heraussticht.