WinCVS - Login Einstellungen - Neues Projekt erzeugen - Der Checkout - Update und Diff Dateivergleich - Der erste Commit - Konflikte erkennen und lösen - Log-Nachrichten - Die wichtigsten Befehle
WinCVS Bevor ich hier beschreibe wie WinCVS zu konfigurieren ist Ersteinmahl etwas allgemeinere Informationen zu WinCVS: So besteht WinCVS aus 2 Teilen : - der Shell Konsole - dem Explorer sobald sie eingeloggt sind/oder auch davor können sie alle CVS Kommandos über die Shell ausführen, was wie wir sehen werden manchmal recht hilfreich sein kann aber auch nicht immer nötig sein wird. Denn wir haben ja auch noch den WinCVS Explorer der viele Kommandos erleichtert.... nach der Installation von WinCVS und Python.
Nun bereiten wir WinCVS auf den Login vor: - über Admin -> Preferences gelangen wir zu den Einstellungen oder Strg + F1 Authentication: hier den Servertyp einstellen in unserem Fall pserver Path: hier das Repository eintragen auf das sie zugreifen wollen in unserem fall /praktikum Host address: hier die IP oder Url des Servers eintragen in unserem Fall 192.168.2.99 User name: in unserem fall hwpx oder praktikum Nun mit OK bestätigen und schon kann s losgehen. Über Admin -> login mit dem Server Verbindung aufnehmen wenn dies fehlerfrei klappt erhalten wir auf der Konsole die Ausgabe: Mit der Eingabe cvs ls können wir schon mal prüfen ob wir bereits Projekte im Repository haben Standart mäßig wird uns auch der Ordner CVSROOT angezeigt in dem konfigurationsdateien abgelegt werden. Ein neues Projekt erzeugen: Um die Sourcen eines neuen Projektes auf den CVS Server zu integrieren begeben wir uns mit dem CVS Explorer in den Ordner* der Sourcen und benutzen dann folgenden Befehl: cvs import -m Kommentar zu den Sourcen <projektname> jrandom start die m Option (m = message, Nachricht) spezifiziert eine kurze Nachricht, die den Import beschreibt. Dies wird dann die erste Log-Nachricht des gesamten Projektes; jeder nachfolgende Commit wird ebenfalls eine eigene Log-Nachricht bekommen. Diese Nachrichten sind verpflichtend; wird die m Option nicht angegeben, startet CVS automatisch einen Texteditor, damit sie eine Log-Nachricht eingeben können. Das nächste Argument der Kommandozeile ist der Projektname. Dies ist der Name, anhand dessen ein Checkout des Projektes aus dem Projektarchiv durchgeführt wird. (Was tatsächlich passiert ist, dass ein Verzeichnis mit diesem Namen im Archiv (Repository) angelegt wird).
Wenn dies einwandfrei geklappt hat gibt es wieder eine entsprechende Ausgabe mit code 0 auf der Konsole (*.exe Dateien werden von CVS nicht standardmäßig übernommen). Hier mal ein Beispiel: cvs import -m "mein neues Projekt" meinprojekt jrandom start N meinprojekt/cs8900.c N meinprojekt/cs8900.h N meinprojekt/easyweb.c N meinprojekt/easyweb.h N meinprojekt/funk.c N meinprojekt/funk.h N meinprojekt/http.c N meinprojekt/http.h No conflicts created by this import Wenn sie sich die Ausgabe des Import-Kommandos noch einmal durchlesen, werden Sie feststellen, dass CVS den Dateinamen einen einzelnen Buchstaben vorangestellt hat in diesem Fall N für neue Datei. Die Verwendung eines einzelnen Buchstaben an der linken Position, um den Status einer Datei anzuzeigen, ist bei den Ausgaben eines Kommandos von CVS üblich. Wir werden dies später auch bei Checkout und Update sehen. Sie könnten jetzt denken, dass Sie, nachdem Sie gerade das Projekt importiert haben, in den aktuellen Verzeichnis sofort arbeiten können. Dies ist jedoch nicht der Fall. Das aktuelle Verzeichnis ist immer noch keine CVS-Arbeitkopie. Es war die Quelle für das import- Kommando, richtig, aber es wurde nicht alleine durch die Tatsache, in CVS importiert worden zu sein, auf magische Art und Weise in eine Arbeitskopie verwandelt. Um eine Arbeitskopie zu erhalten, müssen Sie eine aus dem Archiv auschecken. Zuerst sollten Sie vielleicht jedoch den aktuellen Projektstamm sichern. Der Grund dafür ist, dass, wenn die Quelltexte einmal im CVS-Archiv liegen, Sie sich nicht selbst dadurch verwirren sollten, indem Sie Kopien von Dateien modifizieren die nicht der Versionskontrolle unterliegen (und diese Veränderungen daher nicht Teil der Projekthistorie werden). Sie sollten von nun an alle Ihre Arbeiten an einer Arbeitskopie vornehmen. Sie sollten jedoch den gerade importierten Verzeichnisbaum noch nicht entfernen, da Sie noch nicht überprüft haben, ob das Archiv alle Dateien enthält. Wie jeder Programmierer weiß, zahlt Paranoia sich aus, also erstellen sie erst mal eine Sicherungskopie. * Nur wenn der Ordnername nicht für den Compiler relevant ist denn der spätere Ordnername wird sonst vom Projektnamen beim import bestimmt.(mehr dazu bei Checkout)
Der erste Checkout: Suchen sie sich eine geeignet Stelle mit dem WinCVS Explorer für den Checkout. Bei einem Checkout wird ein Ordner mit dem Namen des Projektes (inklusive Sourcen), in dem vom Explorer ausgewählten Ordner erzeugt. Befehl: cvs checkout <projektname> - statt checkout kann man auch kurz co scheiben hier mal das Beispiel: cvs checkout meinprojekt cvs server: Updating meinprojekt U meinprojekt/cs8900.c U meinprojekt/cs8900.h U meinprojekt/easyweb.c U meinprojekt/easyweb.h U meinprojekt/funk.c U meinprojekt/funk.h U meinprojekt/http.c U meinprojekt/http.h
der mit einem Checkout bezogene Ordner sieht dann wie folgt aus: Der neue Ordner kennzeichnet sich durch ein Häkchen was bedeutet das es ein CVS Ordner ist, mit dem Namen des zuvor eingegebenen Projektes, die Namen der Unterordner bleiben aber unberührt. Und auch der Inhalt ist genau derselbe wie der, den Sie gerade importiert haben (bis auf Binär Dateien die hierbei eine Ausnahme bilden). Direkt nach einem Import wird die Revisionsnummer einer jeden Datei des Projektes mit 1.1.1.1 anzeigt. Diese Initiale Revisionsnummer ist eine Art Spezialfall, weshalb wir hier nicht näher darauf eingehen; wir werden uns näher mit Revisionsnummern beschäftigen, wenn ein Commit von ein paar Veränderungen durchgeführt wurde. Lassen sie uns nun die erste Veränderung seit dem Import vornehmen; es wird die Zeile printf ( hallo ihr da ); in die easyweb.c eingefügt. Das war eine recht simple Veränderung, eine, bei der man nicht so schnell vergessen kann, was man getan hat und WinCVS zeigt dies auch sogleich nach dem speichern an, die datei wird rot (nein nicht vor Scham) durch eine Veränderung an der Datei. Bei einem größeren und komplexeren Projekt ist es aber recht wahrscheinlich, dass man eine Datei bearbeitet, von etwas anderem unterbrochen wird und erst einige Tage später wieder dahin zurückkehren und sich nun nicht mehr daran erinnern kann, was man tatsächlich verändert hat. Dies bringt uns zur ersten Situation CVS rettet dein Leben : die eigene Arbeitskopie mit dem Archiv vergleichen.
Was man selbst und was andere getan haben: update und diff Update ist ein recht komplexer Befehl; er vergleicht den Gesamtzustand der Arbeitskopie mit dem Zustand des Projektes im Archiv. Auch wenn nichts im Archiv seit dem letzten Checkout verändert wurde, könnte sich dennoch etwas in der Arbeitskopie verändert haben, und update zeigt dies dann auf: cvs update cvs server: Updating. M easyweb.c Das M neben easyweb.c bedeutet, das die Datei seit dem letzten Checkout modifiziert wurde, so wie auch WinCVS dies anzeigte und noch nicht mit Commit in das Archiv eingebracht wurde. Manchmal ist alles, was man möchte, herausfinden, welche Dateien man bearbeitet hat. Möchte man jedoch einen detaillierteren Blick auf die Veränderungen werfen, kann man einen kompletten Report im diff-format anfordern. Das diff-kommando vergleicht die möglicherweise modifizierten Dateien der Arbeitskopie mit den entsprechenden Gegenstücken im Archiv und zeigt jegliche Unterschiede auf: cvs diff ***** CVS exited normally with code 1 ***** cvs server: Diffing. Index: easyweb.c =================================================================== RCS file: /test/meinprojekt/easyweb.c,v retrieving revision 1.1.1.1 diff -r1.1.1.1 easyweb.c 232c232 < --- > printf("hallo ihr da"); Dies hilft schon weiter, auch wenn es durch eine Menge überflüssiger Ausgaben ein wenig obskur erscheinen mag. Für den Anfang können die meisten der ersten paar Zeilen ignoriert werden. Diese benennen nur die Datei des Archivs und zeigen die Nummer der letzten eingecheckten Revision. Unter bestimmten Umständen kann auch das eine nützliche Information sein, sie wird aber nicht gebraucht, wenn man nur einen Eindruck davon bekommen möchte, welche Veränderungen an der Arbeitskopie stattgefunden haben.
Um die Lesbarkeit zu verbessern benutzen wir diff mit der globalen Option Q (für Quit, leise CVS soll nicht sagen wo es gerade arbeitet, bei mehreren Verzeichnissen recht hilfreich) und c (für context, Kontext so werden ein paar zusätzliche Zeilen mit angezeigt um einen Zusammenhang erkennbarer zu machen): cvs Q diff c cvs -Q diff -c ***** CVS exited normally with code 1 ***** Index: easyweb.c =================================================================== RCS file: /test/meinprojekt/easyweb.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 easyweb.c *** easyweb.c 2 Dez 2003 21:43:01-0000 1.1.1.1 --- easyweb.c 3 Dez 2003 22:23:03-0000 *************** *** 229,234 **** --- 229,235 ---- Key++; + printf("hallo ihr da"); // enables the 8MHz crystal on XT1 and use // it as MCLK Nun, klarer kann es eigentlich nicht mehr werden! Selbst wenn man nicht gewohnt ist, Kontext-Diffs zu lesen macht ein kurzer Blick auf die vorangegangene Ausgabe offensichtlich, was passiert ist: eine neue Zeile wurde zwischen der Zeile, welche enthält und // enables... hinzugefügt (das + in der ersten Spalte der Ausgabe markiert eine hinzugefügte Zeile). Die ersten beiden Zeilen (nach der momentan nutzlosen Einleitung) sind *** easyweb.c 2 Dez 2003 21:43:01-0000 1.1.1.1 --- easyweb.c 3 Dez 2003 22:23:03-0000 und sagen einem, was mit wem gedifft wurde. In diesem fall wurde Revision 1.1.1.1 von easyweb.c mit einer modifizierten Version der gleichen Datei verglichen (daher gibt es keine Revisionsnummer für die zweite Zeile, weil die einzigen Veränderungen, die noch nicht mit einem Commit in das Archiv aufgenommen wurden, die Veränderungen der Arbeitskopie sind). Die Zeilen mit Sternchen und Strichen markieren Teile im späteren Teil des Diffs. Anschließend wird ein Teil der Originaldatei von einer Zeile mit Sternchen und einem eingefügten Zeilennummernbereich eingeleitet. Danach folgt eine Zeile mit Strichen mit möglicherweise anderen Zeilennummernbereichen, die eine Teil der modifizierten Datei einleiten. Kennzeichnungen der Zeilen : + steht für eine neue Zeile! steht für eine veränderte Zeile - steht für eine Zeile die entfernt wurde
cvs -Q diff -c ***** CVS exited normally with code 1 ***** Index: easyweb.c =================================================================== RCS file: /test/meinprojekt/easyweb.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 easyweb.c *** easyweb.c 2 Dez 2003 21:43:01-0000 1.1.1.1 --- easyweb.c 3 Dez 2003 22:23:03-0000 *************** *** 229,235 **** Key++;! // enables the 8MHz crystal on XT1 and use // it as MCLK --- 229,235 ---- Key++;! printf("hallo ihr da"); // enables the 8MHz crystal on XT1 and use // it as MCLK Index: easyweb.c =================================================================== RCS file: /test/meinprojekt/easyweb.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 easyweb.c *** easyweb.c 2 Dez 2003 21:43:01-0000 1.1.1.1 --- easyweb.c 3 Dez 2003 23:07:10-0000 *************** *** 227,235 **** Key++; - - - // enables the 8MHz crystal on XT1 and use // it as MCLK --- 227,232 ---- natürlich funktioniert ein diff auch in der form: cvs diff <dateinamen> (explizit) Das angeben eines Dateinamen geht natürlich auch bei den meisten anderen Befehlen, wird der Dateiname weggelassen wird der Befehl normalerweise auf alle Dateien angewandt.
Untersuchung zweier Dateiversionen: cvs diff c r 1.2 r 1.3 <Dateiname> cvs diff -c -r 1.2 -r 1.3 easyweb.c ***** CVS exited normally with code 1 ***** Index: easyweb.c =================================================================== RCS file: /test/meinprojekt/easyweb.c,v retrieving revision 1.2 retrieving revision 1.3 diff -c -r1.2 -r1.3 *** easyweb.c 3 Nov 2003 23:37:06-0000 1.2 --- easyweb.c 4 Nov 2003 00:17:08-0000 1.3 *************** *** 31,37 **** { InitOsc(); InitPorts();! TCPLowLevelInit(); /* --- 31,37 ---- { InitOsc(); InitPorts();! printf ("hier und jetzt wird es passieren"); TCPLowLevelInit(); /* -r für Revision
Der erste Commit: Den Commit* führt man bei WinCVS am besten mit einem Rechtsklick auf den/die entsprechende/n CVS Datei/Ordner aus. Bei einem Commit sollte man nicht vergessen einen Kommentar mit Informationen über die Änderungen zu hinterlassen. Nach einem Commit sollte auffallen dass die Versionsnummern der veränderten Dateien inkrementiert wurden (wie zu erwarten war), die original Revisionen aber mit 1.1 anstatt 1.1.1.1 wie anfänglich bezeichnet wird, der Grund dafür ist aber nicht weiter wichtig nur soviel in CVS kommt der importierten 1. Version eine gesonderte Rolle zu. cvs commit -m "no message" easyweb.c Checking in easyweb.c; /test/meinprojekt/easyweb.c,v <-- easyweb.c new revision: 1.2; previous revision: 1.1 done Ein weiterer Befehl um Revisions-Informationen zu bekommen ist der status Befehl: cvs status <Dateiname>
cvs status easyweb.c =================================================================== File: easyweb.c Status: Up-to-date Working revision: 1.2 Repository revision: 1.2 /test/meinprojekt/easyweb.c,v Expansion option: kv Commit Identifier: 4c03fa6e6a10000 Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) Merge From: (none) Wie auch bei anderen Befehlen gilt hier ignorieren sie die Teile der Ausgabe die sie nicht Verstehen. Konflikte erkennen und auflösen Einen Konflikt zu erkennen ist einfach. Wird update ausgeführt, gibt CVS/WinCVS diesbezüglich sehr eindeutige Meldungen aus. Doch lassen sie uns zuerst einen Konflikt erzeugen. Dazu bearbeiten wir easyweb.c und fügen folgende Zeile ein: printf ( diese Änderung wird einen Konflikt auslösen ); und zwar an genau der Stelle an der ein anderer Client printf ( hier und jetzt wird es passieren ); einfügte. Zu diesem Zeitpunkt ist der Status unserer Kopie von easyweb.c cvs status easyweb.c =================================================================== File: easyweb.c Status: Needs Merge Working revision: 1.2 Repository revision: 1.3 /test/meinprojekt/easyweb.c,v Expansion option: kv Commit Identifier: 6883fa6f0030000 Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) Merge From: (none) Das bedeutet, dass sowohl die Version der Datei im Archiv als auch die lokale Arbeitskopie verändert wurde und diese Veränderungen zusammengeführt werden müssen (merge). (CVS weiß noch nicht, dass diese Veränderungen einen Konflikt ergeben werden, da noch kein update durchgeführt wurde). Wird das Update durchgeführt, erscheint folgende Ausgabe:
cvs update easyweb.c RCS file: /test/meinprojekt/easyweb.c,v retrieving revision 1.2 retrieving revision 1.3 Merging differences between 1.2 and 1.3 into easyweb.c rcsmerge: warning: conflicts during merge cvs server: conflicts found in easyweb.c C easyweb.c Die letzte Zeile ist das kleine Geschenk von CVS. Das C in der ersten Spalte neben dem Dateinamen bedeutet, dass die Veränderungen zwar zusammengeführt wurden, aber ein Konflikt entstand. Die Datei easyweb.c beinhaltet nun beide Veränderungen: void main(void) { InitOsc(); InitPorts(); <<<<<<< easyweb.c printf ("diese Änderung wird einen Konflikt auslösen"); ======= printf ("hier und jetzt wird es passieren"); >>>>>>> 1.3 TCPLowLevelInit(); Konflikte werden durch Konfliktmarkierungen in folgendem Format angezeigt: <<<<<<<<<<(Dateiname) die noch nicht durch Commit abgeschickten Änderungen der Arbeitskopie bla bla bla ======== die neuen Änderungen aus dem Archiv bla bla bla >>>>>>>>>> (letzte Revisionsnummer des Archivs) Und WinCVS zeigt uns den Conflict / Konflikt in der Form an: Um den Konflikt zu beseitigen, muss die Datei so bearbeiten werden, dass der entsprechende Quelltext erhalten bleibt, die Konfliktmarkierungen entfernt werden und diese erneute Veränderung mittels Commit an das Archiv gesendet wird. Dies bedeutet nicht notwendigerweise, die eine Veränderung gegen die andere abwägen zu müssen; es könnte auch der gesamte Abschnitt (oder gar die gesamte Datei) neu geschrieben werden, weil eventuell beide Veränderungen nicht ausreichend sind. Das kann ihnen CVS leider nicht abnehmen.
Log-Nachrichten lesen Dies geschieht ganz kurz und schmerzlos mit: cvs log <optionaler Dateiname> Vorsicht bitte sie könnten von den Informationen erschlagen werden. cvs log easyweb.c RCS file: /test/meinprojekt/easyweb.c,v Working file: easyweb.c head: 1.3 branch: locks: strict access list: symbolic names: start: 1.1.1.1 jrandom: 1.1.1 keyword substitution: kv total revisions: 4; selected revisions: 4 description: ---------------------------- revision 1.3 date: 2003/11/04 00:17:08; author: Gast; state: Exp; lines: +1-1; kopt: kv; commitid: 6883fa6f0030000; meine neue Zeile ---------------------------- revision 1.2 date: 2003/11/03 23:37:06; author: tester; state: Exp; lines: +0-3; kopt: kv; commitid: 4c03fa6e6a10000; no message ---------------------------- revision 1.1 date: 2003/11/02 21:43:01; author: tester; state: Exp; branches: 1.1.1; Initial revision ---------------------------- revision 1.1.1.1 date: 2003/11/02 21:43:01; author: tester; state: Exp; lines: +0-0; mein neues Projekt =========================================================================== Somit sollte nun das Grundwissen zur Nutzung von CVS und WinCVS vorhanden sein, eventuell werden dem Script noch weiter Kapitel angehängt. *ein Commit ist das übertragen von Veränderungen der Arbeitskopie an den CVS Server
Die wichtigsten Befehle Befehl Beispiel Kurz Bemerkung Import cvs import m Nachricht <Projektname> <Hersteller> <Version> -importieren von neuen Sourcen -bei <Version> wird typischerweise start eingegeben Ls cvs ls -zeigt Dateibaum der Sourcen Diff cvs -Q diff -c -zeigt unterschiede auf Code ebene -erweiterbar um Dateinamen -(-Q) vernachlässig unnütze Angaben bei der Ausgabe -(-c) zeigt die unterschiede weitreichender -Ausgabe: Codezeilen die mit einem (+) gekennzeichnet sind, sind neu,(-) wurden entfernt, (!) wurden verändert cvs diff c r 1.3 1.4 <Datei> -Vergleichen zweier Versionen Checkout cvs checkout <Projektname> co -aktualisieren der Arbeitskopie -erweiterbar um Dateinamen update cvs update up -vergleicht Arbeitskopie mit Server Sourcen -erweiterbar um Dateinamen -option (-q) unterdrückt unwichtig Informationen commit cvs commit m Kommentar der Änderungen ci -senden der eigenen Veränderungen -kann erweitert werden mit Dateinamen add cvs add newfile.c -eine neue Datei zu den Sourcen hinzufügen status cvs status <Datei> -momentaner Datei zustand log cvs log -zeigt Versions- Änderungen -erweiterbar um Dateinamen