old-www/LDP/LG/issue66/sharma.html

692 lines
34 KiB
HTML

<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>CVS: Client-Server Version Control LG #66</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<CENTER>
<A HREF="http://www.linuxgazette.com/">
<H1><IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png"
WIDTH="600" HEIGHT="124" border="0"></H1></A>
<!-- *** BEGIN navbar *** -->
<!-- *** END navbar *** -->
<P>
</CENTER>
<!--endcut ============================================================-->
<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<center>
<H1><font color="maroon">CVS: Client-Server Version Control</font></H1>
<H4>By <a href="mailto:kapil@linux4biz.net">Kapil Sharma</a></H4>
</center>
<P> <HR> <P>
<!-- END header -->
<span style='font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family:
"Times New Roman";color:black;mso-ansi-language:EN-GB;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA'>
<ol start=1 type=1>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#one"><!-- END header -->Overview</a>
</li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#two">Getting CVS</a>
</li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#three">The
repository</a> </li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#four">Multiple
Developers</a> </li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#five">Rolling
back to previous version</a> </li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#six">Some common
CVS commands</a> </li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#seven">Other
tools and add-ons to CVS</a> </li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l0 level1 lfo1;tab-stops:list 36.0pt'><a href="#more">More
information</a> </li>
</ol>
</span>
<h2><a name=one></a>Overview</h2>
<p>CVS is a version control system. Using it, you can record the history of
your source files. CVS helps if you are part of a group of people working on
the same project, sharing the same code. Several developers can work on the
same project remotely using CVS's client-server model in which the code exists
on a central server and each programmer get the source on his local machine
from the CVS server (checkout) and save it back on the CVS server (checkin)
after development. Each time a programmer checks in his new code into the CVS
server, the difference is saved as a new version rather than overwriting the previous
version. This allows the server to recreate any previous version upon request,
although by default it distributes the latest version.</p>
<p>This article explains how to use CVS in client-server mode and get the most
out of it.</p>
<h2><a name=two></a>Getting CVS</h2>
<p>You can find CVS in your Linux distribution or get the source from <a
href="http://www.cvshome.org/downloads.html">http://www.cvshome.org/downloads.html</a></p>
<p class=MsoNormal>The home page for CVS is <a href="http://www.cvshome.org">http://www.cvshome.org</a>.
</p>
<h2><a name=three></a>The repository</h2>
<p>The CVS repository stores a complete copy of all the files and directories
which are under version control. Normally, you never access any of the files in
the repository directly. Instead, you use CVS commands to get your own copy of
the files into a working directory, and then work on that copy. When you've
finished a set of changes, you check (or commit) them back into the repository.
The repository then contains the changes which you have made, as well as
recording exactly what you changed, when you changed it, and other such
information. </p>
<p><b>Creating a Repository</b> <br>
To create a repository, run the CVS init command. It will set up an empty
repository in the CVS root specified in the usual way . </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>cvs -d /usr/local/cvsroot init</pre>
<p class=MsoNormal>Here /usr/local/cvsroot will become the repository. </p>
<p><b>CVSROOT environment variable</b> </p>
<p>Set the CVSROOT environment variable in your shell startup script. For
instance, in ~/.bashrc: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ export CVSROOT=:pserver:username@foo.com:/usr/local/cvsroot </pre>
<p><b>Backing up the Repository</b> <br>
There are a few issues to consider when backing up the repository: </p>
<ul type=disc>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l1 level1 lfo2;tab-stops:list 36.0pt'>One should either not use
CVS during the backup, or have the backup program lock CVS while doing the
backup. </li>
<li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;
mso-list:l1 level1 lfo2;tab-stops:list 36.0pt'>To lock CVS, you would
create `#cvs.rfl' lock files in each repository directory. </li>
</ul>
<p><b>Remote Repositories</b> <br>
Your working copy of the sources can be on a different machine than the
repository. Using CVS in this manner is known as client/server operation. </p>
<p>Setting up the server: <br>
Put the following entry in /etc/inted.conf on server: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>2401 stream tcp nowait root /usr/local/bin/cvs cvs -f --allow-root=/usr/cvsroot pserver</pre>
<p>If your inetd wants a symbolic service name instead of a raw port number,
then put this in `/etc/services': </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>cvspserver<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>2401/tcp</pre>
<p class=MsoNormal><br>
and put cvspserver instead of 2401 in `inetd.conf'. <br>
After making you changes, send a HUP signal to inetd. </p>
<p><b>Password authentication for remote repository</b> <br>
For remote password authentication put a file `$CVSROOT/CVSROOT/passwd' . The
file will look like: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>anonymous:</pre><pre>kapil:1sOp854gDF3DY</pre><pre>melissa:tGX1fS8sun6rY:pubcvs</pre>
<p>The password is in Unix encrypted form. The first line in the example will
grant access to any CVS client attempting to authenticate as user anonymous, no
matter what password they use. The second and third lines will grant access to
kapil if he supplies his respective plaintext passwords. </p>
<p>The third will grant access to melissa if she supplies the correct password,
but her CVS operations will actually run on the server side under the system
user pubcvs. </p>
<p><i>Note: CVS can be configured not to check the UNIX real passwd file i.e
/etc/passwd for CVS authentication by setting SystemAuth=no in the CVS `config'
file ($CVSROOT/CVSROOT/config).</i> </p>
<p><b>Using the client with password authentication</b> </p>
<p>You have to login to CVS server for the first time: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre><span style="mso-spacerun: yes">&nbsp; </span>cvs -d :pserver:kapil@foo.com:/usr/local/cvsroot login</pre>
<p>The you can use all the commands of CVS on the remote machine: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre><span style="mso-spacerun: yes">&nbsp; </span>cvs -d :pserver:kapil@foo.com:/usr/local/cvsroot checkout someproj</pre>
<p><b>Read only repository access</b> <br>
It is possible to grant read-only repository access to people using the
password-authenticated server. There are two ways to specify read-only access
for a user: by inclusion, and by exclusion. <br>
&quot;Inclusion&quot; means listing the user in the `$CVSROOT/CVSROOT/readers'
file, which is simply a newline-separated list of users. Here is a sample
`readers' file: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>kapil</pre><pre>yogesh</pre><pre>john</pre>
<p>(Don't forget the newline after the last user.) </p>
<p>&quot;Exclusion&quot; means listing everyone who should have write access.
If the file&nbsp;&nbsp;&nbsp; $CVSROOT/CVSROOT/writers exists, then only those
users listed in it will have write access, and everyone else will have
read-only access. The `writers' file has the same format as the `readers' file.
</p>
<p><b>Setting up the files in repository</b> <br>
If the files you want to install in CVS reside in `someproj', and you want them
to appear in the repository as `$CVSROOT/someproj', you can do this: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cd someproj</pre><pre>$ cvs import -m &quot;Imported sources&quot; someproj vendor </pre><pre><span style="mso-spacerun: yes">&nbsp;&nbsp;</span>rel1-1</pre>
<p class=MsoNormal>Here The string `vendor' is a vendor tag, and `rel1-1' is a
release tag. </p>
<p><b>CVS locks in repository</b> <br>
Any file in the repository with a name starting with `#cvs.rfl.' is a read
lock. Any file in the repository with a name starting with `#cvs.wfl' is a
write lock. The directory `#cvs.lock' serves as a master lock. That means one
must obtain this lock first before creating any of the other locks. </p>
<p>To obtain a read lock, first create the `#cvs.lock' directory. If it fails
because the directory already existed, wait for a while and try again. After
obtaining the `#cvs.lock' lock, create a file whose name is `#cvs.rfl.'
followed by information of your choice (for example, hostname and process
identification number). Then remove the `#cvs.lock' directory to release the
master lock. Then proceed with reading the repository. When you are done,
remove the `#cvs.rfl' file to release the read lock. </p>
<p>To obtain a write lock, first create the `#cvs.lock' directory, as with a
read lock. Then check that there are no files whose names start with
`#cvs.rfl.'. If there are, remove `#cvs.lock', wait for a while, and try again.
If there are no readers, then create a file whose name is `#cvs.wfl' followed
by information of your choice (for example, hostname and process identification
number). Hang on to the `#cvs.lock' lock. Proceed with writing the repository.
When you are done, first remove the `#cvs.wfl' file and then the `#cvs.lock'
directory. </p>
<p><b>Symbolic revisions using tags in CVS<br>
</b>The release number of final software releases are different from revisions
in CVS. The revision numbers might change for several times between two
releases.You can use the linux-questions-only@ssc.command to give a symbolic name to a certain
revision of a file. </p>
<p>Change to the working directory and issue the following command for tagging:
</p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs tag rel1-1 file.c</pre>
<p class=MsoNormal>This command will tag the file &quot;file.c&quot; as release
1.1 </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs tag rel1-1 .</pre>
<p class=MsoNormal>This command will tag all the files under current directory
recursively as revision 1.1</p>
<p>You can use the `-v' flag to the status command to see all tags that a file
has, and which revision numbers they represent by issuing the following
command:</p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs status -v file.c</pre>
<p>Now you can checkout any revision of a module by using the following
command: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs checkout -r rel1-1 module1</pre>
<p class=MsoNormal>here &quot;module1&quot; is the name of the module. The -r
flag with checkout option makes it easy to retrieve the sources that make up
revision 1.1 of the module `module1' at any time in the future.</p>
<h2><a name=four></a>Multiple Developers</h2>
<p><b>File status</b> <br>
The cvs status command gives a status about the states of the files. You can
get a status of the file by: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs status [options] files</pre>
<p><b>Bringing a file up to date</b> <br>
When you want to update or merge a file, use the update command. This brings
into your working copy the changes others have recently committed. Your
modifications to a file are never lost when you use update. If no newer
revision exists, running update has no effect. If you have edited the file, and
a newer revision is available, CVS will merge all changes into your working
copy. </p>
<p><b>Resolving Conflicts</b> </p>
<p>If two people simultaneously make changes to different parts of the same
file, CVS is smart enough to merge the changes itself. But if two people make
changes to the <em>same</em> part of a file, CVS cannot tell what the final
result is supposed to be, so it gives up and wines, &quot;Conflict!&quot;
Conflicts arise when one developer commits a change and a second developer,
without running cvs update to receive the first developer's change, tries to
commit his own incompatible change. Resolving changes can take hours or even
days. In this section, I will explain how to resolve source conflicts. </p>
<p>When you enter the cvs commit command to automatically upload all the files
you have changed or added to a project, the CVS repository server may inform
you that your locally-edited files are not up-to-date with the server or that
you need to manually merge one or more files with newer versions that have
already been uploaded to the repository by some other developer. Here's a
typical warning message that occurred during a CVS commit process: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs commit</pre><pre>cvs commit: Examining .</pre><pre>cvs commit: Up-to-date check failed for `andy.htm' </pre><pre>cvs commit: Up-to-date check failed for `sample.htm' </pre><pre>cvs commit: Up-to-date check failed for `index.htm' </pre><pre>...</pre><pre>cvs [commit aborted]: correct above errors first!</pre>
<p>You can use the cvs update command to update your local project copy with
the latest changes in the cvs repository. To update your entire working copy of
the site, open a command prompt, change to the directory containing the project
you're developing, and issue the command: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs update</pre>
<p class=MsoNormal>This will update and automatically merge every file that has
changed since you last copied over new files from the CVS repository.
Line-by-line updates to individual text files (such as HTML files) can often be
handled automatically. CVS will list for you any files that require your
attention for manual editing and merging. </p>
<p>Automatic merge example: <br>
You are editing some project file called &quot;index.html&quot; locally and
when you try to commit that file to CVS repository then CVS will give you the
following error: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs commit index.html</pre><pre><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>cvs commit: Up-to-date check failed for `index.html' </pre><pre><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;</span>cvs [commit aborted]: correct above errors first!</pre>
<p class=MsoNormal>This happens because there is a newer version of the same
file on the CVS repository. You should use cvs update command to get the latest
version from the CVS repository onto your local machine: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs update index.html</pre><pre>RCS file: /usr/local/cvsroot/index.html,v</pre><pre>retrieving revision 1.4</pre><pre>retrieving revision 1.5</pre><pre>Merging differences between 1.4 and 1.5 into index.html </pre><pre>M index.htm</pre>
<p class=MsoNormal>After the automatic merge process you should check the
merged copy to check if it is working properly. When you are satisfied with the
local copy of &quot;index.html&quot; file then you can commit it to CVS: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs commit index.htm</pre><pre>Checking in index.htm;</pre><pre>/usr/local/cvsroot/index.htm,v &lt;-- index.htm</pre><pre>new revision: 1.6; previous revision: 1.5 </pre><pre>done</pre>
<p>Manual merge example: <br>
In some cases, your recent work on a file might be so different that the CVS
needs your manual intervention in order to integrate everyone's work and put it
back into the site repository. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs commit index.html cvs commit: Up-to-date check failed for</pre><pre><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>`index.html' cvs [commit aborted]: correct above errors first!</pre>
<p>Use the cvs update command to bring your local copy of the site up to date: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs update</pre><pre>cvs update: Updating .</pre><pre>RCS file: /usr/local/cvsroot/index.html,v</pre><pre>retrieving revision 1.5</pre><pre>retrieving revision 1.6</pre><pre>Merging differences between 1.5 and 1.6 into index.htm</pre><pre>rcsmerge: warning: conflicts during merge</pre><pre>cvs update: conflicts found in activity.htm</pre><pre>C index.htm</pre>
<p>This time CVS was unable to merge the files automatically, so it created a
special copy of the conflicting file in place of the original index.html. The
file has marker lines to indicate the beginning and end of conflictiong
region(s); e.g., </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre><span style="mso-spacerun: yes">&nbsp; </span>&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; filename</pre>
<p class=MsoNormal>To resolve the conflict, simply edit the index.html file and
replace the text between the markers and test the result until it works. You
should also delete the markers </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;========&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; </pre>
<p class=MsoNormal>from the file. When you have finished correcting the file
and have tested it, use the cvs commit command to put your latest copy of file
into the repository: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs commit</pre><pre>Checking in index.html;</pre><pre>/usr/local/cvsroot/index.html,v &lt;-- index.html</pre><pre>new revision: 1.7; previous revision: 1.6 </pre><pre>done</pre>
<p><b>Watches (CVS communication)</b> <br>
CVS can function as a communication device as well as a record-keeper.&nbsp; A
&quot;watches&quot; feature provides multiple developers working on the same
project with a way to notify each other about who is working on what files at a
given time. By &quot;setting a watch&quot; on a file/directory , a developer
can have CVS notify her if anyone else starts to work on that file by means of
sending e-mail or some other method. </p>
<p>To use watches you have to edit two files in the repository administrative
area. You have to edit the &quot;$CVSROOT/CVSROOT/notify&quot; file (which
tells CVS how notifications are to be performed) and
&quot;$CVSROOT/CVSROOT/users&quot; file(which supplies external e-mail
addresses). The best way to modify administrative files is to checkout one copy
from the repository ,edit them and then check in to repository . </p>
<p>To specify e-mail notification, first uncomment the following line from
&quot;$CVSROOT/CVSROOT/notify&quot; file: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>ALL mail %s -s &quot;CVS notification&quot;</pre>
<p class=MsoNormal>This command causes notifications to be sent as e-mail with
the subject line &quot;CVS notification&quot;. </p>
<p>Then you have to create/edit the file &quot;$CVSROOT/CVSROOT/users&quot; .
The format of each line in the users file is: CVS_USERNAME:EMAIL_ADDRESS. For
example: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>kapil:kapil@linux4biz.net</pre>
<p>The CVS username at the beginning of the line corresponds to a CVS username
in CVSROOT/password, or the server-side system username of the person running
CVS. Following the colon is an external e-mail address to which CVS should send
watch notifications for that user. </p>
<p><b>E-mail notification with logfile</b> <br>
CVS provides a feature of sending automated e-mail to everyone working on a
project&nbsp; with a log message whenever a commit takes place. The program to
do the mailing - contrib/log.pl in the CVS source distribution - can be
installed anywhere on your system. You can also install it into
&quot;$CVSROOT/CVSROOT&quot;. You should change the following line in log.pl : </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$mailcmd = &quot;| Mail -s 'CVS update: $modulepath'&quot;; </pre>
<p>Once you've setup the log.pl , you can put lines similar to these into your &#8220;loginfo&#8221;
file. The <tt><span style='font-size:10.0pt;font-family:"Arial Unicode MS"'>`loginfo'</span></tt>
file is used to control where <samp><span style='font-family:"Arial Unicode MS"'>`cvs
commit'</span></samp> log information is sent. You can find it in &quot;$CVSROOT/CVSROOT&quot;.</p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>projectteam1 CVSROOT/log.pl %s -f CVSROOT/commitlog -m projectteam1@linux4biz.net</pre><pre>projectteam2&nbsp; CVSROOT/log.pl %s -f CVSROOT/commitlog -m projectteam2@linux4biz.net</pre>
<p>The %s expands to the names of the files being committed; the -f option to
log.pl takes a file name, to which the log message will be appended (so
CVSROOT/commitlog is an ever-growing file of log messages); and the -m flag
takes an e-mail address, to which log.pl will send a message about the commit.
The address is usually a mailing list, but you can specify the -m option as <br>
many times as necessary in one log.pl command line. </p>
<p><b>Some commands related to setting up watches on files</b>: </p>
<p>If you only want to be notified about, say, commits, you can restrict
notifications by adjusting your watch with the -a flag (a for action): </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs watch add -a commit hello.c</pre>
<p>Or if you want to watch edits and commits but don't care about unedits, you
could pass the -a flag twice: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs watch add -a edit -a commit hello.c</pre>
<p>Adding a watch with the -a flag will never cause any of your existing
watches to be removed. If you were watching for all three kinds of actions on
hello.c, running </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs watch add -a commit hello.c</pre>
<p class=MsoNormal>has no effect - you'll still be a watcher for all three
actions. </p>
<p>To remove watches, run: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs watch remove hello.c</pre>
<p class=MsoNormal>which is similar to add in that, by default, it removes your
watches for all three actions. If you pass -a arguments, it removes only the
watches you specify: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs watch remove -a commit hello.c</pre>
<p>To find out who is watching files, run cvs watchers: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$cvs watchers</pre><pre>$cvs watchers hello.c</pre>
<p>To find out who is editing files, run cvs editors: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$cvs editors</pre><pre>$cvs editors hello.c</pre>
<p>Note: It is necessary to run &quot;cvs edit&quot; before editing any file to
be able to watch feature working. To make sure you do, CVS has a feature to
remind the someone to use cvs edit with the help of&nbsp; the watch on command:
</p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cd project</pre><pre>$ cvs watch on hello.c</pre>
<p>By running cvs watch on hello.c, kapil causes future checkouts of project to
create hello.c read-only in the working copy. When someone else tries to work
on it, he'll discover that it's read-only and be reminded to run cvs edit
first. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$cvs edit hello.c</pre>
<h2><a name=five></a>Rolling back to previous version</h2>
<p class=MsoNormal>Sometimes you need to revert back to previous version of
your&nbsp; project.&nbsp; A project under CVS version control can quickly and
conveniently revert to an earlier stage of its life. I will explain some of the
common examples: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs checkout -D '1 year ago' preproject</pre>
<p class=MsoNormal>Here preproject is the name of the project. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs checkout -r1.4 preproject</pre>
<p class=MsoNormal>1.4 is CVS's revision number for that version. <a name=six></a></p>
<h2>Some common CVS commands</h2>
<p><b>Some common terms:<br>
</b>Import:<span style="mso-spacerun: yes">&nbsp; </span>This means taking an
existing directory tree and copying it into the CVS repository, creating a new
CVS project.
<br>
Commit: Apply all your changes to the CVS repository. Each changed file will
be assigned a new CVS version.<br>
Checkout: Get the working copy of files from cvs repository into the local
directory.<br>
Export: export is same as checkout. The only difference is that export does not
copy out the CVS administrative directories, so you cannot run CVS commands
in the resulting tree. On the other hand, this is how you create your "final"
copy for distribution.<br>
Upload: General term for Import or commit.<br>
Download: General term for checkout or export.<br>
Checkin: General term, same as commit.</p>
<p><b>Adding a file to the CVS repository &quot;My_Files&quot;</b> </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs add File3.txt</pre><pre>$ cvs commit</pre>
<p class=MsoNormal>cvs add does not upload the file right away, but registers
it to be uploaded at the next commit. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre>
<p>This invokes your default text editor and prompts you to enter a description
of your changes. Save the file and quit the editor. CVS will then ask you to
continue, and select the option to continue. Now you have uploaded a file to
the CVS repository &quot;My_Files&quot;. </p>
<p><b>Changing a file to the CVS repository &quot;My_Files&quot;</b> </p>
<p>&nbsp;This can be done with cvs commit command. Let us add some content to
the file File2.txt and then commit it to the cvs repository.</p>
<pre>$ ls /var &gt;&gt; File2.txt</pre><pre>$ cvs commit</pre>
<p><b>Removing files</b> <br>
To remove files from a site, you run the cvs remove command on the desired
filenames in your working copy. As a ``safeguard'', cvs remove will not work if
the working copies of your files still exist.<br>
Syntax:<span style="mso-spacerun: yes">&nbsp; </span>$ cvs remove [options]
files<br style='mso-special-character:line-break'>
<![if !supportLineBreakNewLine]><br style='mso-special-character:line-break'>
<![endif]></p>
<pre>$ cvs remove file.html</pre><pre>cvs server: file `file.html' still in working directory</pre><pre>cvs server: 1 file exists; remove it first</pre><pre>$</pre>
<p>To get around this, you may use the -f option with the cvs remove command or
remove the file first and then execute the cvs remove command. </p>
<pre>$ cvs remove -f oldfile.html</pre><pre>cvs server: scheduling `oldfile.html' for removal</pre><pre>cvs server: use 'cvs commit' to remove this file permanently</pre><pre>$ cvs commit</pre><pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>Or</pre><pre>$ rm File3.txt</pre><pre>$ cvs remove File3.txt</pre><pre>$ cvs commit</pre><pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre>
<p class=MsoNormal>This will not delete the actual file from the CVS server
yet; it simply makes a note to tell the server to remove these files the next
time you commit your working copy of the project.<br>
<span style="mso-spacerun: yes">&nbsp;</span></p>
<p><b>Removing directories</b> <br>
The way that you remove a directory is to remove all the files in it. You don't
remove the directory itself: there's no way to do that. Instead you specify the
`-P' option to cvs update or cvs checkout, which will cause CVS to remove empty
directories from working directories. (Note that cvs export always removes
empty directories.) Note that `-P' is implied by the `-r' or `-D' options of
checkout. This way CVS will be able to correctly create the directory or not
depending on whether the particular version <br>
you are checking out contains any files in that directory. </p>
<p><b>Creating the directory structure from number of files in the CVS
repository</b><br>
This cvs import command is used to put several projects in cvs repository. </p>
<pre>$ cd source <br>
here source is the files that you want to put in cvs repository.<br
style='mso-special-character:line-break'>
<![if !supportLineBreakNewLine]><br style='mso-special-character:line-break'>
<![endif]></pre><pre>$ cvs import -m &quot;Test Import&quot; My_Files Revision1 start<br>
The string <samp><span style='font-family:"Arial Unicode MS"'>&#8216;Revision1&#8217;</span></samp> is a <em>vendor tag</em>, and <samp><span
style='font-family:"Arial Unicode MS"'>`start'</span></samp> is a <em>release tag</em>. &#8220;My_Files&#8221; is the name of directory in cvs repository. The &#8211;m option is to put log message.</pre>
<p><b>Get the working copy of files from CVS</b> </p>
<p>Okay, now we want to download these files into a Working directory. <br>
When we checkout a package from cvs, it will create a directory for us. The
parameter &quot;My_Files&quot; that we specified when we uploaded the files
into cvs will be the name of <br>
the directory created for us when cvs downloads the package for us. </p>
<p>Now we need to get the cvs package. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs checkout My_Files</pre>
<p><b>Downloading updates that other people make</b> </p>
<p>If you have downloaded a package from a repository that someone else is
maintaining, if you wish to download all the changes, then execute the
following command, </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs update -dP</pre>
<p>The &quot;d&quot; creates any directories that are or are missing. The
&quot;P&quot; removes any directories that were deleted from the repository. </p>
<p><b>Viewing the difference</b> <br>
You can easily see the difference between two file using cvs. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cd project</pre><pre>$ cvs diff index.html</pre>
<p class=MsoNormal>This command runs diff to compare the version of
`index.html' that you checked out with your working copy.&nbsp; Here
&quot;project&quot; is the name of the local project directory. </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs diff -r 1.20 -r 1.21 hello.c</pre>
<p class=MsoNormal>This command will show the difference between two versions
of same file. </p>
<p><b>The annotate Command</b> <br>
With annotate, you can see who was the last person to touch each line of a
file, and at what revision they touched it. It gives you more information than
the history command: </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$cvs annotate</pre>
<p>View logs </p>
<pre><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></pre><pre>$ cvs log -r 1.21 hello.c</pre>
<p class=MsoNormal>This will show you the logs for hello.c version 1.21 <a
name=seven></a></p>
<h2>Other tools and add-ons to CVS</h2>
<p><b>Henner Zeller's CVSweb&nbsp;</b> <br>
It has a feature of browsing the CVS repository by web browser and even shows
the latest revision and log message for each file. It presents you with a
web-based interface to browse any and all of the sites and projects you manage
by&nbsp; CVS. You can get it from <a
href="http://stud.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi/">http://stud.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi/</a>
</p>
<p><b>Martin Cleaver's CVSweb</b> <br>
&nbsp;It features capabilities for file upload as well as file browsing of CVS
repository. You can get this software from <a
href="http://sourceforge.net/projects/cvswebclient/">http://sourceforge.net/projects/cvswebclient/</a>
</p>
<p><b>LinCVS</b> <br>
A CVS GUI&nbsp;client for Linux. It provides nice features and easy to use. You
can get it from: <a href="http://www.lincvs.org/">http://www.lincvs.org/</a> </p>
<p><b>WinCVS</b> <br>
A CVS GUI&nbsp;client for Windows. It has many good features and I will
recommend this software for Windows clients. You can get it from <a
href="http://www.cvsgui.org/download.html">http://www.cvsgui.org/download.html</a>
<a name=more></a></p>
<h2>More Information</h2>
<p>CVS Manual : <a href="http://www.cvshome.org/docs/manual/index.html">http://www.cvshome.org/docs/manual/cvs.html</a></p>
<p>CVS Mailing lists: <a href="http://www.cvshome.org/communication.html">http://www.cvshome.org/communication.html</a></p>
<p>&nbsp;<o:p></o:p></p>
<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P>
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Kapil Sharma</H4>
Kapil is a Linux/Unix and Internet security consultant. He
has been working on various Linux/Unix systems and Internet Security for over
three years. He maintains a web site (<a href="http://www.linux4biz.net">http://linux4biz.net</a>)
for providing free as well as commercial support for web, Linux and Unix
solutions.
<!-- *** END bio *** -->
<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P -->
<H5 ALIGN=center>
Copyright &copy; 2001, Kapil Sharma.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
Published in Issue 66 of <i>Linux Gazette</i>, May 2001</H5>
<!-- *** END copyright *** -->
<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->