Forget you've heard of RCS. Just think about the problem.
How do you get multiple programmers to safely work on the same large code base?
Possible strategies:
Don't get revisions / implicit backup with any of these strategies.
How do you track evolution of a program and how do you make releases?
Need because:
Possible strategies:
CVS (concurrent versions system) is a widely-used, free, open-source tool that manages the above strategies for you. It's "designed by committee" but great for a free tool. Perforce is better, imho, but costs $600 per seat.
CVS has the notion of a repository that stores your your code, tracks all changes, and records your revision comments. CVS doesn't do transactions and doesn't have a real db...just a bunch files on the disk. You can wack trees off the repository (and remove local CVS dirs) w/o consequence. CVS works off a repository directory $CVSROOT and stores some local information in your directories that it manages. You'll set CVSROOT=~userid/cvsroot in your .cshrc or .bashrc etc...
You do not mess with repository, you checkout directories/files, make changes, and then commit your changes and add comments for the log.
Command line usage: cvs command ...
RCS -- Walter Tichy -- works on single files to track revisions. Think of CVS as just a recursive RCS that works on multiple files / dirs. When you check out some code, it does a cp -r repository CWD. When you commit, it does a diff of your current files against repository and then merges your stuff into repository. After a commit, the repository will be a dup of your CWD.
You check out once, commit many time.
There is an implied main branch (main trunk). 1.1, 1.2, 1.3, ... for
all files. The HEAD is the latest version of each file.
http://cvsbook.red-bean.com/cvsbook.html
Copyright B) 1999, 2000 Karl Fogel
http://cvsbook.red-bean.com/cvsbook.html
Copyright B) 1999, 2000 Karl Fogel
I expect you students to play around to get the feel. It takes experience.
You will only need a few CVS commands as a single coder:
cvs import -m 'Initial TML import' org/antlr/tml ANTLR start
I suggest strongly the following dir structure:
~/projects/Server/main/http/*.java
~/projects/Server/release/alpha/http/*.java
~/projects/Server/release/1_0/http/*.java
...
where http is the package name so http.Server maps to
~/projects/Server/main/http/Server.class
if your CLASSPATH is set to .:~/projects/Server/main.
Same concept as single-user mode--you'll just be doing that stuff in your own branch.
----main-----------------> | | ^ ^ | v | | | ---john01--/ | | | v | ------mary01-----/Do not push bug fixes from main line into dev branch (limitation of CVS). Bug fixes manually done in >=2 dev brances will cause conflicts during merge with mainline, but same code so it's ok.
I suggest strongly the following dir structure:
~/projects/Server/main/http/*.java
~/projects/Server/dev/john-fixing-GET/http/*.java
~/projects/Server/dev/mary-adding-logging/http/*.java
~/projects/Server/release/alpha/http/*.java
~/projects/Server/release/1_0/http/*.java
...
Note: you can have as many of these branches checked out as you want or you can release them. Cancels the effect of cvs checkout.
To make a dev branch and merge your changes back into the main line, follow this procedure:
$ cd ~/projects/Server/main/http $ cvs tag -b john01.dev
$ cd ~/projects/Server/dev/john01.dev $ cvs checkout -r john01.dev httpNote that -b and -r flags are different for some stupid reason.
$ cvs statusWill show
Sticky Tag: john01.dev (branch: 1.3.2)
$ cvs commit
$ cd ~/projects/Server/main/http $ cvs update # are we fresh? $ cvs update -j john01.dev # merge john01.dev into main
$ cvs commit
$ cd ~/projects/Server/dev/john01.dev $ cvs release $ chmod -R a-w . # if you want (makes read only)
Here is the script output (cleaned up minus the release branch item):
[jazz:~] parrt% cd /tmp
[jazz:/tmp] parrt% mkdir http
[jazz:/tmp] parrt% cd http
[jazz:/tmp/http] parrt% cat > T.java
package http;
public class T {
int i = 3;
}
[jazz:/tmp/http] parrt% cvs import -m 'course test' http USF start
N http/T.java
No conflicts created by this import
[jazz:/tmp/http] parrt% ls -l /var/data/cvsroot
total 0
drwxr-xr-x 37 parrt wheel 1258 Sep 7 11:31 CVSROOT
drwxrwxr-x 21 parrt wheel 714 Sep 11 15:34 http
[jazz:/tmp/http] parrt% ls -l /var/data/cvsroot/http
[jazz:/tmp/http] parrt% mkdir -p /tmp/projects/Server/main
[jazz:/tmp/http] parrt% cd /tmp/projects/Server/main
[jazz:projects/Server/main] parrt% cvs checkout http
cvs checkout: Updating http
U http/T.java
[jazz:projects/Server/main] parrt% cd http
[jazz:Server/main/http] parrt% ls
CVS T.java
[jazz:Server/main/http] parrt% ls CVS
Entries Repository Root
[jazz:Server/main/http] parrt% cvs status
cvs status: Examining .
===================================================================
File: T.java Status: Up-to-date
Working revision: 1.1.1.1 Wed Sep 11 22:35:48 2002
Repository revision: 1.1.1.1 /var/data/cvsroot/http/T.java,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
[jazz:Server/main/http] parrt% cvs log
cvs log: Logging .
RCS file: /var/data/cvsroot/http/T.java,v
Working file: T.java
head: 1.1
branch: 1.1.1
locks: strict
access list:
symbolic names:
start: 1.1.1.1
USF: 1.1.1
keyword substitution: kv
total revisions: 2; selected revisions: 2
description:
----------------------------
revision 1.1
date: 2002/09/11 22:35:48; author: parrt; state: Exp;
branches: 1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 2002/09/11 22:35:48; author: parrt; state: Exp; lines: +0 -0
course test
=============================================================================
[jazz:Server/main/http] parrt% cat > U.java
package http;
public class U {
int j = 5;
}
[jazz:Server/main/http] parrt% cvs add U.java
cvs add: scheduling file `U.java' for addition
cvs add: use 'cvs commit' to add this file permanently
[jazz:Server/main/http] parrt% cvs commit
cvs commit: Examining .
...
Checking in U.java;
/var/data/cvsroot/http/U.java,v <-- U.java
initial revision: 1.1
done
[jazz:Server/main/http] parrt% cvs log
cvs log: Logging .
RCS file: /var/data/cvsroot/http/T.java,v
Working file: T.java
head: 1.1
branch: 1.1.1
locks: strict
access list:
symbolic names:
start: 1.1.1.1
USF: 1.1.1
keyword substitution: kv
total revisions: 2; selected revisions: 2
description:
----------------------------
revision 1.1
date: 2002/09/11 22:35:48; author: parrt; state: Exp;
branches: 1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 2002/09/11 22:35:48; author: parrt; state: Exp; lines: +0 -0
course test
=============================================================================
RCS file: /var/data/cvsroot/http/U.java,v
Working file: U.java
head: 1.1
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 1; selected revisions: 1
description:
----------------------------
revision 1.1
date: 2002/09/11 22:37:29; author: parrt; state: Exp;
added a file
=============================================================================
[jazz:Server/main/http] parrt% vi T.java
[jazz:Server/main/http] parrt% cvs commit
cvs commit: Examining .
Checking in T.java;
/var/data/cvsroot/http/T.java,v <-- T.java
new revision: 1.2; previous revision: 1.1
done
[jazz:Server/main/http] parrt% cvs tag -b dev01
cvs tag: Tagging .
T T.java
T U.java
[jazz:Server/main/http] parrt% cd /tmp/projects/Server
[jazz:/tmp/projects/Server] parrt% mkdir dev
[jazz:/tmp/projects/Server] parrt% cd dev
[jazz:/tmp/projects/Server/dev] parrt% mkdir dev01
[jazz:/tmp/projects/Server/dev] parrt% cd dev01
[jazz:projects/Server/dev/dev01] parrt% cvs checkout -r dev01 http
cvs checkout: Updating http
U http/T.java
U http/U.java
[jazz:projects/Server/dev/dev01] parrt% cd http
[jazz:Server/dev/dev01/http] parrt% cvs status
cvs status: Examining .
===================================================================
File: T.java Status: Up-to-date
Working revision: 1.2 Wed Sep 11 22:37:55 2002
Repository revision: 1.2 /var/data/cvsroot/http/T.java,v
Sticky Tag: dev01 (branch: 1.2.2)
Sticky Date: (none)
Sticky Options: (none)
===================================================================
File: U.java Status: Up-to-date
Working revision: 1.1 Wed Sep 11 22:37:29 2002
Repository revision: 1.1 /var/data/cvsroot/http/U.java,v
Sticky Tag: dev01 (branch: 1.1.2)
Sticky Date: (none)
Sticky Options: (none)
[jazz:Server/dev01/http] parrt% vi T.java
[jazz:Server/dev01/http] parrt% cvs commit
cvs commit: Examining .
Checking in T.java;
/var/data/cvsroot/http/T.java,v <-- T.java
new revision: 1.2.2.1; previous revision: 1.2
done
[jazz:Server/dev01/http] parrt% cvs diff T.java
[jazz:Server/dev01/http] parrt% cd /tmp/projects/Server/main/http
[jazz:Server/main/http] parrt% cvs update
cvs update: Updating .
[jazz:Server/main/http] parrt% cvs status
cvs status: Examining .
===================================================================
File: T.java Status: Up-to-date
Working revision: 1.2 Wed Sep 11 22:37:49 2002
Repository revision: 1.2 /var/data/cvsroot/http/T.java,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
===================================================================
File: U.java Status: Up-to-date
Working revision: 1.1 Wed Sep 11 22:37:11 2002
Repository revision: 1.1 /var/data/cvsroot/http/U.java,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
[jazz:Server/main/http] parrt% cvs update -j dev01
cvs update: Updating .
RCS file: /var/data/cvsroot/http/T.java,v
retrieving revision 1.2
retrieving revision 1.2.2.1
Merging differences between 1.2 and 1.2.2.1 into T.java
[jazz:Server/main/http] parrt% javac *.java # and test
[jazz:Server/main/http] parrt% cvs commit
Checking in T.java;
/var/data/cvsroot/http/T.java,v <-- T.java
new revision: 1.3; previous revision: 1.2
done
[jazz:Server/main/http] parrt% cd /tmp/projects/Server/dev/dev01
[jazz:Server/dev/dev01] parrt% cvs release http
[jazz:Server/dev/dev01] parrt%