30.13 Versionsmanagement 

Seit einigen Jahren werden sogenannte Versionsmanagement-Systeme in der Softwareentwicklung immer populärer. Da gibt es beispielsweise Visual SourceSafe von Microsoft oder CVS für Unix, Windows und Linux. Diese Systeme kümmern sich primär darum, dass mehrere Entwickler ohne weitere Probleme an einer Software – und damit auch an den gleichen Quelldateien – arbeiten können. Die Dateien werden dabei auf einem System abgelegt, auf das alle Zugriff haben. Ein Entwickler kann von solch einem System die aktuellen Quelldateien (und damit auch die Veränderungen, die von anderen an den Dateien vorgenommen wurden) auf seinen Rechner übertragen und ist gleichzeitig in der Lage, seine eigenen Änderungen an dieses System zu übermitteln.
Wir werden uns in diesem Buch auf die zwei populärsten Versionsmanagement-Systeme für Linux und Unix konzentrieren: CVS und Subversion. Der Vollständigkeit halber sei erwähnt, dass es für beide Systeme auch Skripte (CVS) bzw. Apache-Module (Subversion) für den Zugriff via Webbrowser gibt.
30.13.1 CVS 

CVS, das Concurrent Versions System, gibt es schon seit vielen Jahren. Es ist vielleicht noch immer das meistgenutzte Versionsmanagement-System. Viele große Projekte wie das OpenBSD-Projekt nutzen CVS. Wir selbst nutzen CVS ebenfalls seit einigen Jahren für die Arbeit an unseren Büchern und an einigen gemeinsamen Projekten.
Ein Projekt anlegen
Repository
Zunächst muss man ein Projektverzeichnis erschaffen, auf das alle Entwickler zugreifen können. Dazu genügt bereits ein SSH-Server. Auf diesem legt man unter dem gemeinsamen Benutzer, in diesem Fall »swendzel«, ein Verzeichnis für das jeweilige Projekt an. Es empfiehlt sich dabei, ein globales CVS-Verzeichnis (Repository) einzurichten, in das man alle Projekte einbauen kann. So erspart man sich später die Arbeit, die Umgebungsvariable CVSROOT für jedes Projekt zu ändern.
$ cd $ mkdir .cvs $ mkdir .cvs/CVSROOT $ mkdir .cvs/projekt
Listing 30.72 Das Projekt »projekt« anlegen
CVS-Projekte werden Module genannt. Module bezeichnen Verzeichnisse im CVS-Repository, in denen die Dateien eines Projekts enthalten sind. |
Entwicklungsbeginn
Auf den jeweiligen Entwickler-Workstations setzt man nun die Shellvariable CVSROOT auf den CVS-Benutzer des Projektsystems und das entsprechende Verzeichnis in der Form Benutzer@Host:/Verzeichnis. Zudem sollte man ssh verwenden, was durch CVS_RSH angegeben wird.
$ export CVSROOT='swendzel@192.168.0.2:/home/swendzel/.cvs' $ export CVS_RSH="ssh"
Listing 30.73 CVSROOT setzen
Bevor die Entwicklung beginnen kann, muss jeder Entwickler noch den aktuellen Auszug des jeweiligen Moduls aus dem CVS-Repository laden. An dieser Stelle kommt zum ersten Mal das Tool cvs zum Einsatz. Man verwendet dafür den Befehl checkout, der alle aktuellen Dateien überträgt und somit eine lokale Kopie des aktuellen Projektverzeichnisses anlegt.
$ ls $ cvs checkout projekt cvs checkout: Updating projekt $ ls projekt
Listing 30.74 checkout von »projekt«
Dateien und Veränderungen
add und commit
Als Nächstes fügt man eine Datei zum Projekt hinzu, beispielsweise eine .c-Datei. Diese legt man zunächst lokal an und überträgt sie dann mit dem Befehl add ins Repository-Modul. Anschließend nutzt man den Befehl commit, um die lokalen Änderungen auf das CVS-System zu übertragen. Den Befehl commit verwendet man auch, wenn man etwas an einer bereits bestehenden Datei verändert hat und diese Änderungen auf das CVS-System übertragen möchte. Hinter dem Parameter -m wird dabei die Veränderung eingetragen.
$ cd projekt $ cat << EOF >test.c > #include <stdio.h> > > int main(int argc, char *argv[]) { > printf("Hello!\n"); > return 0; > } > EOF $ cvs add test.c cvs add: scheduling file `test.c' for addition cvs add: use `cvs commit' to add this file permanently $ cvs commit -m 'Erste Version von test.c' cvs commit: Examining . RCS file: /home/swendzel/.cvs/projekt/test.c,v done Checking in test.c; /home/swendzel/.cvs/projekt/test.c,v <-- test.c initial revision: 1.1 done
Listing 30.75 Eine Quellcode-Datei erstellen und übertragen
delete
Soll hingegen eine Datei gelöscht werden, wird der Befehl delete verwendet. Damit keine unbeabsichtigten Löschvorgänge durchgeführt werden, erklärt sich CVS jedoch erst bereit, eine Datei zu löschen, wenn man diese auch lokal gelöscht hat. Auch hiernach müssen wieder mit commit die Änderungen an den CVS-Server geschickt werden.
$ cvs delete test.c cvs remove: file `test.c' still in working directory cvs remove: 1 file exists; remove it first $ rm test.c $ cvs delete test.c cvs remove: scheduling `test.c' for removal cvs remove: use `cvs commit' to remove this file permanently $ cvs commit -m '' cvs commit: Examining . Removing test.c; /home/swendzel/.cvs/projekt/test.c,v <-- test.c new revision: delete; previous revision: 1.1 done
Listing 30.76 delete
up
Nun arbeiten in der Regel mehrere Entwickler an einem Projekt. Damit diese Entwickler ebenfalls Änderungen an den Quellcodes durchführen und eventuell neue Dateien einbringen können, sollte man sich diese Änderungen und neuen Dateien in regelmäßigen Abständen herunterladen. Dies wird mit dem Befehl up (auch update) erledigt. Man sollte dabei den Parameter -d übergeben. Dieser legt, falls notwendig, neue Verzeichnisse an.
$ cvs up -d cvs update: Updating . P Makefile $
Listing 30.77 cvs up -d
log
Wichtig bei der Arbeit mit CVS ist auch, dass man sich über die Änderungen, die am Quellcode vorgenommen werden, auf dem Laufenden hält. Dafür nutzt man den Befehl log und übergibt ihm die Namen zu den Dateien, zu denen man die Änderungsinformationen wünscht. Dabei erscheinen übrigens die Strings, die Sie bei einem commit-Befehl hinter dem -m-Parameter übergeben.
$ cvs commit -m 'Suffixregel f. c.o.' cvs commit: Examining . Checking in Makefile; /home/swendzel/.cvs/projekt/Makefile,v <-- Makefile new revision: 1.3; previous revision: 1.2 done $ cvs log Makefile RCS file: /home/swendzel/.cvs/projekt/Makefile,v Working file: Makefile head: 1.3 branch: locks: strict access list: symbolic names: keyword substitution: kv total revisions: 3; selected revisions: 3 description: ---------------------------- revision 1.3 date: 2005/06/26 17:12:58; author: swendzel; state: Exp; lines: +2 –0 Suffixregel f. c.o. ---------------------------- revision 1.2 date: 2005/06/26 16:57:50; author: swendzel; state: Exp; lines: +1 –0 *** empty log message *** ---------------------------- revision 1.1 date: 2005/06/26 16:56:05; author: swendzel; state: Exp; *** empty log message *** =====================================================
Listing 30.78 cvs log-Makefile
Falls Sie weitere Informationen zu CVS suchen, empfehlen wir Ihnen [Bud05A].
30.13.2 Subversion 

Die Weiterentwicklung des Concurrent Versions System nennt sich Subversion. Sie bietet gegenüber CVS einige Vorteile und hat im Grunde nur einen einzigen Nachteil: Subversion benötigt mehr Speicherplatz. Dies liegt daran, dass Subversion von jeder veränderten Datei eine Kopie sichert. Zudem verfügt Subversion über ein anderes Versionsschema als CVS.
Die Vorteile bestehen nun darin, dass es zusätzliche Befehle gibt und dass Dateien und Verzeichnisse umbenannt werden können. Bei CVS musste man diese noch löschen und unter einem neuen Namen anlegen, um sie »umzubenennen«. Verbessert wurde auch die Handhabung von Binärdateien. Außerdem kann über ein Modul für den Apache Webserver 2.x auf das Repository zugegriffen werden. Für CVS gibt es allerdings CVSweb, das unter der BSD-Lizenz erhältlich ist und Ähnliches ermöglicht. [Falls Sie sich CVSweb einmal ansehen möchten, sollten Sie die Adresse www.openbsd.org/cgi-bin/cvsweb/ besuchen.] Die Befehle stimmen mit denen von CVS ungefähr überein; hier nur einige Beispiele:
- commit
Eigene Veränderungen können via svn commit auf den Server übertragen werden.
$ svn commit -m 'Buffer Overflow Fix in recv.c'
Listing 30.79 svn commit
- up
Um die aktuelle Version vom Repository auf den eigenen Rechner zu übertragen, wird – wie bei CVS – der Befehl up verwendet.
$ svn up Revision 755.
Listing 30.80 svn up
- log
Der Befehl log zeigt die letzten Commits des Repositories an. Im Folgenden sehen Sie einen Auszug der letzten Veränderungen im Subversion Repository der Hardened Linux Distribution.
$ svn log -------------------------------------------------------------------- r755 | cdpxe | 2007-04-11 23:57:39 +0200 (Mi, 11 Apr 2007) | 1 line remove unneded old config archives+sign files -------------------------------------------------------------------- r754 | cdpxe | 2007-04-11 23:44:08 +0200 (Mi, 11 Apr 2007) | 1 line aaa_hl pkg update for 1.6.6 -------------------------------------------------------------------- r753 | cdpxe | 2007-04-11 23:42:51 +0200 (Mi, 11 Apr 2007) | 1 line current internal dev version is 1.6.6 from now on *har har* -------------------------------------------------------------------- r752 | cdpxe | 2007-04-11 23:38:21 +0200 (Mi, 11 Apr 2007) | 1 line update for 1.6.5 (upload after the release, not now) -------------------------------------------------------------------- r751 | cdpxe | 2007-04-11 21:12:32 +0200 (Mi, 11 Apr 2007) | 1 line remove slackware/l/gd because we already have the package in universe/l/gd -------------------------------------------------------------------- ... ...
Listing 30.81 svn log
- rename
Das Umbenennen von Dateien und ganzen Verzeichnissen ist in Subversion auch kein Problem.
$ svn rename pakete packages
Listing 30.82 svn rename
- stat
Lokale Veränderungen lassen sich mit dem stat-Befehl anzeigen. Dieser Befehl ist äußerst sinnvoll, wenn man sehen möchte, was man alles modifiziert hat, und anschließend die Veränderungen in mehrere einzelne Commits aufteilen möchte.