

	\documentclass[a4paper,11pt]{article}
	\usepackage{ngerman}
	\usepackage[latin1]{inputenc}
	\setlength\parskip{\medskipamount}
	\setlength\parindent{0pt}
	\begin{document}

	
 % tipps_und_troubleshooting
 % Copyright 
 % Lizenz: GPL
 % 
 % $Name: $
 % $Revision: 1.3.2.6 $
 % $Source: /cvsroot/selflinux/tutorial/software/development/version_control/cvs/cvs_buch/kapitel_8/kapitel_8,v $
 % SelfLinux-0.7.2
 %
 % Diese Datei ist Teil von SelfLinux http://www.selflinux.de
 %
 %%% $Id: kapitel_8,v 1.3.2.6 2002/12/15 18:47:30 fboerner Exp $

	\title{Tipps und Troubleshooting}


	
	    \author{}
	    %\url{mailto:}
    

	\maketitle

	
	
	%\ref{../index.tex}
	
		%\ref{programmierung.tex}
		Programmierung
		%\ref{cvs.tex}
		CVS
	\ref{tipps_und_troubleshooting}

    \par{Layout}
    Matthias Hagedorn
	    %\url{mailto:herbert-kw@t-online.de}
    
    	\par{Lizenz}
	GPL
 
	\tableofcontents{}

        
	\section{Wenn mal was schief läuft} \label{d77e56}
        

   

   
  \par
  
Ich habe schon in den vorangegangenen Kapiteln betont, dass CVS keine
{\bf Blackbox}-Software ist. In eine {\bf Blackbox} kann man nicht
hineinschauen, sie bietet keinen Zugriff auf die inneren Vorgänge,
sodass man nichts bereinigen kann (aber auch nichts durcheinander
bringen). Die Prämisse ist die, dass bei einer {\bf Blackbox}
normalerweise nichts bereinigt werden muss. Die Software sollte die
meiste Zeit über perfekt laufen, daher brauchen sich die Anwender
nicht um die inneren Vorgänge zu kümmern. Wenn eine {\bf Blackbox}
ausfällt, so geschieht das jedoch meist gründlich. Jedes Problem
bedeutet den Totalausfall, da man nicht viele Möglichkeiten hat,
etwas zu reparieren.
   

   
  \par
  
CVS ist eher eine völlig transparente Box - nur ohne die Box. Die
beweglichen Teile sind der Umwelt direkt ausgesetzt - nicht etwa
hermetisch abgeschlossen -, und Teile der Umwelt (unerwartete
Dateizugriffs echte, abgebrochene Kommandos, konkurrierende Prozesse,
was auch immer) können manchmal in den Mechanismus gelangen und
sozusagen das Uhrwerk blockieren. Aber selbst wenn CVS nicht immer
perfekt läuft, so fällt es auch fast nie komplett aus. Es hat den
Vorteil des kontrollierten Leistungsrückgangs, und der Grad, zu dem es
nicht perfekt läuft, ist für gewöhnlich proportional zur Anzahl und
Schwere der in seiner Umgebung auftretenden Probleme. Wenn man genug
darüber weiß, was CVS zu tun versucht - und wie es das versucht -,
wird man wissen, was im Problemfall zu tun ist.
   

   
  \par
  
Obwohl ich hier natürlich nicht alle Probleme aufzählen kann, an die
Sie geraten können, so habe ich doch versucht, die häufigsten hier
abzudecken. Das Kapitel ist in zwei Teile aufgeteilt: Der erste
beschreibt die Umgebungseinflüsse, auf die CVS am empfindlichsten
reagiert (hauptsächlich Zugriffsrechte im Archiv und die der
Verwaltung dienenden Teile der Arbeitskopie), und der zweite Teil
behandelt einige der am häufigsten anzutreffenden Probleme und deren
Lösung. Indem Sie sich damit befassen, wie man diese
Standardsituationen meistert, werden Sie auch ein Gefühl dafür
bekommen, wie man an unerwartete Probleme im CVS herangeht.
   
  \section{Die üblichen Verdächtigen} \label{d77e88}
        

   

   
  \par
  
Als CVS-Administrator (oder Notarzt) merkt man schnell, dass 90
Prozent der Probleme, welche die Anwender haben, durch Inkonsistenzen
in deren Arbeitskopien und die übrigen 90 Prozent durch falsche
Zugriffsrechte im Archiv verursacht werden. Deshalb werde ich, bevor
wir uns den einzelnen Situationen widmen, einen kurzen Überblick über
den administrativen Teil der Arbeitskopien geben und einige wichtige
Tatsachen über die Zugriffsrechte ansprechen
   

   \subsection{Der administrative Teil der Arbeitskopie} \label{d77e98}
        

    

    
  \par
    
In Kapitel 2 haben Sie schon die Grundlagen des Aufbaus einer
Arbeitskopie kennen gelernt; in diesem Abschnitt werden wir ein wenig
mehr ins Detail gehen. Dabei geht es hauptsächlich um die Dateien in
den administrativen Unterverzeichnissen, die den Namen {\bf CVS/} tragen.
{\bf Entries}, {\bf Root} und {\bf Repository} haben Sie bereits kennen gelernt, doch in
{\bf CVS/} können sich auch noch andere, von der Situation abhängige
Dateien befinden. Diese Dateien werde ich jetzt beschreiben, teils,
damit sie Sie nicht überraschen, wenn Sie sie antreffen, teils, damit
Sie von ihnen verursachte Probleme lösen können.
      

    
  \par
    
{\bf CVS/Entries.Log}
      

    
  \par
    
Gelegentlich wird eine Datei namens {\bf CVS/Entries.Log} auf mysteriöse
Weise erscheinen. Der einzige Zweck dieser Datei ist es, kurzzeitig
kleinere Änderungen an {\bf CVS/Entries} zwischenzuspeichern, und zwar so
lange, bis eine Operation ansteht, die so wichtig ist, dass es sich
lohnt, die gesamte Datei {\bf Entries} neu zu schreiben. CVS kann
Änderungen in der Datei Entries nicht an Ort und Stelle vornehmen,
sondern muss, um eine Änderung vorzunehmen, die ganze Datei einlesen
und wieder zurück schreiben. Um das zu vermeiden, vermerkt CVS
manchmal kleine Änderungen in {\bf Entries.Log}, bis es {\bf Entries} das nächste
Mal neu schreiben muss.
      

    
  \par
    
Das Format von {\bf Entries.Log} ist das gleiche wie das von {\bf Entries}, bis
auf einen zusätzlichen Buchstaben am Anfang jeder Zeile. {\bf A} bedeutet,
dass die Zeile der Datei {\bf Entries} hinzuzufügen ist, und {\bf R} heißt,
dass die Zeile entfernt werden muss.
      

    
  \par
    
Sie können {\bf Entries.Log} fast immer ignorieren, es kommt sehr selten
vor, dass ein menschliches Wesen deren Inhalt verstehen muss. Wenn Sie
jedoch {\bf Entries} durchgehen, um ein Problem in der Arbeitskopie zu
beheben, dann sollten Sie auch {\bf Entries.Log} untersuchen.
      


    
  \par
    
{\bf CVS/Entries.Backup} 
      

    
  \par
    
Die Datei {\bf CVS/Entries.Backup} ist der Ort, wohin CVS die neue
{\bf Entries}-Datei schreibt, bevor es sie in {\bf Entries} umbenennt. (Ähnlich
wie es erst temporäre {\bf RCS}-Dateien in das Archiv schreibt und sie
erst, wenn sie fertig gestellt sind, an den vorgesehenen Ort
verschiebt und umbenennt.) Da die Datei {\bf Entries.Backup} zu {\bf Entries}
wird, werden Sie selten eine Datei namens {\bf Entries.Backup} zu Gesicht
bekommen; wenn doch, dann bedeutet das vermutlich, dass CVS inmitten
einer Operation abgebrochen wurde.
      


    
  \par
    
{\bf CVS/Entries.Static}
      

    
  \par
    
Wenn eine Datei {\bf CVS/Entries.Static} existiert, dann heißt das, dass
nicht das ganze Verzeichnis aus dem Archiv geholt wurde. (Wenn CVS
weiß, dass die Arbeitskopie in einem unvollständigen Zustand ist,
wird es keine zusätzlichen Dateien in das Verzeichnis bringen.)
      

    
  \par
    
Die Datei {\bf Entries.Static} ist während eines {\bf Checkout}  oder eines {\bf Update}
vorhanden und wird sofort entfernt, wenn die Operation abgeschlossen
ist. Wenn Sie also eine Datei {\bf Entries.Static} sehen, dann heißt das,
dass CVS unterbrochen wurde und dass deren Vorhandensein CVS vom
Anlegen neuer Dateien in der Arbeitskopie abhält. (Oftmals löst der
Aufruf von {\bf cvs update -d} das Problem und entfernt {\bf Entries.Static}.)
      


    
  \par
    
Bemerkung
      

    
Das Nichtvorhandensein von {\bf Entries.Static} bedeutet nicht automatisch,
dass die Arbeitskopie alle Dateien des Projektes enthält. Jedes Mal,
wenn ein neues Verzeichnis im Archiv des Projekts angelegt wird und
jemand seine Arbeitskopie aktualisiert, ohne {\bf -d} bei {\bf update} anzugeben,
wird das neue Verzeichnis nicht in der Arbeitskopie angelegt werden.
Lokal betrachtet weiß CVS nichts davon, dass es ein neues Verzeichnis
im Archiv gibt, und wird die Datei {\bf Entries.Static} entfernen, wenn das
{\bf Update} gelaufen ist, selbst wenn das neue Verzeichnis nicht in der
Arbeitskopie vorhanden ist.
    

   
  \par
    
{\bf CVS/Tag}
     

   
  \par
    
Wenn die Datei {\bf CVS/Tag} vorhanden ist, so benennt sie eine Marke, die
sozusagen dem Verzeichnis zugeordnet ist. Ich sage bewusst
{\bf sozusagen}, da, wie Sie ja wissen, CVS keinerlei Revisionshistorie
für Verzeichnisse vorhält und streng genommen auch keine Marken an
ihnen anbringen kann. Marken werden nur an normale Dateien
angebracht, oder, genauer gesagt, bestimmten Revisionen einer normalen
Datei zugeordnet.
     

   
  \par
    
Wenn jedoch jede Datei in einem Verzeichnis einer bestimmten Marke
zugeordnet ist, dann stellt sich CVS die Marke als auch an dem ganzen
Verzeichnis angebracht vor. Wenn Sie zum Beispiel eine Arbeitskopie
aus einem bestimmten Zweig per {\bf Checkout} holen
     

   
    \begin{tt} \begin{scriptsize} user@linux \~{}/ \$  
cvs co -r Bugfix\_Branch\_1
     \end{scriptsize} \end{tt} \linebreak 
   

   
  \par
    
und dann eine Datei hinzufügen, so ist es wünschenswert, dass die
Anfangsrevision der Datei auch diesem Entwicklungszweig zugeordnet
ist. Aus ähnlichen Gründen muss CVS wissen, ob das Verzeichnis eine
sonstige bindende Marke2 oder einen Datumsstempel aufweist.
     

   
  \par
    
Die für die Marken zuständigen Dateien ({\bf CVS/Tag}) enthalten nur eine
Zeile. Das erste Zeichen dieser Zeile ist ein einbuchstabiges Kürzel,
das aussagt, um was für eine Marke es sich handelt; der Rest der
Zeile ist der Name der Marke. Zurzeit verwendet CVS nur diese drei
einbuchstabigen Kürzel:
     

   
  \par
    
{\bf T}-Die Marke eines Zweiges
     

   
  \par
    
{\bf N}-eine normale Marke (also nicht die Marke eines Zweiges)
     

   
  \par
    
{\bf D}-ein bindendes Datum. So etwas tritt auf, wenn ein Kommando wie
     

   
    \begin{tt} \begin{scriptsize} user@linux \~{}/ \$  
cvs checkout -D 1999-05-15 myproj
     \end{scriptsize} \end{tt} \linebreak 
   

   
  \par
    
oder
     

   
    \begin{tt} \begin{scriptsize} user@linux \~{}/ \$  
cvs update -D 1999-05-15 myproj
     \end{scriptsize} \end{tt} \linebreak 
   

   
  \par
    
gestartet wird.
     

   
  \par
    
(Wenn Sie noch andere einbuchstabige Kürzel entdecken, dann heißt das,
dass CVS neue Markenarten eingeführt hat, seitdem dieses Kapitel
geschrieben wurde.)
     

   
  \par
    
Sie sollten die Datei {\bf Tag} nicht von Hand entfernen; verwenden Sie
besser {\bf cvs update -A}.
     

   
  \par
    
{\bf Echte Seltenheiten} 
     

   
  \par
    
Es gibt noch andere Dateien, die Sie gelegentlich im
{\bf CVS/}-Unterverzeichnis vorfinden können:
     

   
  \par
    
{\bf CVS/Checkin.prog, CVS/Update.prog
CVS/Notify, CVS/Notify.tmp
CVS/Base/, CVS/Baserev, CVS/Baserev.tmp
CVS/Template}
     

   
  \par
    
Diese Dateien verursachen normalerweise keine Probleme, daher führe
ich sie hier nur der Vollständigkeit halber auf (siehe Kapitel 9 für
deren vollständige Beschreibung).
     


   
  \par
    
{\bf Portabilität und zukünftige Erweiterungen}
     

   
  \par
    
Jedes Mal, wenn CVS neue Features hinzugefügt werden, können neue
Dateien (die ier nicht aufgeführt sind) in den administrativen
Abteilungen der Arbeitskopien auftreten. Wenn es neue Dateien gibt,
so werden sie wahrscheinlich im Cederqvist unter {\bf Working Directory
Storage} dokumentiert. Wenn Sie es vorziehen, aus dem Quelltext zu
lernen, können Sie auch in {\bf src/cvs.h} aus der Quelltextdistribution
nachlesen.
     

   
  \par
    
Bedenken Sie, dass alle {\bf CVS/*}-Dateien - aktuelle und zukünftige -
jeweils die Zeilenendekennung verwenden, die für das lokale System der
Arbeitskopie (zum Beispiel LF unter UNIX, CRLF unter Windows)
angebracht ist. Das bedeutet, dass wenn Sie eine Arbeitskopie von
einer Maschine auf eine andere verfrachten, CVS sie nicht mehr
verarbeiten können wird. (Sie haben dann aber noch ganz andere
Probleme, da die unter Revisionskontrolle stehenden Dateien selbst
die für ihre neue Heimat falsche Zeilenendekennung haben werden.)
     
   

   \subsection{Zugriffsrechte im Archiv} \label{d77e400}
        

    

    
  \par
    
CVS setzt nicht ein bestimmtes Schema bei der Vergabe der
Zugriffsrechte im Archiv voraus - es kommt mit einem breiten Spektrum
davon aus. Um allerdings einem verwirrenden Verhalten vorzubeugen,
sollten Sie sicherstellen, dass Sie sich beim Einrichten des Archivs
an die folgenden Kriterien halten:
      

    
  \par
    
Wenn ein Benutzer irgendeine Form des Zugriffs auf ein
Unterverzeichnis im Archiv wünscht - und sei es nur lesender Zugriff -
benötigt er für gewöhnlich auf Systemebene Schreibzugriff auf das
Unterverzeichnis. Das ist nötig, weil CVS temporäre Lockfiles im
Archiv erzeugt, um die Datenkonsistenz gewährleisten zu können. Auch
reine Leseoperationen (wie {\bf checkout} oder {\bf update}) erzeugen Lockfiles,
die anzeigen, dass die Daten, bis sie fertig sind, in ein und
demselben Zustand zu bleiben haben.
      

    
  \par
    
Wie schon in Kapitel 4 besprochen, kann man die Notwendigkeit der
Schreibberechtigung umgehen, indem man in {\bf CVS/config} den Parameter
LockDir wie folgt setzt:
      

    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
CVS/config
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
     
LockDir=/usr/local/cvslocks
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}

    
  \par
    
Natürlich müssen Sie dann dafür sorgen, dass das Verzeichnis
{\bf /usr/local/cvslocks} für alle Benutzer von CVS schreibbar ist. In jedem
Fall benötigen die meisten CVS-Operationen, auch die rein lesenden,
irgendwo ein beschreibbares Verzeichnis. Als Vorgabe ist dieses
Verzeichnis das des Archivs; wenn Sie sehr sicherheitsbewusst sind,
dann lenken Sie es woandershin um.
      

    
  \par
    
Stellen Sie sicher, dass die Datei {\bf CVSROOT/history} (wenn sie
existiert) world-writeable3 ist. Wenn die History-Datei existiert,
dann versuchen die meisten CVS-Operationen ihr einen Eintrag
hinzuzufügen, und wenn dieser Versuch fehlschlägt, schlägt die ganze
Operation mit einer Fehlermeldung fehl. Leider (und
unerklärlicherweise) ist die History-Datei nicht von Geburt an
world-writeable, wenn Sie ein neues Archiv mit {\bf cvs init} erzeugen.
Zumindest bei der derzeit aktuellen CVS-Version sollten Sie deren
Zugriffsrechte direkt nach dem Erzeugen des neuen Archivs ändern (oder
die Datei einfach entfernen, wenn Sie das Speichern der
Projekthistorie gänzlich unterbinden wollen).
      


    
  \par
    
Bemerkung
      

    
Dieses Problem könnte sich von alleine lösen - ich habe den Betreuern
von CVS einen Patch zukommen lassen, durch den die History-Datei
world-writeable wird, wenn ein neues Archiv angelegt wird. Wenn Sie
also eine neuere Version von CVS beziehen, als gerade erhältlich ist
(Stand: September 1999), könnte das Problem Sie nicht mehr betreffen.
    

    
  \par
    
Aus Sicherheitsgründen sollten Sie dafür sorgen, dass die meisten
Benutzer von CVS auf Unix-Ebene keinen Schreibzugriff auf das
{\bf CVSROOT}-Verzeichnis haben. Wenn jemand Checkin-Zugriff auf {\bf CVSROOT}
hat, dann kann er {\bf commitinfo}, {\bf loginfo} oder beliebige andere triggernde
Dateien so anpassen, dass beliebige Programme seiner Wahl aufgerufen
werden, er könnte sogar ein neues Programm mit einem {\bf Commit} in das
System bringen, wenn das, was er haben möchte, sich noch nicht dort
befindet. Sie sollten daher davon ausgehen, dass jeder, der {\bf Commit}-
Zugang zu {\bf CVSROOT} hat, in der Lage ist, beliebige Kommandos im System
abzusetzen.
      
    
  \section{Häufige Probleme und deren Lösung} \label{d77e487}
        

   

   
  \par
  
Der Rest dieses Kapitels ist in einer Folge von Fragen und Antworten
organisiert, ähnlich den FAQ (Frequently Asked Questions4) aus dem
Internet. Sie alle stammen aus wirklichen Erfahrungen mit CVS. Aber
bevor wir uns die einzelnen Fälle ansehen, wollen wir uns noch einen
Moment Zeit nehmen und uns die CVS Fehlerbehebung allgemein ansehen.
   

   
  \par
  
Der erste Schritt bei der Behebung eines CVS-Problems ist
üblicherweise der, festzustellen, ob es sich um ein Problem in der
Arbeitskopie oder im Archiv handelt. Die beste Technik dafür - und
das wird niemanden überraschen -, ist zu überprüfen, ob das Problem
auch in anderen Arbeitskopien, als in der, bei der es erstmals
festgestellt wurde, auftritt. Wenn das der Fall ist, dann ist es
vermutlich ein Problem im Archiv, ansonsten wohl ein lokales Problem
der betroffenen Arbeitskopie.
   

   
  \par
  
Probleme in den Arbeitskopien treten häufiger auf. Nicht etwa, weil
Arbeitskopien irgendwie weniger zuverlässig sind als das Archiv,
sondern weil jedes Archiv normalerweise mehrere Arbeitskopien hat.
Obwohl die meisten {\bf Verknotungen} in einer Arbeitskopie mit genügend
Geduld aufgelöst werden können, ist es häufig effizienter von der
Zeit her, einfach die Arbeitskopie zu löschen und mittels {\bf Checkout} neu
anzulegen.
   

   
  \par
  
Wenn natürlich das Auschecken zu lange dauert oder sich noch
wesentliche Änderungen, die Sie noch nicht per {\bf Commit} in das Archiv
gespeichert haben und die Sie nicht verlieren wollen, in der
Arbeitskopie befinden, oder Sie einfach wissen wollen, was denn nun
schief gelaufen ist, dann lohnt es sich, etwas herum zu stochern und
die Ursache des Problems herauszufinden. Beim Herumstochern sind die
ersten Orte, an denen man suchen sollte, die {\bf CVS/}-Unterverzeichnisse.
Prüfen Sie die Dateiinhalte und die Dateizugriffsrechte. Ganz
vereinzelt kann es vorkommen, dass die Zugriffsrechte auf einmal {\bf nur
lesbar} oder sogar noch nicht einmal lesbar werden. (Ich vermute,
dass das eher daran liegt, dass sich ein Benutzer bei einem
Unix-Kommando vertippt hat, statt dass ein Fehler aufseiten von CVS
vorliegt.)
   

   
  \par
  
Probleme im Archiv werden fast immer von falsche Datei- oder
Verzeichniszugriffsrechten verursacht. Wenn Sie vermuten, dass ein
Problem an falschen Zugriffsrechten im Archiv liegt, sollten sie erst
einmal die effektive Benutzerkennung5 derjenigen Person, die das
Problem hat, herausfinden. Bei allen lokalen und bei den meisten
nicht lokalen Benutzer ist das entweder der normale Benutzername oder
der Benutzername, den sie beim Auschecken ihrer Arbeitskopie
angegeben haben. Wenn Sie die pserver-Methode zusammen mit
user-aliasing verwenden (siehe Abschnitt {\bf Der
Passwortauthentisierungs-Server} in Kapitel 4), dann ist die
Benutzerkennung diejenige, die in der Datei {\bf CVSROOT/passwd} steht.
Wenn Sie das nicht gleich bemerken, können Sie eine Menge Zeit damit
verschwenden, den Fehler an der falschen Stelle zu suchen.
   

   
  \par
  
Doch jetzt, ohne weitere Umschweife ...
   

   \subsection{Alltägliche Probleme und ihre Lösung} \label{d77e539}
        

    

    
  \par
    
Die folgenden Situationen habe ich erlebt, als ich anderen bei ihren
Abenteuern mit CVS zur Seite gestanden habe. Dazu kommen noch einige
Punkte, die keine echten Probleme sind, sondern lediglich Fragen, die
mir schon einmal gestellt wurden und die ich hier beantworten möchte.
Ich halte diese Liste für ziemlich umfassend, und manches, was Sie
schon in früheren Kapiteln gelesen haben, kann sich hier wiederholen.
      

    
  \par
    
Die Situationen sind entsprechend der Häufigkeit ihres Auftretens
angeordnet, die häufigsten dabei zuerst.
      


    
  \par
    
{\bf Ich bekomme dauernd die Meldung 'Waiting for Locks'. Was soll das?}
      

    
  \par
    
Wenn Sie eine Meldung wie
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} cvs update: [22:58:26] waiting for qsmith's lock in /usr/local/newrepos/myproj\end{scriptsize} \end{tt} \linebreak
       

    
  \par
    
erhalten, dann bedeutet das, dass Sie versuchen, auf ein
Unterverzeichnis im Archiv zuzugreifen, das momentan von irgendeinem
anderen CVS-Prozess belegt wird. Da ein Prozeß in diesem Verzeichnis
abläuft, befindet es sich möglicherweise nicht in einem Zustand, der
es erlaubt, dass andere CVS-Prozesse darauf zugreifen.
      

    
  \par
    
Wenn allerdings diese Wartemeldung lange Zeit bestehen bleibt, dann
heißt das, dass ein CVS-Prozess - aus welchem Grund auch immer - dabei
gescheitert ist, textblocker sich aufzuräumen. So etwas kann auftreten,
wenn CVS plötzlich und unerwartet stirbt, beispielsweise durch
Stromausfall bei dem Rechner, der das Archiv beherbergt.
      

    
  \par
    
Die Lösung liegt darin, die Lock-Dateien von Hand aus dem fraglichen
Verzeichnis im Archiv zu entfernen. Wechseln Sie in das entsprechende
Verzeichnis im Archiv, und suchen Sie nach Dateien namens {\bf \#cvs.lock}
oder solchen, die mit {\bf \#cvs.wfl} oder {\bf \#cvs.rfl} beginnen. Vergleichen
Sie die Zeitstempel der Dateien mit den Startzeiten aller gerade
laufenden CVS-Prozesse. Wenn ausgeschlossen ist, dass die Dateien von
einem noch laufenden Prozess angelegt worden sind, dann ist es
ungefährlich, sie zu löschen. Der wartende CVS-Prozess wird
irgendwann merken, dass die {\bf Lock}-Dateien verschwunden sind - das
sollte ungefähr 30 Sekunden dauern -, und wird dann der angeforderten
Operation gestatten, fortzufahren.
      

    
  \par
    
Wenn Sie an mehr Details interessiert sind, dann lesen Sie unter
{\bf Locks} im Cederqvist nach.
      


    
  \par
    
{\bf CVS behauptet, dass bei einer Datei der »Up-to-Date Check« fehlschlägt.}
      

    
  \par
    
{\bf Was mache ich bloß?}
      

    
  \par
    
Keine Panik - das bedeutet einfach, dass sich die Datei, seit Sie sie
das letzte Mal ausgecheckt oder ein Update gemacht haben, geändert
hat.
      

    
  \par
    
Starten Sie {\bf cvs update} auf der Datei, um die Änderungen aus dem Archiv
einzuarbeiten. Wenn die Änderungen mit Ihren lokalen Änderungen
kollidieren, dann editieren Sie die Datei, um den Konflikt zu
beheben. Versuchen Sie danach erneut den {\bf commit} - er wird nicht
fehlschlagen -, wenn man einmal die Möglichkeit ausschließt, dass
jemand eine weitere Revision per {\bf Commit} veröffentlicht hat, während
Sie damit beschäftigt waren, die letzten Änderungen einzuarbeiten.
      


    
  \par
    
{\bf Ich schaffe es nicht, die pserver-Zugangsmethode ans Laufen zu kriegen.}
      

    
  \par
    
Der häufigste, aber am wenigsten offensichtliche Grund für dieses
Problem ist, dass Sie vergessen haben, das Archiv mit der Option
{\bf --allow-root} in Ihrer {\bf inetd}-Konfigurationsdatei aufzulisten.
      

    
  \par
    
Erinnern Sie sich an die Beispiel-{\bf /etc/inetd.conf}-Datei aus Kapitel 4:
      

    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
/etc/inetd.conf
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
       
cvspserver stream tcp nowait root /usr/local/bin/cvs cvs \
--allow-root=/usr/local/newrepos pserver
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}

    
  \par
    
(In der eigentlichen Datei ist das eine einzige lange Zeile, ohne den
Backslash.)
      

    
  \par
    
Der Teil {\bf --allow-root=/usr/local/newrepos} ist eine
Sicherheitsmaßnahme, die dafür sorgt, dass niemand CVS dazu
missbraucht, um {\bf pserver}-Zugang zu Archiven zu erhalten, auf die nur
lokal zugegriffen werden soll. Jedes Archiv, auf das pserver-Zugriff
möglich sein soll, benötigt einen {\bf --allow-root}-Eintrag. Sie können so
viele {\bf --allow-root}-Optionen, wie Sie für alle Archive im System
benötigen, haben (oder so viele, wie Sie wollen, solange Sie nicht an
die Längenbeschränkung der Argumente für inetd stoßen).
      

    
  \par
    
Lesen Sie in Kapitel 4 nach, wenn Sie genauere Informationen zur
Einrichtung eines Passwort authentisierten Servers wünschen.
      


    
  \par
    
{\bf Die pserver-Zugriffsmethode funktioniert IMMER noch nicht!}
      

    
  \par
    
O.K., wenn es nicht an einem fehlenden {\bf --allow-root} liegt, gibt es
noch andere Möglichkeiten:
      

    
  \par
    
Der Benutzer hat keinen Eintrag in der Datei {\bf CVSROOT/passwd}, und die
Datei {\bf CVSROOT/config} enthält {\bf SystemAuth=no}, sodass CVS nicht auf die
System-{\bf passwd}-Datei zurückfällt (oder sie enthält {\bf SystemAuth=yes},
aber die System-{\bf passwd}-Datei enthält auch keinen Eintrag für diesen
Benutzer).
      

    
  \par
    
Der Benutzer hat zwar einen Eintrag in {\bf CVSROOT/passwd}, aber es gibt
keinen entsprechenden Benutzer im System, und {\bf CVSROOT/passwd} bildet
den Benutzer nicht auf einen im System gültigen Benutzernamen ab.
      

    
  \par
    
Das Passwort ist falsch. (CVS ist aber gut darin, den Benutzer darauf
hinzuweisen, also ist das wahrscheinlich nicht die richtige Antwort.)
      

    
  \par
    
Die Passwortdateien und {\bf /etc/inetd.conf} sind richtig eingerichtet,
aber Sie haben einen Eintrag wie diesen in {\bf /etc/services} vergessen:
      

    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
etc/services
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
       
cvspserver 2401/tcp
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}

    
  \par
    
und so lauscht {\bf inetd} gar nicht auf dem Port und kann die Verbindung
auch nicht an CVS weiter reichen.
      


    
  \par
    
{\bf Meine Commits geschehen stückweise, nicht atomar.}
      

    
  \par
    
Das liegt daran, dass CVS-{\bf Commits} stückweise geschehen und nicht atomar. :-)
      

    
  \par
    
Genauer gesagt laufen sie verzeichnisweise ab. Wenn Sie einen {\bf commit} 
(oder ein {\bf update} oder irgendetwas anderes) ausführen, der mehrere
Verzeichnisse betrifft, dann wird CVS jedes korrespondierende
Verzeichnis im Archiv nacheinander sperren, während es die Operation
darin durchführt.
      

    
  \par
    
Bei kleinen bis mittleren Projekten ist das selten ein Problem - CVS
erledigt seine Aufgaben in jedem Verzeichnis so schnell, dass es gar
nicht auffällt, dass es nicht atomar geschieht. Bei großen Projekten
kann es aber leider zu Szenarios wie folgendem kommen. (Stellen Sie
sich vor, dass das bei einem Projekt geschieht, das mindestens zwei
Unterverzeichnisse (A und B) enthält, die beide viele Dateien
enthalten.):
      

    
  \par
    
Der Benutzer qsmith startet einen {\bf commit}, der Dateien aus beiden
Unterverzeichnissen betrifft. CVS führt den {\bf Commit} zuerst mit den
Dateien in Verzeichnis B aus (möglicherweise weil qsmith die
Verzeichnisse in seiner Kommandozeile in dieser Reihenfolge angegeben
hat).
      

    
  \par
    
Die Benutzerin jrandom startet {\bf cvs update}. Aus welchem Grund auch
immer startet der {\bf Update}-Prozess in dem Verzeichnis A in der
Arbeitskopie. (CVS gibt keine Garantien, in welcher Reihenfolge es
Verzeichnisse oder Dateien bearbeitet, wenn man es nicht dazu zwingt.)
Beachten Sie, dass es keinen Konflikt mit den Sperren gibt, da ja
qsmith in Verzeichnis A noch gar nicht aktiv ist.
      

    
  \par
    
Der {\bf commit} von qsmith wird mit B fertig und macht bei A weiter und
wird auch dort fertig.
      

    
  \par
    
Zum Schluss wechselt der {\bf update}-Prozess von qsmith zu Verzeichnis B
und wird auch dort fertig.
      

    
  \par
    
Es ist klar, dass, wenn alles vorüber ist, die Arbeitskopie von
jrandom die Änderungen von qsmith an Verzeichnis B enthält, nicht
jedoch die in Verzeichnis A. Obwohl qsmith vorhatte, dass die
Änderungen als Einheit vorgenommen werden, ist es nicht so gekommen.
Jetzt ist die Arbeitskopie von jrandom in einem Zustand, den qsmith
nie vorhergesehen hätte.
      

    
  \par
    
Die Lösung ist natürlich, dass jrandom einen weiteren cvs {\bf update}-Lauf
durchführt, der die noch unberücksichtigten Änderungen aus dem {\bf Commit}
von qsmith nachholt. Das setzt natürlich voraus, dass jrandom
überhaupt die Möglichkeit hat, herauszufinden, dass sie nur einen Teil
von qsmiths Änderungen mitbekommen hat.
      

    
  \par
    
Es gibt für dieses Dilemma keine einfache Lösung. Sie müssen einfach
hoffen, dass der inkonsistente Zustand der Arbeitskopie irgendwie
auffällt. (Vielleicht lässt sich die Software nicht übersetzen, oder
jrandom und qsmith haben eine für beide verwirrende Unterhaltung, bis
ihnen auffällt, was passiert sein muss.)
      

    
  \par
    
Dass CVS keine {\bf atomaren} Transaktionen bereitstellt, wird allgemein
als Manko gesehen. Der alleinige Grund dafür, dass keine
Sperrmechanismen im Hauptverzeichnis des Archivs eingeführt werden,
ist der, dass sich dann bei großen Projekten mit vielen Benutzern
häufig Verklemmungen dieser Sperren ergeben würden. CVS hat also das
kleinere Übel gewählt, das die Häufigkeit dieser Verklemmungen
verringert, aber eben diese versetzten Lese- und Schreiboperationen
zulässt. Eines Tages wird jemand CVS anpassen (also die Operationen
des Archivs beschleunigen), sodass man nicht mehr zwischen zwei Übeln
wählen muss; bis dahin müssen wir uns mit den nicht atomaren
Vorgängen abfinden.
      

    
  \par
    
Für weitere Informationen empfehle ich die Sektion {\bf Concurrency} im Cederqvist.
      


    
  \par
    
{\bf Warum verändert CVS dauernd die Zugriffsrechte meiner Dateien?}
      

    
  \par
    
CVS ist allgemein nicht gut darin, die Zugriffsrechte von Dateien zu
bewahren. Wenn man ein Projekt importiert und dann auscheckt, gibt es
keine Garantie, dass die Zugriffsrechte der Dateien in der neuen
Arbeitskopie dieselben sind wie beim Importieren des Projekts.
Wahrscheinlicher ist, dass die Dateien der Arbeitskopie mit denselben
Standardzugriffsrechten erzeugt werden, mit denen neue Dateien
normalerweise angelegt werden.
      

    
  \par
    
Es gibt aber mindestens eine Ausnahme. Wenn Sie ausführbare
Shell-Skripten im Projekt speichern wollen, können Sie sie in jeder
Arbeitskopie ausführbar machen, indem Sie die korrespondierende Datei
im Archiv ausführbar machen:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
ls -l /usr/local/newrepos/someproj
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} total 6\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} -r--r--r-- 1 jrandom users 630 Aug 17 01:10 README.txt,v\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} -r-xr-xr-x 1 jrandom users 1041 Aug 17 01:10 scrub.pl,v*\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} -r--r--r-- 1 jrandom users 750 Aug 17 01:10 hello.c,v\end{scriptsize} \end{tt} \linebreak
    

    
  \par
    
Beachten Sie, dass, obwohl die Datei ausführbar ist, sie immer noch
read-only ist, wie es alle Dateien im Archiv sein sollten. (Wie schon
gesagt macht CVS erst eine temporäre Kopie der {\bf RCS}-Datei, führt alle
Operationen auf der Kopie durch und ersetzt, wenn es fertig ist, das
Original mit der Kopie.)
      

    
  \par
    
Wenn Sie eine ausführbare Datei importieren oder hinzufügen, dann
erhält CVS die {\bf Executable Flags} (diese machen sie ausführbar); wenn
also die Rechte von Anfang an richtig gesetzt waren, haben Sie nichts
zu befürchten. Wenn Sie allerdings aus Versehen die Datei hinzufügen,
bevor Sie sie ausführbar gemacht haben, dann müssen Sie manuell die
{\bf RCS}-Datei im Archiv ausführbar machen.
      


    
  \par
    
Bemerkung
      

    
Die Zugriffsrechte im Archiv behalten immer die Oberhand. Wenn also
eine Datei im Archiv nicht ausführbar ist, in der Arbeitskopie aber
schon, dann wird die Datei in der Arbeitskopie nach einem {\bf Update}
nicht mehr ausführbar sein. Die Tatsache, dass sich die Zugriffsrechte
der Dateien still und heimlich ändern können, kann ziemlich
frustrierend sein. Wenn das geschieht, sollten Sie als Erstes das
Archiv überprüfen, um zu sehen, ob Sie das Problem lösen können,
indem Sie dort die Zugriffsrechte der entsprechenden {\bf RCS}-Dateien
setzen.
    

    
  \par
    
Ein Feature namens {\bf PreservePermissions} wurde CVS hinzugefügt, dass
manche dieser Probleme erträglicher machen könnte. Durch dessen
Nutzung können aber andere unerwartete Ereignisse auftreten (weshalb
ich es hier nicht uneingeschränkt empfehle). Machen Sie sich mit den
Punkten {\bf config} und {\bf Special Files} im Cederqvist vertraut, bevor
Sie {\bf PreservePermissions=yes} in {\bf CVSROOT/config} hinein schreiben.
      


    
  \par
    
{\bf CVS kann unter Windows meine .cvspass-Datei nicht finden. Warum?}
      

    
  \par
    
Für {\bf pserver}-Verbindungen sucht CVS auf der Client-Seite in Ihrem
Home-Verzeichnis nach der Datei {\bf .cvspass}. Windows-Maschinen kennen
aber kein natürliches Home-Verzeichnis, weswegen CVS in der
Umgebungsvariablen {\bf %HOME%} nachschaut. Man muss aber bei der
Einrichtung von HOME sehr vorsichtig sein. Folgendes funktioniert:
      

    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
Datei .cvspass
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
       
set HOME=C:
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}
  
    
  \par
    
Das aber nicht:
      

    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
Datei .cvspass
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
       
set HOME=C:\
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}

    
  \par
    
Der abschließende Backslash reicht aus, um CVS zu verwirren; es wird
{\bf C:$\backslash$.cvspass} nicht öffnen können.
      

    
  \par
    
Die schnelle und dauerhafte Lösung ist also
      

    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
Datei .cvspass
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
       
set HOME=C:
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}

    
  \par
    
in Ihre {\bf autoexec.bat} zu schreiben und Windows neu zu starten. Danach
sollte CVS-{\bf pserver} richtig funktionieren.
      


    
  \par
    
{\bf Meine Arbeitskopie ist auf verschiedene Zweige verteilt. Hilfe!}
      

    
  \par
    
Sie haben festgestellt, dass verschiedene Unterverzeichnisse Ihrer
Arbeitskopie irgendwie in verschiedenen Zweigen gelandet sind? Das
liegt vermutlich daran, dass Sie {\bf Updates} mit der Option {\bf -r}
durchgeführt haben, jedoch nicht vom Hauptverzeichnis Ihrer
Arbeitskopie aus.
      

    
  \par
    
Kein Problem. Wenn Sie zur Hauptentwicklungslinie zurückkehren wollen,
führen Sie einfach
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs update -r HEAD
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
oder
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs update -A
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
aus dem Hauptverzeichnis aus. Wenn Sie hingegen Ihre ganze
Arbeitskopie auf eine bestimmte Entwicklungslinie setzen wollen,
führen Sie Folgendes aus:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs update -r Name\_des\_Zweiges
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
Es ist an sich nichts Falsches daran, ein oder zwei Unterverzeichnisse
Ihrer Arbeitskopie auf einem anderen Zweig zu haben als den Rest, wenn
Sie beispielsweise einige kurze Arbeiten in diesem Zweig und nur in
diesen bestimmten Verzeichnissen durchführen wollen. Es ist aber
generell eine gute Idee zurückzukehren, sobald Sie fertig sind - das
Leben ist viel weniger verwirrend, wenn Ihre ganze Arbeitskopie
derselben Entwicklungslinie folgt.
      


    
  \par
    
{\bf Wenn ich export -D durchführe, scheint es manchmal die neusten
Änderungen zu missachten!}
      

    
  \par
    
Das liegt an den unterschiedlich laufenden Uhren auf der lokalen
Maschine und im Archiv. Sie können das Problem lösen, indem Sie eine
oder beide Uhren neu stellen oder indem Sie ein anderes Datum als
Argument zu {\bf -D} angeben. Es ist durchaus akzeptabel, ein in der Zukunft
liegendes Datum (wie zum Beispiel {\bf -D tomorrow}) anzugeben, wenn das
nötig ist, um den Zeitunterschied zu kompensieren.
      


    
  \par
    
{\bf Ich kann export -r nicht ausführen wegen irgendwelcher 'val-tags'. Was soll das?}
      

    
  \par
    
Siehe nächste Frage.
      


    
  \par
    
{\bf Tag-Operationen schlagen wegen irgendwelcher 'val-tags' fehl. Was soll das?}
      

    
  \par
    
Wenn Sie einen ähnlichen Fehler wie diesen
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} cvs [export aborted]: cannot write /usr/local/myproj/CVSROOT/val-tags: $\backslash$\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} Operation not permitted\end{scriptsize} \end{tt} \linebreak
    

    
  \par
    
erhalten, dann bedeutet das, dass der Benutzer, unter dem CVS läuft,
nicht die Berechtigung hat, in die Datei {\bf CVSROOT/val-tags} zu
schreiben. In dieser Datei werden gültige Namen von Marken
gespeichert, damit CVS schnell feststellen kann, welche Marken gültig
sind. Leider verändert CVS diese Datei selbst für Operationen, die
auf das Archiv bezogen eigentlich nur lesend sind, wie beispielsweise
das Auschecken eines Projektes.
      

    
  \par
    
Dieser Fehler in CVS könnte zurzeit, da Sie dies lesen, schon behoben
sein. Bis es so weit ist, liegt die Lösung entweder darin, die Datei
{\bf val-tags world-writeable} zu machen oder, wenn das nicht hilft, sie zu
löschen oder ihren Eigentümer auf den abzuändern, der CVS laufen
lässt. (Man sollte denken, dass das Ändern der Zugriffsrechte genügen
sollte, ich habe aber schon mehrere Situationen erlebt, bei denen ich
auch den Eigentümer ändern musste.)
      


    
  \par
    
{\bf Ich habe Probleme mit bindenden Marken, ich möchte sie loswerden.}
      

    
  \par
    
Verschiedene CVS-Operationen ziehen mit sich, dass die Arbeitskopie
eine bindenden Marke, ein so genanntes {\bf Sticky Tag}, erhält, also eine
einzige Marke, der jeder Revision jeder Datei zugeordnet ist. (Im
Falle einer verzweigten Version wird die bindende Marke auf jede
Datei, die der Arbeitskopie hinzugefügt wird, angewendet.) Ihre
Arbeitskopie erhält jedes Mal eine bindende Marke, wenn sie abhängig
von einer Marke oder von einem Datum auschecken oder ein {\bf Update}
durchführen.
      

    
  \par
    
Zum Beispiel:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs update -r Name\_der\_Marke
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
oder
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs checkout -D ''1999-08-16''
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
Wenn ein Datum oder der Name einer normalen Marke (nicht die eines
Zweiges) verwendet wird, dann wird die Arbeitskopie zu einem
{\bf eingefrorenen} Abbild dieses Augenblicks in der Geschichte des
Projektes - so werden Sie natürlich nicht in der Lage sein,
irgendwelche Änderungen daraus per {\bf Commit} im Archiv abzulegen.
      

    
  \par
    
Um die bindende Marke zu entfernen, lassen Sie {\bf update} mit der Option {\bf -A} laufen
      
 
    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs update -A
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
wodurch die bindende Marke aufgelöst wird und jede Datei auf den
neusten Stand der Hauptentwicklungslinie gebracht wird.
      

    
  \par
    
{\bf CVS Checkout/Update schlägt mit einer Fehlermeldung fehl, die 'cannot
expand modules' lautet.}
      

    
  \par
    
Das ist ein Fall einer falschen Fehlermeldung in CVS; wahrscheinlich
wird früher oder später jemand sie korrigieren, in der Zwischenzeit
kann sie Sie aber erwischen.
      

    
  \par
    
Die Fehlermeldung sieht etwa so aus:
      
 
    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs co -d bwf-misc user-space/bwf/writings/misc
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} cvs server: cannot find module 'user-space/bwf/writings/misc' - ignored\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} cvs [checkout aborted]: cannot expand modules\end{scriptsize} \end{tt} \linebreak
    

    
  \par
    
CVS scheint zu sagen, dass etwas mit der Datei {\bf CVSROOT/modules} nicht
stimmt. In Wahrheit handelt es sich aber um ein Problem mit den
Zugriffsrechten im Archiv. Entweder ist das Verzeichnis, das ich
auschecken möchte, nicht lesbar, oder eines seiner übergeordneten
Verzeichnisse ist nicht lesbar. In diesem Fall war eines der
übergeordneten Verzeichnisse schuld:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
ls -ld /usr/local/cvs/user-space/bwf
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} drwx------ 19 bwf users 1024 Aug 17 01:24 bwf/\end{scriptsize} \end{tt} \linebreak
    

    
  \par
    
Lassen Sie sich nicht von dieser offensichtlich falschen Fehlermeldung
täuschen - es ist ein Problem mit den Zugriffsrechten im Archiv.
      


    
  \par
    
{\bf Irgendwie kann ich die Watches nicht abschalten!}
      

    
  \par
    
Sie haben wahrscheinlich
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs watch remove
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
für alle Dateien aufgerufen, aber vergessen, ebenfalls
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs watch off
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
aufzurufen. Ein kleiner Hinweis, wie man Probleme mit {\bf Watches}
(Beobachtungslisten) diagnostiziert: Manchmal ist es immens erhellend,
wenn man einfach in das Archiv geht und die {\bf CVS/fileattr}-Dateien
direkt untersucht. Siehe Kapitel 4 für weitere Informationen darüber.
      


    
  \par
    
{\bf Meine Binärdateien werden verunstaltet.}
      

    
  \par
    
Haben Sie daran gedacht, {\bf -kb} anzugeben, als Sie sie dem Archiv
hinzugefügt haben? Wenn nicht, dann könnte CVS
Zeilenendekonvertierungen oder {\bf RCS}-Schlüsselwortersetzungen
durchgeführt haben. Die einfachste Lösung ist normalerweise, sie als
Binärdatei zu kennzeichnen:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs admin -kb foo.gif
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
und es dann nach Korrektur der Datei dem Archiv per {\bf Commit}
mitzuteilen. CVS wird sie bei dem neuen {\bf Commit} nicht wieder verändern
und bei späteren {\bf Commits} auch nicht, da es ja jetzt weiß, dass es
sich um eine Binärdatei handelt.
      


    
  \par
    
{\bf CVS macht die Zeilenendekonvertierung nicht richtig.}
      

    
  \par
    
Wenn Sie CVS auf einer Nicht-Unix-Plattform laufen haben und bei
manchen Arbeitskopien nicht die gewünschte Zeilenendekennung erhalten,
dann liegt das normalerweise daran, dass die Dateien aus Versehen mit
der Option {\bf -kb} hinzugefügt wurden. Im Archiv wird das, ob man es
glaubt oder nicht, mit dem Kommando
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs admin -kkv DATEI
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
behoben. Die Option {\bf -kkv} besagt, dass normale Schlüsselwortersetzung
durchgeführt werden soll, und impliziert auch die normale
Zeilenendekonvertierung. (CVS ist intern betrachtet ein wenig wirr,
wenn es um die Unterscheidung zwischen Schlüsselwortersetzung und
Zeilenendekonvertierung geht. Das zeigt sich darin, dass man mit den
{\bf -k}-Optionen nicht beide Parameter festlegen kann.)
      

    
  \par
    
Leider behebt das {\bf admin}-Kommando das Problem mit der Datei nur im
Archiv - Ihre Arbeitskopie denkt immer noch, dass es sich um eine
Binärdatei handelt. Sie können zwar die Zeile für diese Datei in
{\bf CVS/Entries} anpassen, sodass sie {\bf -kb} nicht mehr enthält, aber das löst
das Problem nicht in den anderen Arbeitskopien, die es sonst noch
gibt.
      


    
  \par
    
{\bf Ich muss ein Unterverzeichnis aus meinem Projekt löschen. Wie stelle ich das an?}
      

    
  \par
    
Tja, richtig löschen können Sie das Unterverzeichnis nicht, aber Sie
können alle Dateien darin entfernen (indem Sie sie erst löschen, dann
{\bf cvs remove} und {\bf commit} ausführen). Sobald das Verzeichnis leer ist,
kann jeder es automatisch aus seiner Arbeitskopie heraus schneiden,
indem er die Option {\bf -P} beim {\bf update} mit angibt.
      


    
  \par
    
{\bf Kann ich .cvspass-Dateien oder Teile davon kopieren?}
      

    
  \par
    
Ja, das ist möglich. Man kann {\bf .cvspass}-Dateien von Rechner zu Rechner
kopieren, und man kann auch einzelne Zeilen aus einer {\bf .cvspass}-Datei
zur anderen kopieren. Bei Servern mit hoher Latenz kann das schneller
gehen, als sich mittels {\bf cvs login} bei jedem Rechner, der eine
Arbeitskopie beheimatet, anzumelden.
      

    
  \par
    
Denken Sie daran, dass es vermutlich nicht funktionieren wird, wenn
Sie eine {\bf .cvspass}-Datei zwischen zwei Rechnern mit unterschiedlicher
Zeilenendekennung transferieren. (Natürlich können Sie die
Konvertierung wahrscheinlich ohne große Mühe manuell durchführen.)
      


    
  \par
    
{\bf Ich habe gerade einige Dateien mit der falschen Log-Nachricht committed.}
      

    
  \par
    
Sie müssen nichts im Archiv von Hand editieren, um das zu korrigieren.
Lassen Sie einfach {\bf admin} mit der Option {\bf -m} laufen. Bedenken Sie, dass
Sie kein Leerzeichen zwischen die Option {\bf -m} und ihr Argument setzen
dürfen und dass Sie die Ersatzlog-Nachricht genau wie jede normale mit
Anführungszeichen kapseln müssen:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs admin -m1.17:''I take back what I said about the customer.'' hello.c
      \end{scriptsize} \end{tt} \linebreak 
    


    
  \par
    
{\bf Ich möchte Dateien verschieben, ohne die Revisionshistorie zu verlieren.}
      

    
  \par
    
Kopieren Sie (nicht verschieben) die {\bf RCS}-Dateien an den gewünschten
neuen Platz im Projekt. Sie müssen zusätzlich an der alten Stelle
verbleiben.
      

    
  \par
    
Führen Sie dann aus einer Arbeitskopie Folgendes aus:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
rm alte\_Datei\_1 alte\_Datei\_2 ...
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs remove alte\_Datei\_1 alte\_Datei\_2 ...
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
cvs commit -m ''removed from here'' alte\_Datei\_1 alte\_Datei\_2 ...
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
Wenn jetzt jemand ein {\bf Update} durchführt, dann wird CVS die alten
Dateien richtigerweise entfernen und die neuen Dateien in die
Arbeitskopie hineinbringen, so als ob sie ganz normal dem Archiv
hinzugefügt worden wären (abgesehen davon, dass Sie für angeblich neue
Dateien ungewöhnlich hohe Revisionsnummern haben).
      


    
  \par
    
{\bf Wie bekomme ich eine Liste aller Marken in einem Projekt?}
      

    
  \par
    
Dafür gibt es in CVS momentan keine bequeme Möglichkeit. Alle Benutzer
bekommen diesen Mangel schmerzlich zu spüren, und ich glaube, dass
daran gearbeitet wird, diese Funktion verfügbar zu machen. Wenn Sie
dies lesen, gibt es vielleicht schon ein Kommando {\bf cvs tags} oder so
ähnlich.
      

    
  \par
    
Bis es soweit ist, können Sie die Liste auch über Umwege erhalten.
Führen Sie {\bf cvs log -h} aus, und lesen Sie den Teil der Ausgabe, welcher
der Kopfzeile symbolic names: folgt. Oder, falls Sie sich auf dem
Rechner, auf dem das Archiv liegt, befinden, können Sie sich einfach
den Anfang einiger der {\bf RCS}-Dateien direkt im Archiv ansehen. Alle
Marken (solche, die sich auf Entwicklungszweige beziehen, wie auch
solche, die das nicht tun) sind im Feld symbols aufgeführt:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
head /usr/local/newrepos/hello.c,v
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} head 2.0;\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} access;\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} symbols\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} Release\_1\_0:1.22\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} Exotic\_Greetings-2:1.21\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} merged-Exotic\_Greetings-1:1.21\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} Exotic\_Greetings-1:1.21\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} merged-Exotic\_Greetings:1.21\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} Exotic\_Greetings-branch:1.21.0.2\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} Root-of-Exotic\_Greetings:1.21\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} start:1.1.1.1\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} jrandom:1.1.1;\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} locks; strict;\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} comment @ * @;\end{scriptsize} \end{tt} \linebreak
    


    
  \par
    
{\bf Wie bekomme ich eine Liste aller Projekte im Archiv?}
      

    
  \par
    
Wie auch das Auflisten aller Marken, so ist diese Funktion in der
aktuellen Version von CVS nicht implementiert, aber es ist sehr
wahrscheinlich, dass es bald implementiert wird. Ich glaube, dass das
Kommando {\bf cvs list} oder kurz {\bf cvs ls} genannt werden wird und dass es
sowohl die Datei modules parsen wird, als auch die Unterverzeichnisse
im Archiv auflisten wird.
      

    
  \par
    
In der Zwischenzeit fahren Sie wahrscheinlich am besten damit, sich
die Datei {\bf CVSROOT/modules} (entweder direkt oder mit {\bf checkout -c})
anzusehen. Wenn allerdings noch niemand ein Modul für ein bestimmtes
Projekt angelegt hat, wird es da auch nicht aufgeführt werden.
      

    
  \par
    
{\bf Manche Kommandos schlagen fehl, wenn sie remote ausgeführt werden,
nicht aber lokal. Wie kann ich das Problem eingrenzen und beheben?}
      

    
  \par
    
Es gibt hin und wieder Probleme mit der Kommunikation zwischen Client
und Server. Wenn das der Fall ist, so handelt es sich um einen Fehler
in CVS, aber wie soll man so etwas aufspüren?
      

    
  \par
    
CVS ermöglicht es, das Protokoll zwischen Client und Server
mitzulesen. Bevor Sie das Kommando auf dem lokalen Rechner (mit der
Arbeitskopie) ausführen, setzen Sie die Umgebungsvariable
{\bf CVS\_CLIENT\_LOG}. Die Bourne-Shell-Syntax dafür lautet so:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
CVS\_CLIENT\_LOG=clog; export CVS\_CLIENT\_LOG
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
Sobald diese Variable gesetzt wurde, zeichnet CVS die gesamte
Kommunikation zwischen Client und Server in zwei Dateien auf, deren
Namen auf dem Namen in der Variablen basieren:
      

    
     \begin{tt} \begin{scriptsize} user@linux \~{}/ \$ 
ls
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} CVS/ README.txt a-subdir/ b-subdir/ foo.gif hello.c\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} cvs update\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} ? clog.in\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} ? clog.out\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} cvs server: Updating .\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} cvs server: Updating a-subdir\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} cvs server: Updating a-subdir/subsubdir\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} cvs server: Updating b-subdir\end{scriptsize} \end{tt} \linebreak
     \begin{tt} \begin{scriptsize}  \linebreak user@linux \~{}/ \$ 
ls
      \end{scriptsize} \end{tt} \linebreak 
     \begin{tt} \begin{scriptsize} CVS/ a-subdir/ clog.in foo.gif\end{scriptsize} \end{tt} \linebreak
     \linebreak\begin{tt} \begin{scriptsize} README.txt b-subdir/ clog.out hello.c\end{scriptsize} \end{tt} \linebreak
     \begin{tt} \begin{scriptsize}  \linebreak user@linux \~{}/ \$ 
      \end{scriptsize} \end{tt} \linebreak 
    

    
  \par
    
Die Datei {\bf clog.in} enthält alles, was der Client zum Server geschickt
hat, und {\bf clog.out} enthält all das, was der Server zurück zum Client
gesendet hat. Hier der Inhalt von {\bf clog.out}, damit Sie eine
Vorstellung von dem Protokoll erhalten:
      


    \begin{tabular}{|l|}
                  \hline
                  \begin{tt} 
        
clog.out
     \end{tt} \\ 
                  \hline
                  \begin{minipage}{130mm} 
                  \begin{scriptsize} 
                  \begin{verbatim} 
        
     
Valid-requests Root Valid-responses valid-requests Repository \
Directory Max-dotdot Static-directory Sticky Checkin-prog Update-prog
\ Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged
\ Notify Questionable Case Argument Argumentx Global_option
Gzip-stream \ wrapper-sendme-rcsOptions Set expand-modules ci co
update diff log add \ remove update-patches gzip-file-contents status
rdiff tag rtag import \ admin export history release watch-on
watch-off watch-add watch-remove \ watchers editors init annotate noop
ok M ? clog.in M ? clog.out E cvs server: Updating .
E cvs server: Updating a-subdir
E cvs server: Updating a-subdir/subsubdir
E cvs server: Updating b-subdir
ok
     
     \end{verbatim} 
                  \end{scriptsize} 
                  \end{minipage} \\
                  \hline
                  \end{tabular}

    
  \par
    
Die Datei {\bf clog.in} ist sogar noch komplizierter aufgebaut, da
Revisionsnummern und andere dateibezogene Informationen zum Server
geschickt werden müssen.
      

    
  \par
    
Ich habe hier nicht genug Platz, um das Client/Server-Protokoll zu
dokumentieren, aber Sie können, wenn Sie eine vollständige
Beschreibung wünschen, die Info-Seiten namens {\bf cvsclient} lesen, die
bei CVS mitgeliefert werden. Man kann wahrscheinlich eine Menge über
das Protokoll herausfinden, wenn man es einfach roh liest. Wenngleich
Sie wohl kaum anfangen werden, die Client/Server-Kommunikation zu
untersuchen, bevor Sie nicht alle anderen möglichen Ursachen für ein
Problem ausgeschlossen haben, ist es doch ein unschätzbar wertvolles
Hilfsmittel, um herauszufinden, was wirklich zwischen den beiden
vorgeht.
      


    
  \par
    
{\bf Ich konnte mein Problem nicht in diesem Kapitel beschrieben finden.}
      

    
  \par
    
Mailen Sie eine vollständige und genaue Beschreibung Ihres Problems an
info-cvs@gnu.org, das ist die Diskussions-Mailingliste von CVS. Ihre
Mitglieder sind über viele Zeitzonen verteilt, und ich habe
normalerweise innerhalb von ein bis zwei Stunden eine Antwort
erhalten. Treten Sie der Liste bei, indem Sie eine E-Mail an
info-cvs-request@gnu.org schicken, dann können auch Sie dabei helfen,
Fragen zu beantworten.
      


    
  \par
    
{\bf Ich glaube, ich habe einen Fehler in CVS gefunden. Was mache ich?}
      

    
  \par
    
CVS ist weit davon entfernt, perfekt zu sein - wenn Sie die
Dokumentation schon gelesen und auch die Frage auf der Mailingliste
erörtert haben und immer noch glauben, dass Sie einen Fehler vor sich
haben, dann ist das vermutlich auch der Fall.
      

    
  \par
    
Schicken Sie eine so komplette Beschreibung wie möglich an
bug-cvs@gnu.org. (Sie können auch dieser Liste beitreten, verwenden
Sie einfach stattdessen bug-cvs-request.) Stellen Sie sicher, dass
Sie Ihre Versionsnummer von CVS beifügen (sowohl die Client- als auch
die Serverversion, falls von Bedeutung) sowie ein Rezept, wie der
Fehler reproduziert werden kann.
      

    
  \par
    
Wenn Sie einen Patch geschrieben haben, der den Fehler behebt, dann
fügen Sie ihn bei und erwähnen das auch im Betreff der E-Mail. Die
Betreuer werden Ihnen sehr dankbar sein.
      

    
  \par
    
(Weitere Details über diese Vorgänge sind unter BUGS im Cederqvist und
in der Datei {\bf HACKING} in der Quelltextdistribution von CVS umrissen.)
      


    
  \par
    
{\bf Ich habe ein neues Feature für CVS implementiert, wem schicke ich das?}
      

    
  \par
    
Gleiche Vorgehensweise wie bei einem Fehler: Schicken Sie den Patch an
bugs-cvs@gnu.org. Lesen Sie aber zuerst die Datei {\bf HACKING}.
      

    

   \subsection{Die Dinge ändern sich} \label{d77e1639}
        

    

    
  \par
    
Die Techniken der Fehlerbeseitigung und die bekannten Fehler, die in
diesem Kapitel beschrieben worden sind, waren (ungefähr) zu Zeiten von
CVS Version 1.10.7 zutreffend. In der Welt von CVS bewegt sich aber
alles sehr schnell. Als ich die letzten paar Kapitel geschrieben
habe, ist der inoffizielle Mantel der CVS-Betreuung von Cyclic
Software auf SourceGear, Inc. (www.sourcegear.com) übergegangen, denn
diese haben Cyclic aufgekauft. SourceGear hat öffentlich verkündet,
dass sie beabsichtigen, eine aktive Rolle bei der CVS-Betreuung zu
übernehmen, und hat die Zustimmung von Cyclic erhalten, was (mehr oder
weniger) ausreicht, um sie zu den derzeitigen »Hauptbetreuern« von
CVS zu machen. (Die Adresse www.cyclic.com bleibt aber erhalten,
sodass alle URLs, die vorher in diesem Buch angegeben wurden, ihre
Gültigkeit behalten.)
      

    
  \par
    
SourceGear ist momentan damit beschäftigt, die verschiedenen Patches,
die noch herumfliegen, zu bereinigen und zu organisieren, mit der
Absicht, viele davon in CVS zu integrieren. Manche dieser Patches
werden wahrscheinlich Fehler beheben, die ich schon aufgelistet habe,
und manche werden den Anwendern von CVS neue Mittel zur
Fehlerbehebung bieten.
      

    
  \par
  \label{d6e1658}  
Die beste Möglichkeit, um up-to-date mit dem, was da vorgeht, zu
bleiben, ist die Datei NEWS in Ihrer CVS-Distribution zu lesen, die
Mailinglisten zu beobachten und Änderungen im Cederqvist und in der
Online-Version einiger der Kapitel aus diesem Buch zu verfolgen.
      



	\newcounter{d6e1661} 
                  \begin{list}{\arabic{d6e1661}}
                  {\usecounter{d6e1661}}
        
	 
	\item Anm. d. Übers.: Schwarze (geschlossene) Kiste
	 
	\item Anm. d. Übers.: »Nonbranch Sticky Tag«
	 
	\item Anm. d. Übers.: Von jederman beschreibbar
	 
	\item Anm. d. Übers.: Häufig gestellte Fragen
	 
	\item Anm. d. Übers.: User ID
	 
	\item Anm. d. Übers.: Im Deutschen auch Rückstrich genannt: »$\backslash$«.
	 
	\item Anm. d. Übers.: Batch-Dateien, um ein anderes »deutsches«
	 Wort zu bemühen. Stapelverarbeitungsdateien, wenn's denn
	 unbedingt sein muss.
	\end{list} 
   
   
  
	\ref{inhalt.tex}


	\end{document}
	
