CSP301
CVS
A useful Page
Motivation:
Lets consider the way
coding is done for large projects in real life. What are the issues:
- Multiple people work on a
project- how to we synchronize their work.
- Many a things need to be
recoded...enhancements, bugs may be reasons.....but then this may cause
further problems....wrong design, some unaccounted dependencies - the
problem of restoring things as they were.
- How do we keep track of
changes- who did what and when
These are the kind of things that CVS
(standing for concurrent versioning system looks at)
Introduction to CVS's approach:
We looked at the the
various questions above now we understand how CVS tries to solve these
problems:
- Multiple people: Well if we
allow people to work on the files with their own set of files then they
need to be sync'd together, at some point in time. CVS depends on
co-operation of the developers to do this syncing . You as a member of
the group will specifically have to submit the change for them to be
visible to others. It can't do anything if you don't care to
submit(....remember to be a responsible team (wo)man. :)... ). Note that while you are making changes
they aren't immediately visible to others so modular structure of the
project in terms of well separated files of interest is all the more
important....making appropriate allocation of files and directories at
the time of start.You will still have decide on merge points etc.
- Now the most rudimentary
method to keep track of all the changes is to have snapshots of all the
stages. But then imagine how much disk space wastage that shall mean.
CVS does something better-it stores the changes in an incremental
manner such that you can recover your files up to any point in the
past, without the need to have to have multiple copies. In fact this
gives rise to the concept of versions. Note that it is important to add
comments while submitting changes otherwise it will become difficult
for you to determine what all changes were made in causing the
change of version, if a need of rollback ever arises.
- Keeping versions and
associated comments along with the changes submitted, at each stage,
clearly does the job of tracking changes well.
Basic Functioning:
Let's look at the basic
set of commnads needed at working with CVS for a given project.(block letters indicate commands,
assume that the project name is NetLib)
Basic setup:
- The first thing is to setup
the root for the cvs repository: This is the place where all the cvs
files are stored. CVS can support this repository over network too,
through cvspserver, but for sake of simplicity assume that we have it
in our home. Assume that we have our repository in '$HOME/cvsRoot',
then best way to let CVS know about you choice of root is to set
$CVSROOT variable in .bash_profile and export it.
- We shall also set $CVSEDITOR
varibale to identify the editor that is used to add comments while
commiting changes.
To make above add
following lines to $HOME/.bash_profile (source the .bash_profile: source .bash_profile after making
these changes)
CVSROOT=$HOME/cvsRoot/
CVSEDITOR=vi
export CVSROOT
CVSEDITOR
- Now we need to initialize the
$CVSROOT for use as respository root.Do a 'cvs init' to initialize the
directory pointed to by $CVSROOT. Note that to refer to some
directory other that that variable pointed one we can always pass
'-d [diectory from cvs]' options at any stage.$CVSROOT just
serves as the default variable.This generates all the book keeping
files needed for the working of cvs. With our cvs repository in place
we move on to using phase.
Using CVS:
- First natural thing to
ask is how to add a project to the CVS. Assuming that you have created
the project at $HOME/preoject/NetLib. We do the following:
cvs [-d ~/cvsRoot
import] -m "Start files" NetLib sample start
N
NetLib/Makefile
cvs import:
Importing /home/attic/avinash/cvsRoot/NetLib/lib
cvs import:
Importing /home/attic/avinash/cvsRoot/NetLib/bin
cvs import:
Importing /home/attic/avinash/cvsRoot/NetLib/src
N
NetLib/src/a.c
N
NetLib/src/b.c
cvs import:
Importing /home/attic/avinash/cvsRoot/NetLib/doc
cvs import:
Importing /home/attic/avinash/cvsRoot/NetLib/include
N
NetLib/include/a.h
N
NetLib/include/b.h
No conflicts
created by this import
Here
'-m ' is use to give the comment 'Start files' while -d option again gives the root.
NetLib is the name under which the project appears in the $CVSROOT.
Rest of the options don't have much meaning .
Have a look at the root repository now and see how does the project
appear there.
- Now lets have a look at
what can be 'checked out' from the cvs once the directory has been
imported.
cvs
-d ~/cvsRoot/ checkout NetLib
U NetLib/Makefile
cvs checkout: Updating NetLib/bin
cvs checkout:
Updating NetLib/doc
cvs checkout:
Updating NetLib/include
U
NetLib/include/a.h
U
NetLib/include/b.h
cvs checkout:
Updating NetLib/lib
cvs checkout:
Updating NetLib/src
U
NetLib/src/a.c
U NetLib/src/b.c
You can use 'co' instead of 'checkout'. The
entire NetLib gets replicated !!
- Okay we have a
'checked' out project how do we sumit changes to the CVS.Assume
Makefile was changed above.
cvs -d
~/cvsRoot/ commit -m "Added all to makefile" Makefile
Checking in Makefile;
/home/attic/avinash/cvsRoot/NetLib/Makefile,v <--
Makefile
new
revision: 1.2; previous revision: 1.1
done
Notice the version change performed as
Makefile gets updated.This is what can be used later to restore things
to previous stage.
We just have
to roll back to some older version number on that file.
- Once you are done with
updates you can 'release' the working copy by
using
cvs -d ~/cvsRoot/ release -d NetLib/
(
from the dir above Netlib)
You have [0] altered files in this repository.
Are you sure you
want to release (and delete) directory `../NetLib/': y
This
indicates the case where all the files have been comitted to the cvs
and the file in the working dir are the same as those in the
repository.If not than release
complains about altered files and your
changes aren't lost...just because you forgot to remember what all
files were changed.
- Other commands:
- cvs add filename : Adds the named file to the CVS as a
component of the checked out project.This addition actually takes place
as subsequent commit.
- cvs remove filename: Removes the file from versioning systems.
Effects at commit or release time
- cvs log
filename: Show all the changelog messages that we provided at
commit time.
- cvs diff
filename: Shows the difference between working file
and the cvs file.
Retrieval of files:
- Date based retrieval:
We can request the latest entry upto a date using -D "YYYY-MM-DD"
format date contructs.That s where meaningful log messages may be
useful.
cvs
-d ~/cvsRoot/ co -D "YYYY-MM-DD" NetLib
This
shall restrore the NetLib to the level it was on date "YYYY-MM-DD". And thus we can restore things to sanity
if changes go haywire.
- Tag (event) based retrieval:
Here we can retrieve upto some important point in the process, that has
been tagged using some special name.On access of the source we can then
specify the tag to use making a rollaback upto a major milestone
possible that are often results of major structure change in the
code, which are major sources of error. The relevent commands are:
(set tag )cvs rtag
milestoneI myproj
(use tag)cvs checkout
-P -r milestoneI myproj
(untag) cvs -d milestoneI myproj
'-n
' option lets you know what shall happen without actually performing
the action.
- Handling Multiple
users: Okay now you have checked out and some one has edited a file
after that and comitted that changes. We must get the file upto
date. The commands are:(if other user made changes to the makefile)
cvs
status Makefile: this shall
compare the version of the file at the repository and the Makefile in
the working directory .
File:
Makefile Status:
Needs Patch
Working revision:
1.2 Tue Aug 17 22:20:14 2004
Repository revision:
1.3
/home/attic/avinash/cvsRoot/NetLib/Makefile,v
Sticky
Tag: (none)
Sticky
Date: (none)
Sticky
Options: (none)
As we can see here the working copy is older
that the Recent copy at the server.So we need to update our copy with
the new changes. The states possible are
- Up-to-date (files are the
same on both sides)
- Locally Modified (you have
modified the local copy but no changes have been comitted.
- Needing Patch (the recent
copy of the file has changes )
- Needs Merge ( a new version
has come up and also you have modified the filed)
cvs update Makefile: this shall cause the updation of the files
with the changes that were made by the other user.
U Makefile
The output
indicates that the file got updated . As only a patch was needed for
the file in consideration. But if the ' Status:
Needs Merge'
was
returned then we need to
make some changes before
update can be done.Running update gives error of the type
cvs -d ~/cvsRoot/ update
b.c
RCS file:
/home/attic/avinash/cvsRoot/NetLib/src/b.c,v
retrieving revision
1.1.1.1
retrieving revision 1.3
Merging differences
between 1.1.1.1 and 1.3 into b.c
rcsmerge: warning:
conflicts during merge
cvs update: conflicts
found in b.c
C b.c
The resulting file is
of the type: ('vim b.c')
<<<<<<< b.c
//go!
NoHello(){}
=======
//hi!
Hello(){}
>>>>>>> 1.3
which indicates what has changed.To make
the final version we decide what to select and them commit in the
normal fashion indicating that the conflict has been solved.
Note that while doing so the extra lines '<<<<<...." and
">>>>>....." should be deleted.
Don't worry about forgetting to perform this upto-date check before you
commit.In such a scenario commit returns with the following error:
cvs -d ~/cvsRoot/
commit -m "Failed Attempt" Makefile
cvs commit: Up-to-date check
failed for `Makefile'
cvs [commit aborted]: correct
above errors first!
You can look
at the other options using man or info on cvs.
Thanks --
Avinash