A Crash Course in CVS

advertisement
A Crash Course in CVS
19 November 2003
Joe Vornehm
Northwestern University
ECE Department
Overview
•
•
•
•
•
•
The need for version control
Version control basics
CVS basics: adding, updating, committing...
Controlling the project
Things that don’t work well
Q&A
Assumptions
• Basic familiarity with Unix shells
– GUI tools also available
• For “Unix on Windows:” www.cygwin.com
• For more info: www.cvshome.org
• This presentation:
http://www.ece.northwestern.edu/~jev283/
talks/cvs/
The Need for Version Control
• Tracking changes during development
– Seeing how, when things changed
– “The ‘Oops’ factor”
• Coordinating among multiple developers
• Access control (not CVS)
• Solution: Keep a history of each file in a
central location called the “repository”
Version Control Systems
• Big “Repository in the
Sky”
• Local copies of files in
“working directory”
– Develop program in
working directory
– Copy files to/from
repository—called
“checking in/out” or
“committing/updating”
Repository
Alice’s
working
directory
Bob’s
working
directory
Interacting with CVS
• cvs command
– GUIs also available
– CVS interface built into editors, MATLAB, etc.
• CVSROOT environment variable specifies
location of CVS repository
– Can be local directory, network disk, CVS
“pserver,” rsh/ssh tunnel
– Can also use “cvs -d”
CVS Commands
•
•
•
•
cvs global-opts command command-opts
cvs --help-commands, cvs -H command
cvs --help-options (not for beginners)
Examples:
– cvs add hello.c
– cvs add -m “Created hello.c” hello.c
– cvs -d $MY_CVSROOT add -m “Created
hello.c” hello.c
CVS Commands (concl.)
• Most CVS commands accept a filename,
many filenames, or no filename to mean the
current directory (and -R to recurse below
the current directory)
One Important Global Option
• cvs -n command … causes CVS to execute
the command without changing any files on
disk (or in the repository)
– Good for seeing what something will do before
you try it
– Certain behaviors are different with -n, so you
may get strange errors that go away when you
don’t use -n
Getting Started
• Easiest way: import an existing project, then
create a new working directory
• Make a repository:
– mkdir /project/cvsroot
– export CVSROOT=/project/cvsroot
• Probably want this in .profile or .cshrc
– cvs init
Getting Started (cont.)
• Import original source directory
– cd /project/myproj
– cvs import myproj mygroup start
• myproj is the name of the CVS “module”
• mygroup is some tag indicating where the
sources came from (not used very much)
• start is some tag indicating that this is the
very first import of this project into CVS
Getting Started (concl.)
• Create a local working directory
– cd ~/work
– cvs checkout myproj
• Gets a clean copy of myproj source code, puts it in
directory myproj
– cd myproj
• Start developing!
The Daily Grind
• cvs commit, update, and add make up the
vast majority of day-to-day CVS usage
• cvs commit: Take changes made to working
directory, commit them to CVS repository
• cvs update: Get latest versions from CVS
repository, update working directory
• cvs add: Add a file from the working
directory to the repository
cvs commit
• Make changes to a file, then commit the file
using cvs commit filename
– CVS prompts for a “log message,” something
short and descriptive of changes, like,
“Changed frobnitz operator to support multiple
inheritance.”
– Alt.: specify message using cvs commit -m msg
• “cvs commit” with no filename commits all
changed files in current directory
cvs update
• cvs update filename updates a file in the
working directory so it matches the latest
version in the repository
• “cvs update” with no filename updates all
changed files in current directory
• CVS actually updates files by merging
version-to-version changes with the
working directory file… more later.
cvs add
• cvs add filename tells CVS to add a file to
the repository during the next commit
operation
• cvs commit filename (or cvs commit)
actually adds the file… same syntax as
before.
Status information
• cvs log filename gives a history of all
commit log messages for a particular file
• cvs status filename gives status information
about a particular file (version number,
whether it needs an update or a commit,
etc.)
• cvs history gives history information about
repository accesses
Useful Commands
• cvs diff filename compares a local file to a
repository version, compares two versions,
etc.
• cvs update -p filename prints the updated
file to the screen without changing the file
on disk… useful for pipe commands
CVS Keywords
• CVS generally does not independently
change the contents of files you commit or
update
• Keywords are an exception: $Id$,
$Revision$, $Log$, etc.
• CVS updates these strings with the
appropriate information at each revision
CVS Keywords (cont.)
• Example:
/* hello.c -- Guess what it does. */
#include <stdio.h>
/* $Revision$ */
int main(int argc, char **argv)
etc.
CVS Keywords (concl.)
• After check-in, the file reads:
/* hello.c -- Guess what it does. */
#include <stdio.h>
/* $Revision: 1.1$ */
int main(int argc, char **argv)
etc.
Adding another person
• Ideal development cycle:
– Alice works on functions.c, Bob works on
main.c
– Alice makes a change to functions.c, commits
– Alice: “Bob, I added that thingy to functions.c.”
– Bob: “OK.”
– Bob runs cvs update functions.c (or just cvs
update) and continues developing main.c
Adding Another Person (cont.)
• More realistic development cycle:
–
–
–
–
–
Alice is working on sum() in functions.c
Bob is working on product() in functions.c
Alice finishes sum() and commits functions.c
Bob finishes product() and tries to commit
CVS refuses, because it knows Bob is working
on an old version of functions.c
Adding Another Person (cont.)
• What is Bob to do?
– Bob runs cvs update functions.c
– If Bob is lucky, he and Alice haven’t changed
the same lines anywhere
• CVS merges Alice’s changes with Bob’s in Bob’s
copy of functions.c
• Now Bob can commit his copy of functions.c with
both his changes and Alice’s
• …and Bob should tell Alice that he committed
functions.c again!
Adding Another Person (cont.)
• What if Alice’s and Bob’s changes conflict?
– If Bob is unlucky, he and Alice have changed
some of the same lines in different ways
– cvs update: In the conflicting areas, CVS puts
both sets of changes into Bob’s copy of
functions.c, set off by angle brackets
– Bob has to merge the changes manually
(typically deciding whether to keep his changes
or Alice’s) and then commit the file.
Adding Another Person (cont.)
• Other ways to handle conflicting updates:
– Alice and Bob can have a meeting to discuss
which changes Bob should make
– Bob can postpone the merge and just continue
development with his own functions.c (without
Alice’s changes)
– Bob can overwrite his functions.c with the
repository copy (that has Alice’s changes but
not his)
Adding Another Person (concl.)
• One developer: never (rarely) any conflicts
• A few developers (2-20): occasional
conflicts
– Either each piece of code is one person’s
responsibility, or developers are working
together anyway
• Many developers: conflicts arise
– Need more than just CVS to resolve issues
Tag! You’re It
• Sometimes you want a snapshot of the
project state
• Symbolic tags are a way to do that
– One tag means “the version of each file that
was current when this tag was created”
– Good for external releases, forks, big decision
points, experimenting
• cvs tag tagname or cvs tag tagname files
Working with Old Versions
• Most CVS commands (commit, update,
diff) accept the -r revision flag to deal with
a specific version instead of the most recent
version
– Example: cvs update -r 1.3 functions.c will go
back to version 1.3 of functions.c
• But beware: this creates a “sticky tag” that
may bite you later…
Sticky Tags
• Sticky tags are CVS attributes that “stick”
to a file across commit/update cycles
• Most common sticky tag is revision number
– After cvs update -r revision filename, future
updates of filename will still “update” it to
version revision, not the current version
• To undo: cvs update -A filename
• Note: Regular tags (cvs tag) are sticky, too
Branches
• Sometimes, development needs to go down
two different paths simultaneously (e.g.,
experimental features)
• Tag the project, but make the tag a “branch
tag” using cvs tag -b
• Tags are sticky; CVS will know to commit
to the branch instead of to the main
development line
Branches (concl.)
• Branches can be merged or brought into
sync
• Branches can cause some headaches if not
used properly
• It’s often easier to develop a branch in a
separate working directory from your main
working directory
Advanced Topics
• Editing repository files or CVS-directory
directly (text editor, format is simple)
• Writing scripts that run every time
something happens to the repository
(commit, update, etc.)
• Unix, Windows, Cygwin, end-of-line
compatibility
Some Things Don’t Work (Well)
•
•
•
•
Deleting files: works but with artifacts
Renaming files: not easy but possible
Renaming directories: good luck!
Version numbers can be confusing (1.1 vs.
1.1.1.1)
• Can’t use CVS for access control (except
maybe via repository scripts)
Other Version Control Solutions
•
•
•
•
•
•
subversions (GNU)
RCS (GNU)—older, not as flexible
SCCS (vendors), PVCS
Clearcase, MS Visual SourceSafe
Try http://www.gnu.org/directory/
Look for CVS add-ons (e.g. GUIs) at
http://www.cvshome.org/
Download