CVS, "Concurrent Versioning System", ist ein System zur Verwaltung von Quelltexten in unterschiedlichen Versionen. CVS hat nix mit RCS oder SCCS zu tun. Wer RCS oder SCCS schon kennt, vergißt das am besten wieder, dann wird das Lernen einfacher. --- Einmalige Handgriffe für CVS Benutzer --- 1. User werden Um das CVS Archiv benutzen zu können, muß man sich einmal von dem CVS-Admin als User eintragen lassen. Man bekommt dann ein Paßwort zugeteilt. 2. Software haben Auf dem Entwicklungsrechner muß ein CVS-Paket installiert sein. Für Suse Linux 6.2 oder 6.3 Linux muß das Paket cvs aus der Serie d1 installiert sein. Hausregel: CVS-Version muß 1.10.6 oder besser sein, ältere Versionen sind nicht zu verwenden. 3. Software konfigurieren Default-Optionen einstellen $ cat > $HOME/.cvsrc cvs -q -z9 update -dAP diff -u status -v ^D 4. Einloggen Bei einem CVS-Archiv muß man sich einmal anmelden. Das CVS verifiziert das Paßwort und hinterlegt es verschlüsselt in $HOME/.cvspass. Anmelden geht so: $ cvs -d :pserver:@boss:/repository login Password: Dabei ist das CVS-Paßwort zu verwenden, nicht das Unix-Paßwort. Kommt eine Fehlermeldung, kann man bei dem CVS-Admin aufschlagen und sich ausweinen. Hier werden Sie geholfen. 5. Modul auschecken Zweckmäßigerweise legt man sich in seinem Home ein Verzeichnis Source an. Dort wechselt man rein und checkt sich genau einmal das Modul aus, an dem man arbeiten möchte. Zum Beispiel zum arbeiten am Modul testmodul: $ mkdir $HOME/Source $ cd $HOME/Source $ cvs -d :pserver:@boss:/repository checkout testmodul Man bekommt jetzt eine ganze Reihe von U (Update) Meldungen und erhält ein frisches Verzeichnis testmodul. Da kann man rein wechseln und lustig ändern. --- Ende Einmalige Handgriffe für CVS Benutzer --- --- Ständige Handgriffe für CVS-Benutzer --- Funktionsweise Anders als RCS oder SCCS arbeitet CVS nicht mit einzelnen Dateien, sondern mit ganzen Verzeichnissen. Alle Befehle beziehen sich per Default immer auf den gesamten Verzeichnisbaum, meist das aktuelle Verzeichnis. Es ist also sehr wichtig, in welchem Verzeichnis man sich gerade befindet. Am günstigsten ist es, in die Wurzel des Moduls zu wechseln. Arbeitet man also am Modul testmodul, das man nach $HOME/Source/testmodul ausgecheckt hat, dann sollte man für alle cvs-Kommandos in dieses Verzeichnis wechseln. Anders als SCCS und RCS arbeitet CVS nicht mit Locks. Alle Benutzer können gleichzeitig und unabhängig an ihrer Kopie des Moduls arbeiten. CVS vergleicht die lokale Kopie des Moduls (den Workspace) mit der zentralen Kopie des Moduls (dem Repository). Wenn der Workspace gegenüber dem Repository veraltet ist, dann muß man den Workspace updaten, bevor man seine eigenen Änderungen in das Repository zurück überweisen kann. Beim Update wird ein Patch generiert, der die Unterschiede zwischen der Version des Source, die man ausgecheckt hat und der aktuellen Version des Source enthält. Dieser Patch wird dann auf den Workspace angewendet. Wenn sich die eigenen Änderungen und die Änderungen im Repository nicht überschneiden, hat man danach eine Version im Workspace, die auf dem Stand des Repository ist UND die die lokalen Änderungen enthält. Wenn es zu Überschneidungen kommt, hat man einen Conflict und muß den erst auflösen, bevor man weitermachen kann. 1. Workspace aktuell halten $ cvs -z9 update -dAP oder, falls das o.a. .cvsrc verwendet wird, einfach nur $ cvs update Ich verwende /home/kk/Source/update: #! /bin/sh -- USER=`whoami` MAILTO="$USER@netuse.de" PATH="/opt/bin:/usr/bin:/bin:/usr/ccs/bin:/usr/sbin:/bin:/usr/openwin/bin:/home/$USER/bin:." export PATH cd /home/$USER/Source for i in * do if [ -d $i ] && [ -d $i/CVS ] then cd $i echo "Updating $i..." cvs -z9 update -dAP cd .. fi done 2>&1 | mailx -s "`date +%d-%b-%Y` update" $MAILTO einmal am Tag: kk@boss ~/Source $ crontab -l 01 08 * * * /home/kk/Source/update 2. Änderungen ins Repository comitten $ cvs commit Wichtig: Sinnvolle Doku schreiben Speichern Auf das Lock warten (kann bis zu einer Minute dauern) 3. Änderungen zwischen Workspace und Repository ansehen $ cvs diff -u oder, wenn man das o.a. .cvsrc verwendet, einfach nur $ cvs diff Beachte: "-u" ist eine GNU diff Option für "unified diff" und wird von Solaris diff nicht verstanden. Entweder installiert man GNU diffutils (empfohlen) man ändert in .cvsrc die diff-Option auf "-c" ab. 4. Dateien zufügen und löschen Datei zufügen: kk@boss ~/Source/testmodul $ cat beispiel.c /* $Id: handgriffe.txt,v 1.1 2000/01/07 17:12:47 kk Exp $ */ /* $Log: handgriffe.txt,v $ /* Revision 1.1 2000/01/07 17:12:47 kk /* Handgriffe zugefuegt. /* */ #include int main(void) { printf("Hello, World!\n"); return 0; } kk@boss ~/Source/testmodul $ cvs add beispiel.c cvs server: use 'cvs commit' to add this file permanently Mit dem nächsten "cvs commit" geht die Datei ins Archiv. Datei löschen: a. Erst die Datei löschen b. Dann "cvs remove Dateiname". Mit dem nächsten "cvs commit" geht die Datei ins Archiv. 5. Verzeichnisse hinzufügen $ cvs add verzeichnisname Wichtig: Ein CVS erlaubt es, in der Versionshistorie rückwärts zu gehen. Daher kann man einmal eingecheckte Verzeichnisse nie wieder löschen, nur leer machen. Überlegt Euch also, was Ihr tut. Im Notfall übt mit dem testmodul, bevor Ihr das eigentliche Produktions-Repository versaut. Wichtig: In ganz großen Notfällen kann der CVS-Admin Hand auflegen. Bitte nicht selbst an den Dateien in /repository rumspielen! --- Ende der ständigen Handgriffe --- --- Handgriffe zum Auflösen von Konflikten --- Zu einem Konflikt kommt es, wenn unvereinbare Änderungen an einer Datei gemacht werden. Teilt man ein Projekt sinnvoll in kleinere Dateien auf, kommt es nur sehr selten zu Konflikten. Werden die Dateien eines Moduls zu groß, muß es nicht zu Konflikten kommen, solange die Änderungen an der Datei sich nicht überlappen. Die Wahrscheinlichkeit für Konflikte steigt aber. 1. Konflikt feststellen Versucht man ein Modul zu committen, ohne gegenüber dem Repository auf dem neuesten Stand zu sein, bekommt man einen Fehler gemeldet. Man muß updaten: kk@boss ~/Source/testmodul $ cvs commit cvs server: Up-to-date check failed for `beispiel.c' cvs [server aborted]: correct above errors first! cvs commit: saving log message in /tmp/cvsBAATPaOrN Das Update wird dann unter Umständen für einige Dateien fehlschlagen: kk@boss ~/Source/testmodul $ cvs update RCS file: /repository/testmodul/beispiel.c,v retrieving revision 1.1 retrieving revision 1.2 Merging differences between 1.1 and 1.2 into beispiel.c rcsmerge: warning: conflicts during merge cvs server: conflicts found in beispiel.c C beispiel.c P keywords Für die Datei keywords ist das Update gelungen (P == Patched successfully) und die Datei ist auf Stand. Für die Datei beispiel.c ist es zu einem Konflikt gekommen (C == Conflict). Der Konflikt muß aufgelöst werden, bevor comitted werden kann. kk@boss ~/Source/testmodul $ cat beispiel.c [...] int main(void) { <<<<<<< beispiel.c /* Dies wird einen Konflikt ergeben. */ ======= /* Dies ist nur ein kleiner Test */ >>>>>>> 1.2 printf("Hello, World!\n"); [...] In der Datei finden sich einer oder mehrere Konfliktmarker der Form <<<<<< >>>>>>>. Im vorderen Teil steht immer die "lokale" Version aus dem Workspace, hinten die offizielle Version aus dem Repository, beide getrennt durch ======. Der Entwickler muß nun die Konfliktmarker entfernen und die beiden Versionen von Hand sychronisieren. Das kann dazu führen, daß man sich für die eine oder andere Version entscheidet oder es ganz anders löst. Hier wird diese Version committed: kk@boss ~/Source/testmodul $ cat beispiel.c [...] int main(void) { /* Dies war nur ein kleiner Test */ printf("Hello, World!\n"); [ ... ] kk@boss ~/Source/testmodul $ cvs commit ... --- Ende Handgriffe zum Auflösen von Konflikten --- -- Kristian Koehntopp