corner image
home ·Howto CVS


letzte Änderung:
TCP-States
Netzwerk
Links
Australien
Wertpapiere

Howto CVS

Von Claus Ebert

Version 0.12

Klar! Als Entwickler ist ein Versionsverwaltungssystems ein muß. Dazu bietet sich CVS, als Standard der Open Source Szene an.
Es gibt aber einige Fallstricke beim Installieren und Konfigurieren,und an die Synatx muß man sich auch erst gewöhnen.

1.CVS Client Konfiguration / Installation

2.CVS Server einrichten

3.CVS Benutzen

4.CVS-Root

5.Tricks & Tips


1. CVS Client Konfiguration / Installation

1.1 WinCVS

WinCVS ist ein Grafisches Frontend für CVS unter Windows.
Wenn die Entwicklungsungebung CVS nicht unterstützt, ist WinCVS ein sehr nützliches Tool. Die einzige Wichtige einstellung ist die des CVSROOT. z.B:

CVSROOT=:pserver:user@cvs.example.org:/usr/local/cvsroot

Hinweis: Leider kommt WinCVS mit der Port-Angabe im CVSROOT nicht zurecht. WinCVS interpretiert die Portnummer (zumindest bei mir) als Teil des Pfades zum Repository, was immer in einer Ablehnung der Verbindung beim cvs logon endet.
Das einzige was bei mir geholfen hat, ist, den Port im Einstellungsdialog einzugeben und NICHT über die CVSROOT Variable zu setzen.

top

1.2 CVS unter AIX

Da der CVS Standard Port 2401 unter AIX (leider) schon vergeben ist, muß man einen anderen Port verwenden (in meinem Fall 2402).
Mein Kollege hat dazu CVS für diesen Port als Defaultport kompiliert (auch ne lösung ;-)).
Es sollte aber auch über die Environment-Variable CVS_CLIENT_PORT oder direkt mit der CVSROOT - variable gehen ( CVSROOT=:pserver:user@cvs.example.org:2402/usr/local/cvsroot ).
Hier ist wieder der Pfad hinter der Port Nummer zu beachten.
TIP: ein touch ~/.cvspass hilft, wenn cvs das File nicht selbst anlegen kann.

top

2. CVS Server einrichten

2.1 CVS Server unter AIX einrichten

Leider ist der CVS Standard Port (2401) unter AIX schon vergeben, also nehmen wir den nächsten verfügbaren. In meinem Fall war das Port 2402.
Also frisch ans Werk:
Zuerst muß in der Datei /etc/services die Zeile

cvspserver      2402/tcp

eingefügt werden.
Jetzt müssen wir nur noch dem inetd sagen was er tun soll.
Dazu fügen wir in die Datei /etc/inetd.conf folgende Zeile ein:

cvspserver  stream  tcp  nowait  root  /usr/local/bin/cvs 
          cvs -f --allow-root=/usr/cvsroot pserver

Die beiden Zeilen oben müssen hintereinander in einer Zeile stehen

Unter --allow-root={pfad} sollte ein eingerichtetes Repository verfügbar sein (siehe Einrichten eines Repositories ).
Das war es eigendlich schon. Nun muß nur noch dem Client beigebracht werden, das er den Port 2402 verwenden soll.

top

2.2 CVS Server unter Linux/Debian einrichten

Unter Debian ist es eigendlich ganz einfach: mit
>apt-get install cvs
CVS installieren. Danach müssen die Fragen nur noch beantwortet werden und der CVS-Server sollte betriebsbereit sein.

Falls die configuration wiederholt werden soll, dann hilft einem ein
>dpkg-reconfigure cvs
bestimmt weiter.

top

3. CVS Benutzen

3.1 Einrichten eines Repositories

Das CVS-Repository ist das zentrale Verzeichnis, in dem alle Dateien und Unterverzeichnisse verwaltet werden. Ich nehme hier als Beispiel ein CVS Repository in /var/log/CVS  an. Deswegen sollte als Vorbereitung die Umgebungsvariable CVSROOT auf dieses Verzeichnis gesetzt werden, z.B. in der bash mit:

>export CVSROOT=/var/log/CVS

Ein Repository kann als root angelegt werden, mit:
mkdir -p /var/log/CVS/CVSROOT
mkdir -p /var/log/CVS/Module

In /var/log/CVS/ speichert CVS seine Daten. CVS nennt dies ein Repository.
In /var/log/CVS/Module speichert CVS die Daten zum Projekt Module Doku. CVS nennt dies ein Modul.

Falls noch nicht geschehen sollte jetzt die CVS-Gruppe und der CVS-User angelegt werden:

>groupadd cvs
>useradd -g users -G cvs -m cvs_user
>cd /var/log/CVS
>chown -R cvs_user.cvs Module

groupadd und useradd brauche ich hier nicht zu beschreiben.
Wichtig ist nur daß das Repository dem CVS-User (cvs_user) zugewiesen werden muß und er schreibrechte auf alle Modul-Unterverzeichnisse hat.

Wichtig!!! Nie die Dateien im Repository direkt ändern !!!
Wichtig!!! Verzeichnisse sind später nicht zu entfernen !!!

Zu guter letzt müssen wir cvs nur noch das Repository initialisieren lassen. Das tun wir mit:

>cvs -d /var/log/CVS init

cvs init ist "vorsichtig". D.h. es löscht nie Dateien im Repository, könnte also gefahrlos auch später aufgerufen werden.
Wir haben nun ein leeres Repository angelegt.
Um es mit Leben zu füllen müssen wir zuerst ein Modul in das Repository importieren

top

3.2 Importieren in das Repository

In das Repository kann von jedem Rechner in Netzwerk importiert werden. Vorausgesetzt wird lediglich, das CVS installiert und die Environment-Variable CVSROOT gesetzt ist.

Alle Dateien, die sich in dem Verzeichnis befinden, in dem wir momentan sind weden mit
>cvs import -m "initial Import" Module Original alpha
in das Repository aufgenommen.

Beim Import erwartet CVS diese Syntax:
>cvs import -m <Kommentar> <Modul-Name> <Vendorname> <Revision-tag>

Vendorname und Revision-Tag müssen angegeben werden, aber der Inhalt ist beliebig. CVS nimmt nun die Daten in seine Verwaltung auf.

Falls man den gerade importierten Versionsstand wieder (trotz einiger Änerungen) wieder restaurieren will, empfiehlt es sich, jetzt ein Tag zu setzen:
>cvs tag -F Original Module
Die Daten im jetztigen Zustand bekommen den Tag "Original".
Der Parameter -F bedeudet Force und überschreibt ein Tag falls es schon im Repository vorhanden sein sollte.... hmmm ...
OK. Wenn eine Datei im Repository bereits mit diesem Tag markiert ist, aber bereits eine (einige) neue Versionen dieser Datei committet wurden, dann wandert das Tag zu der neuesten Version der Datei.
Dieser Parameter eignet sich also auch um ein Tag zu einer neueren Version zu verschieben.
Dies ist aber mit Vorsicht zu geniesen, da so die konsistenz der 'alten' Version dann nicht mehr gewährleistet ist.

top

3.3 Auschecken (cvs checkout)

>cvs checkout -r Original Modul
CVS erzeugt im aktuellen Arbeitsverzeichnis das Unterverzeichnis Modul an und exportiert alle im Repository befindlichen Dateien und Unterverzeichnisse des Moduls Modul.

Der Parameter -r  bedeudet das alle Dateien die mit dem Tag
Orginal markiert wurden exportiert werden.

Auschecken in ein anderes Verzeichnis, als durch den Modulnamen vorgegeben:
Mit dem Parameter -d kann man angeben, in welches Verzeichnis das Modul ausgecheckt werden soll.
z.B :
>cvs checkout -d neuModule Module

veranlasst cvs das Modul Module in das Verzeichnis neuModule auszuchecken.

top

3.4 Änderungen dem Repository hinzufügen (cvs commit)

>cvs commit Module
Durch diesen Befehl werden die geänderten Daten ins Repository übernommen, dazu wird der Editor aufgerufen und ein Kommentar kann zu den Änderungen eingegeben werden.

Welcher Editor verwendet wird, kann man über die Environment-Variable EDITOR festlegen.

z.B:
>cvs tag -F alpha1 Module
versieht die aktuelle Version mit einem neuen Versions-Tag.

top

3.5 Hinzufügen von Dateien

Hinzufügen einer Datei: (in diesem Fall der Datei tuWas )

>cd Module
>vi tuWas ... <esc> :wq! (Windows: einfach Notepad benutzen)
>cvs add tuWas
Datei wird fürs Hinzufügen NUR vorgemerkt! Mit einem

>cvs commit
wird die neue Datei ins Repository aufgenommen.

Jetzt ist ein guter Zeitpunkt ein neues Versions-Tag zu setzen. Das beschieht folgendermaßen:
>cd ..
>cvs tag -F "tuWas_hinzugefuegt" Module
Der neue Versions-Tag ist gesetzt. Verzeichnisse werden analog hinzugefügt. Jedoch geschieht dies nicht rekursiv!

top

3.6 Entfernen von Dateien

Im CVS-Kontext bedeutet das Entfernen einer Datei, daß die alte Version im Repository erhalten bleibt, aber beim checkout nicht mehr ausgeliefert wird.

>cd Module
>rm tuWas
entfernt die Datei tuWas aus dem Arbeitsverzeichnis.
>cvs remove tuWas
markiert die Datei tuWas zum löschen. Aber erst mit
>cvs commit
wird das "löschen" ausgeführt.
Die Datei wird bein nächsten checkout oder update nicht mehr berücksichtigt.

>cd ..
>cvs tag -F "tuWas entfernt" Module
Tagt (Markiert) alle Dateien des Moduls.

top

3.7 Entfernte Datei zurückholen

Um die Datei tuWas wieder zurückzuholen müssen wir dem checkout Kommando sagen welche Version wir haben wollen.

>cvs checkout -r "tuWas_hinzugefuegt" Module
Dies hat aber einen "sticky" Tag zur Folge. "sticky" meint in diesem Fall, daß die durch -r {Version} mitgegebene Version bis auf weiteres diejenige bleibt, auf die sich die folgenden Updates beziehen.

>cvs update -A
holt die neueste Version und entfernt dabei "sticky" Tags

>cvs update -p -r "tuWas_hinzugefuegt" Module
holt die ältere Version, in der die Datei noch existiert, gibt diese aber einfach in die Konsole aus.

top

3.8 Datei umbenennen

Um eine Datei umzubenennen, genügen einige einfache Kommandos:
>mv foo bar
Die Datei foo in bar umbenennen.
>cvs remove foo
Die Datei foo im CVS-Repository als entfernt markieren.
>cvs add bar
Die neue Datei bar hinzufügen.
>cvs commit -m "Renamed foo to bar" foo bar 
Die Änderungen ins repository übernehmen.

Dabei ändert sich die Versionsnummer. Wenn das nicht gewünscht wird, kann mit
>cvs commit -r 3.0
eine Versionsnummer vorgegeben werden.
Achtung: Die neue Versionsnummer muß höher sein als alle aktuell im Modul verwendeten.

top

3.9 alte Versionen benutzen

Um eine Datei in einer alter oder getaggten Version aus CVS herauszuholen benutzen wir den Update -Befehl zusammen mit der -r option

>cvs up - r 1.12 Makefile
Hiermit wird die Date Makefile aud die im Reposotory vorhandene Version 1.12 up- oder downgegradet.

Das ganze funktioniert natuerlich auch für getaggte Versionen
>cvs up - r "TESTVERSION" Makefile
hiermit wird das Makefile mit dem Tag TESTVERSION aus dem Repository geholt

Das ganze kann natürlich auch mit find kombiniert werden:
>find . -name Makefile -exec cvs update -r TESTVERSION '{}' \;
hiermit wird das Makefile mit dem Tag TESTVERSION aus dem Repository für dieses und alle Subdirecturies geholt

top

3.10 Unterschiede zwischen Versionen

Der -Befehl liefert die Unterschiede zwischen der Datei im lokalen Verzeichnis und der im Repository oder zwischen verschiedenen Versionen:

>cvs diff
Ohne weitere Parameter werden die unterschiede zwischen den Dateien im aktuellen Verzeichnis, und den Dateien im Repository ausgegeben.

Um direkt die Unterschiede zwischen zwei Versionsnummern angezeigen zu lassen, bekommt diff die Option -r (für Revision) mit auf den Weg:
>cvs diff -r 3.0 -r 3.12 Module
In diesem Beispiel werden die Unterschiede zwischen den Versionen 3.0 und 3.12 ausgegeben.

Was für Versionen funktioniert, geht natürlich auch für Dati:
>cvs diff -D 09/11/2000 -D 09/19/2000 Module
Das Beispiel zeigt Unterschiede zwischen Versionen vom 11.09.2000 und vom 19.09.2000 auf.
(Datum im Format mm/dd/yyyy)

Alle Unterschiede seit dem letzten checkout werden von
>cvs diff -u Module
angezeigt.

Führt man vor jedem commit ein:
>cvs diff -u Module >>Module.changelog
aus, erhält man mit der Zeit eine Changelog-Datei ohne diese selbst zu bearbeiten zu müssen.

top

3.11 Branches

Erzeugen eines Branches (Ast), der unabhängig vom Haupt-(Datei)-Baum bearbeitbar ist. Branches können eigenständig bleiben oder später zum Haupt-Baum hinzugefügt werden ("merge"):

Um einen neuen Branch einzufügen verwenden wir folgenden Befehl:
>cvs tag -b branch_tag foo.cpp

Dies erzeugt einen neuen Zweig (Branch) für die Datei foo.cpp mit dem Tag branch_tag im Repository, ausgehend von der Version, die sich momentan im Arbeitsverzeichnis befindet.

Achtung!! Es wurde nur der Zweig erzeugt. Man arbeitet aber nicht automatisch im neuen Branch!!!

Um mit dem neuen Branch arbeiten zu können müssen wir diesen zuerst in unser Arbeitsverzeichnis holen:

>cvs update -r branch_tag foo.cpp

so ... jetzt haben wir den Branch im Arbeitsverzeichnis, was wir mit einem

>cvs status foo.cpp

überprüfen können.

VARIANTE:

>cvs checkout -d ./test_branch -r branch_tag foo.cpp

Erzeugt ein Verzeichnis test_branch und legt die Dateien in diesem ab. Dadurch kann man mehrere Branches parallel bearbeiten.

Jetzt ist unser Arbeitsverzeichnis auf den neuen Branch eingestellt, und wir können mit einem ganz normalen

>cvs commit foo.cpp

Änderungen in den Branch übernehmen.

top

3.12 Die History

Auslesen der History:
>cvs history -e
gibt alles aus

>cvs history -m {Module}
gibt nur die History dieses Modules aus

>cvs history -c
Info über "commited files"

>cvs history -o
Info über "checked out files"

top

3.13 Exportieren

Um nur die "Nutzdaten" vom 24.12.2002 ohne die Verwaltungsdateien von CVS zu erhalten (in das lokale Verzeichnis ExportModul ):
>cvs export -d ExportModul -D 12/24/2002  Modul

top

3.14 update

Um die eigene Arbeitsversion einer Datei mit den Änderungen anderer Bearbeiter zu synchronisieren, führt man cvs update aus:
>cvs update Doku_CVS

top

3.15 Ignorieren von Dateien

Befinden sich bei einem CVS Update Dateien im lokalen Arbeitsverzeichnis, die nicht von CVS verwaltet werden, ergibt sich eine Meldung wie:
? Doku_CVS//Comment
Um solche Meldung zu verhindern, kann man sich in seinem Homeverzeichnis die Datei .cvsignore anlegen. Pro Zeile ein Dateiname, * als Joker.

cvs ignoriert von selbst bereits alle Dateien mit:
.bak    .BAK    .o      .obj    CVS     RCS     core

top

3.16 Kurze Kommandoübersicht

CVS Kommandos mit Syntax :
>cvs import [-m {Kommentar}] {Modulname} {Vendor-Tag} {Revision-Tag}
>cvs checkout [-P] [-r {tag}] {Modulname}
>cvs commit [-r {tag}] [{datei}] [{Modulname}]
>cvs update [-p] [-r] [-A] [{tag}] [{Modulname}]
>cvs tag [-b] [-F] {tag} {Modulname}
>cvs rtag [-b] -r {tag} {Modulname}
>cvs add {datei}
>cvs remove [-f] [-l] [-R] {datei}
>cvs -d {CVSROOT-path} init
>cvs history [-m {Modulname}] [-e] [-o]
>cvs export -d {Verzeichnisname} [-D {Datum}] [-r {tag}]{Modulname}

top

4. CVS-Root

4.1 Beispiele für die Variable CVSROOT

CVSROOT=:pserver:user@cvs.example.org:2402/usr/local/cvsroot 
pserver = die Verbindung zum entfernter CVS-Server soll über TCP/IP aufgebaut werden.
user = dieser User wird zum login verwendet.
cvs.example.org Domain oder IP des Rechners am den sich CVS verbinden soll.
2402 Port an den sich CVS verbinden soll. (2401 ist default).
/usr/local/cvsroot Verzeichnis des Repositories (auf dem CVS-Server)

CVSROOT=/devel/CVSROOT
Es soll das Repository auf der lokalen Platte im Verzeichnis /devel/CVSROOT verwendet werden.

top

5. Tricks & Tips

5.1 Zweites Repository verwenden

Hat man die Variable $CVSROOT nicht gesetzt oder will sie nicht ändern, weil sie auf ein weiteres, benutztes Repository verweist, kann mit
>cvs -d 10.0.0.216:/var/CVS  checkout alice
der Pfad nach -d übergeben werden. Die Pfadangabe muß absolut sein.

top

5.2 Lokale kopie an ein neues Repository anpassen

Wenn das Repository auf einen anderen Server verschoben wird, muß man normalerweise seine lokale Arbeitskopie neu auschecken, was aber nicht immer gewünscht ist.

Falls (aus welchen Gründen auch immer) das Repository auf einen anderen Server verschoben wurde, kann man in der lokalen Arbeitskopie keinen Update oder Commit mehr ausführen.
cvs ist so intelligent, das es den Inhalt von CVSROOT für jedes Verzeichnis speichert, und bei allen weiteren cvs-operationen als default verwendet.

Das ist prinzipiell wunderbar, denn nur so sind die 'kurzen' cvs Befehle erst möglich.

>cvs update anstatt >cvs -d /usr/local/cvsroot update

Falls aber der CVS-Server einen neuen Namen (usw..) bekommen hat, versucht cvs immer sich zum alten Server zu verbinden.
Folgendes script Ersetzt alle alten Einträge mit denen des neuen Servers so das ein komplett neuer checkout nicht mehr notwendig ist:

>cd /das/lokale/arbeitsverzeichnis/
for f in `find . -name "Root"|grep "/CVS/Root"`
do
  cat $f|sed -e"s/alter.cvs.server/neuer.cvs.server/" > /tmp/tmpf; mv /tmp/tmpf $f
done

Hinweis: Das Verzeichnis /tmp sollte vorhanden sein.

top
  ©2016· Claus Ebert · Emailemail senden