Subversion

Aus THM-Wiki
(Weitergeleitet von Concurrent Versions System)
Wechseln zu: Navigation, Suche

Subversion (SVN) ist ein System zur Versionsverwaltung von Dateien, das u.a. bei der OpenSource-Entwicklung häufig eingesetzt wird (1).

Motivation

Bei Softwareentwicklung im Team stellen sich grundsätzlich die Fragen wo und wie die aktuellen Quellcodes bereitgestellt werden, wie Änderungen oder Erweiterungen unterschiedlicher Entwickler in die Hauptversion aufgenommen werden, und wie andere Entwickler über diese Änderungen zu informieren sind. In Abbildung 1 ist die Organisation ohne automatisierte Verwaltungsinstanz dargestellt, mit der viele Projekte anfangen. Ein Entwickler wird als Maintainer ausgewählt, der über die Hauptversion wacht und sie an andere Entwickler verteilt sowie deren Korrekturen und Erweiterungen entgegen nimmt und in die Hauptversion einpflegt.

Selbst bei kleinen, gut organisierten Projekten werden diese Aufgaben schnell zur aufwändigen Administrativa. Vor allem die schnell auseinanderlaufenden Versionen, an denen die Entwickler arbeiten, sowie die Behandlung von Konflikten in den Änderungen erfordern viel Kommunikation und viel Zeit des Maintainers. Je größer und verteilter ein Projekt wird, desto schwieriger und aufwändiger wird auch der Koordinationsaufwand.

Aus dieser Problematik entstand die Idee einer zentralen, automatisierten Verwaltungsinstanz, die eben genau diese Aufgaben übernimmt. Jeder Entwickler soll Zugriff erhalten und eigenverantworlich Änderungen vornehmen, die er dann an die Instanz übermitteln kann. Änderungen sollen an alle Entwickler mitgeteilt werden. Eine Darstellung dieses Ansatzes ist in Abbildung 2 gezeigt.

Abbildung 1: Ein Maintainer wacht über den Code und seine Änderungen
Abbildung 2: Eine Verwaltungsinstanz übernimmt die Verwaltung des Codes

Zwei Modelle für die Verwaltungsinstanz

Ein zentrales Repository kann grundsätzlich auf folgende zwei verschiedene Arten arbeiten:

  • Lock-Modify-Unlock
  • Copy-Modify-Merge

Das Lock-Modify-Unlock Modell beschreibt, dass ein Entwickler ein Objekt exklusiv für sich sperrt und somit sicher stellt, dass er der alleinige Bearbeiter ist (Lock). Sind die Änderungen abgeschlossen (Modify), kann das Objekt wieder entsperrt und somit für andere freigegeben werden (Unlock).

So sinnvoll dieser Ansatz erscheint hat er doch den Nachteil, dass an einem Objekt zu jeder Zeit nur ein Entwickler Änderungen vornehmen kann. Auch wird es nicht lange dauern bis Entwickler vergessen ihre Objekte wieder zu entsperren und den Entwicklungsprozess damit unnötig aufhalten.

Bei dem Copy-Modify-Merge Modell wird der Quelltext von einem zentralen Repository kopiert und dann lokal geändert (Copy, Modify). Sind die Änderungen abgeschlossen, können sie in das Repository übertragen werden. Hierbei wird ein Vergleich der lokalen Version mit der Version auf dem Repository durchgeführt, da in der Zwischenzeit andere Entwickler möglicherweise Änderungen vorgenommen und übertragen haben (Merge). Im einfachsten Fall sind die Änderungen an anderer Stelle und behindern eine automatische Übertragung nicht. Sind die Änderungen jedoch an der gleichen Stelle in Code, tritt ein Konflikt auf, der von dem Entwickler manuell zu lösen ist.

In jedem Fall ermöglicht dieser Ansatz einen schnelleren und flexibleren Entwicklungsprozess als mit dem Lock-Modify-Unlock Ansatz.

Subversion Basics

Subversion bietet ein Repository erlaubt mehreren Entwicklern zur gleichen Zeit an den gleichen Dateien zu arbeiten. Um die Arbeiten beim Merge abzugleichen kann das GNU Tool diff genutzt werden, das es ermöglicht die Unterschiede von zwei Dateien bzw. zwei Versionen der gleichen Datei zu identifizieren. Das Repository speichert weiterhin jede Version jeder Datei. Um den Speicherplatz effizient zu nutzen, werden Änderungen von einer Version zur nächsten als diff gepeichert. Durch das GNU Tool patch können dann aus einer Datei und den diffs die entsprechend anderen Versionen rekonstruiert werden.

Die lokale Kopie des Subversion Repository wird in der Regel als Working Copy oder auch Arbeitskopie bezeichnet und dient als Grundlage für alle Änderungen. Abbildung 3 zeigt eine typische Session mit zwei Benutzern, anhand derer wir uns jetzt die Kommandos näher anschauen werden. Unter CVS Beispielsession ist diese Session noch weiter beschrieben.

Abbildung 3: Beispiel Session mit zwei Benutzern


Grundlegende Befehle

In den folgenden Beispielen wird der Benutzer emheo auf das estudy Subversion-Repository zugreifen und dort vor allem mit dem Branch u-portale arbeiten. In der Regel wird man mit Subversion auf dem Hauptentwicklungszweig (dem sog. Trunk) arbeiten und daher einen etwas anderen Pfad benutzen.

Für alle Befehle gilt, dass sie entweder wie angegeben ohne weitere Parameter aufgerufen (und dann alle Dateien durcharbeiten) oder auf bestimmte Dateien beschränkt werden können.

Hier wird der Trunk aus dem Repository gelesen.

$ svn checkout --username emheo https://svn.mni.fh-giessen.de/trunk

Checkout: Eine Arbeitskopie erstellen

Das Checkout ist der erste Schritt, wenn man an einem existierenden Projekt arbeiten möchte. Es kopiert im Grunde alle Dateien vom Subversion-Repository auf den lokalen Rechner. Die dort entstandenen Dateien und Verzeichnisse werden um ein Verzeichnis ".svn" ergänzt, dass lokale Kopien der Dateien beinhaltet. Die ausgecheckte Version nennt man Working Copy oder auch Arbeitkopie.

Um also den Branch u-portale auszuchecken und eine erste Working Copy zu erhalten machen wir folgendes:

$ svn checkout -r u-portale eStudy 

eStudy ist das Modul, mit -r u-portale geben wir den Branch an, den wir auschecken wollen.

Eine Änderung machen

Die Datein der Arbeitskopie können wie gewohnt lokal bearbeitet werden. So z.B. über

$ vi eStudy/eStudy/style/BIMfort/_about.txt

Anschließend muss die Änderung über Update mit dem Repository verglichen werden und über Commit ins Repository gemergt.

Update: Die Arbeitskopie abgleichen

Update vergleicht die Arbeitskopie mit dem Repository und kopiert geänderte bzw. neue Dateien und Ordner vom Server in die Arbeitskopie. Ist eine Datei lokal geändert worden und somit nicht mit der Vorversion im Repository identisch wird das Update versuchen die Änderungen in die Arbeitskopie zu mergen. Sind Änderungen jedoch an der gleichen Stelle aufgetreten tritt ein Konflik auf, den der Benutzer zu lösen hat.

$ svn -q update
M eStudy/eStudy/style/BIMfort/_about.txt

Der Parameter -q führt dazu, dass statt aller Dateien nur die von einer Änderung betroffenen ausgegeben werden. In der Ergebnisliste deutet das vorangestellte M an, dass Änderungen im Vergleich zum Repository vorliegen. Ein A bezeichnet neue Dateien, C einen Konflikt.

In regelmäßigen Abständen sollte ein Update auch mit der Option -d aufgerufen werden. Diese Option führt dazu, dass neue Ordner im Repository in die Arbeitskopie kopiert werden. Ohne diese Option werden nur existierende Ordner und deren Dateien abgeglichen.

$ svn -q update -d

Diff: Unterschiede zwischen Versionen zeigen

Ohne Parameter vergleicht cvs diff die Arbeitskopie gegen das Repository

$ svn diff

Jedoch kann man hier auch mit der -r Option explizit angeben welche Revision gegen welche verglichen werden soll.

$ svn diff -r 12 HalloWelt.java
$ svn diff -r 12 -r 15 HalloWelt.java

Commit: Änderungen zum Repository senden

Commit sendet Änderungen zum Server. Über -m wird ein Kommentar mitgegeben, der im Repository gespeichert wird. Diese Möglichkeit sollte immer genutzt werden um den anderen Entwicklern Änderungen anzuzeigen und zu erläutern.

$ svn commit -m "Rechtschreibung korrigiert :-)"

Log: Die Historie untersuchen

Einen Überblick über alle Revisionen in dem Subversion-Repository kann man sich mit Log verschaffen. Hier sieht man auch die Kommentare, die bei jedem Commit mitgegeben wurden.

$ svn log user
------------------------------------------------------------------------
r154 | commana | 2008-04-03 14:46:57 +0200 (Do, 03 Apr 2008) | 1 line

Fixes aus eCom Branch
------------------------------------------------------------------------
r38 | f0lk | 2008-03-16 19:42:54 +0100 (So, 16 Mär 2008) | 1 line

initial commit
------------------------------------------------------------------------

Weiterführende Befehle

Import: Ein neues Projekt starten

Einen Import stößt man an, wenn man ein neues Subversion Projekt starten möchte. Da das für uns nicht weiter relevant ist, hier nur die allgemeine Syntax:

svn import ...

Gültige Optionen:
  -q [--quiet]             : So wenig wie möglich ausgeben
  -N [--non-recursive]     : Nicht rekursiv hinabsteigen
  --auto-props             : automatische Eigenschaften einschalten
  --no-auto-props          : automatische Eigenschaften ausschalten
  -m [--message] par       : Verwende PAR als Logmeldung
  -F [--file] par          : Lies Logmeldung aus Datei PAR
  --force-log              : Gültigkeit der Quelle für die Logmeldung erzwingen
  --editor-cmd par         : Verwende PAR als externen Editor
  --encoding par           : Behandle Wert, als sei er in der Zeichenkodierung PAR
  --no-ignore              : Globale »ignore«- und »svn:ignore«-Einstellungen nicht beachten
  --username par           : Benutzername PAR angeben
  --password par           : Passwort PAR angeben
  --no-auth-cache          : Anmeldeinformationen nicht zwischenspeichern
  --non-interactive        : Keine interaktiven Rückfragen ausgeben
  --config-dir par         : Benutzerkonfigurationsdateien aus dem Verzeichnis PAR lesen

Add: Neue Dateien und Verzeichnisse anlegen

Die Subversion-Option add ermöglicht es, Dateien oder Ordner zu dem Repository hinzuzufügen. Bei Dateien wird hier die Hinzufügung nur vorgemerkt und erst bei dem folgenden commit tatsächlich ausgeführt. Ordner hingegen werden direkt hinzugefügt! Wichtig ist in beiden Fällen, dass die Dateien bzw. Ordner schon in der Working Copy existieren.

$ mkdir ordner
$ touch datei1 ordner/datei2
$ svn add datei1 ordner ordern/datei2
$ svn commit -m "Gelöscht, war nur zum Test" datei1 ordner/datei2

Remove: Dateien und Ordner entfernen

Analog zum Anlegen können Dateien gelöscht werden. Bevor der entsprechende Subversion-Befehl aufgerufen wird, muss die Datei lokal bereits gelöscht sein. Anschließend wird die Löschung durch ein Commit auf dem Server durchgeführt.

$ rm datei1
$ svn remove datei1
$ svn commit -m "Gelöscht weil überflüssig" datei1

Doch keine Sorge, die alten Versionen der Datei ist auch weiterhin in dem Subversion-Repository enthalten. Schließlich haben wir ein Versionierungssystem eingesetzt :)

Das Löschen von Verzeichnissen ist ungleich aufwändiger. Erst müssen alle Dateien in dem Verzeichnis lokal und im Repository gelöscht werden. Anschließend sind die Änderungen per Commit in das Repository zu übernehmen. Ein folgendes Update mit der -P Option löscht leere Verzeichnisse im Repository und der Working Copy.

$ cd ordner
$ rm datei2
$ svn remove datei2
$ svn commit
$ cd ..
$ svn update -P

Nicht nur Dateien, sondern auch Ordner werden mit einer Revision Version versehen. Sie können also wieder hergestellt werden.

Dateien und Ordner umbenennen

Die Umbenennung von Dateien und / oder Ordnern ist identisch zu dem UNIX-Ansatz per mv (move). Die Dateien werden also gelöscht und neu angelegt. Entsprechend sind die SVN-Befehle aus den Abschnitten #Add: Neue Dateien und Verzeichnisse anlegen und #Remove: Dateien und Ordner entfernen anzuwenden.

Eine weitere Möglichkeit ist die direkte Umbenennung mit dem Befehl:

svn mv ...

QUELLE und ZIEL können beide Arbeitskopien (AK) oder URLs sein:
    AK  -> AK:   Verschieben und zum Hinzufügen (mit Historie) einplanen
    URL -> URL:  Vollständig serverseitiges Verschieben.

Gültige Optionen:
  -r [--revision] par      : PAR (manche Befehle akzeptieren auch einen Wertebereich PAR1:PAR2)
                             Ein Revisionsparameter kann sein:
                                NUMMER       Revisionsnummer
                                »{«DATUM»}«  Revision zum Startdatum
                                »HEAD«       Neueste Revision im Projektarchiv
                                »BASE«       Basisrevision der Arbeitskopie
                                »COMMITTED«  Letzte übertragene Revision zu oder vor BASE
                                »PREV«       Letzte Revision vor COMMITTED
  -q [--quiet]             : So wenig wie möglich ausgeben
  --force                  : Durchführung des Befehls erzwingen
  -m [--message] par       : Verwende PAR als Logmeldung
  -F [--file] par          : Lies Logmeldung aus Datei PAR
  --force-log              : Gültigkeit der Quelle für die Logmeldung erzwingen
  --editor-cmd par         : Verwende PAR als externen Editor
  --encoding par           : Behandle Wert, als sei er in der Zeichenkodierung PAR
  --username par           : Benutzername PAR angeben
  --password par           : Passwort PAR angeben
  --no-auth-cache          : Anmeldeinformationen nicht zwischenspeichern
  --non-interactive        : Keine interaktiven Rückfragen ausgeben
  --config-dir par         : Benutzerkonfigurationsdateien aus dem Verzeichnis PAR lesen

Branches

Branches, also Zweige, erlauben es in Subversion mehrere Versionen des Codes weiterzuentwickeln. Zum Beispiel wird häufig nach einem Release im Hauptzweig (Trunk) weiterwentwickelt für die nächste Version, während ein Branch basierend auf dem Releasecode aufgemacht wird um dort Fehler zu korrigieren. Später können Branches auch wieder in den Trunk gemergt werden (und sollten das auch, damit die Fehlerkorrekturen auch dem nächsten Release zugute kommen).

Das Konzept ist identisch zu dem Setzen von Tags, weitere Informationen können in dem unter Literatur empfohlenen Buch gefunden werden.

In eStudy werden die Branches zur Abkapselung der Kurse verwendet. Wird ein neuer Branch angelegt, ist dies nichts anderes als eine Kopie.

Eine vereinfachte Darstellung ist in Abbildung 4 zu finden:

Abbildung 4: Ein Branch ist entstanden


Tools

In Eclipse finden sich die kennengelernten Befehle alle wieder,wenn ein entsprechendes Plugin (bevorzugt Subversive) installiert ist. So z.B. in der CVS Perspektive der Checkout, in der Java oder PHP Perspektive unter Team der Update, Commit, und ähnliche (siehe Abbildung 5 und 6)

Abbildung 5: CVS Checkout in Eclipse
Abbildung 6: CVS Update, Commit in Eclipse

Weitere Tools zur Arbeit mit CVS sind z.B.

Ausblick

Zunehmend wird ein jüngeres Versionierungssystem mit Namen Subversion anstelle von CVS eingesetzt. Die Befehle sind größtenteils identisch, doch haben die Subversion Entwickler aus den Problemen in CVS gelernt. Diese wichtigsten sind:

  • CVS kann nur Dateien, nicht Verzeichnisse verwalten. Verzeichnisse sind nur über einen Kunstgriff in das CVS aufgenommen, werden dort jedoch nicht versioniert. Somit können Dateien un Verzeichnisse auch nicht einfach umbenannt oder verschoben werden.
  • CVS besitzt im Gegensatz zu Subversion kein Transaktionskonzept. So kann es sein, dass man 10 Dateien aus einem Projekt zum Server commited hat und bei der 11ten ein Fehler auftritt. Statt alle Änderungen zurückzurollen entsteht so ein inkonsitenter Zustand.

Weiterhin unschön ist die Arbeit mit Binärdateien, da auch Subversion sich nicht auf die Änderungen der Dateien beschränkt und bei einer Änderung den kompletten Dateiinhalt überträgt.

Fußnoten

  • CVS wird zumeist in OpenSource Projekten eingesetzt, jedoch sind die Probleme keinesfalls auf die OpenSource Entwicklung beschränkt. Vielmehr fallen die Probleme durch die Verteilung der Entwickler über den Globus und die Freiwilligkeit eines jeden einzelnen besonders ins Gewicht. Schließlich möchte man sich auf die Entwicklung und nicht die Koordination konzentrieren

Literatur


Links

--Oehme-SO 21:56, 16. Mär. 2007 (CET)