Problem #1: Synchronizing Files
Want to work on one set of files on three different machines
Home, office, a friend's
Option 1: single file system
Difficult to set up (and make secure)
Inflexible: what if I'm on the road?
Option 2: Carry around a floppy
Have to remember to copy files onto it
And off again
My project might not fit onto one
Option 3: mail, ftp, scp, etc.
Still have to remember to push and pull exactly the right files at exactly the right time
Option 4: get the computer to do the work
Keep a master copy in one place
Write a program to push and pull changes
If it's worth repeating, it's worth automating
Problem #2: Undoing Changes
Sometimes want to undo changes to a file
Start work, realize it's the wrong approach, want to get back to starting point
Like "undo" in an editor
But longer-lived (whole history of file)
Solution: Version Control
Keep copies of old files in repository
Instead of overwriting xyz.java, rename it to xyz.java.1
Next time it changes, create xyz.java.2, etc.
Also record times: "What did these files look like at noon last Friday?"
File Histories
Two ways to describe a file
Version #3
At time 15:30
Storing Differences
Storing whole files very expensive
So just store differences
file #0 + diff #1/2 = file #1
By induction, create any file from original state plus differences
Backward Differences
In practice, want recent versions of files much more often than old versions
So store latest version of file plus backward differences
Final Storage Scheme
Backing Out
Angela decides something has gone wrong
Can revert changes by:
Putting master copy of files back into previous state
Deleting deltas after that state
What if several files changed at once?
CVS doesn't record change sets explicitly
Have to guess which file changes go together
Better systems (e.g. Perforce) do
Can revert entire change set in one step
Problem: Sharing Files
How can Angela and Hassan work on the same files at the same time?
Edit the same physical files simultaneously (no)
Copy files to and from a shared directory by hand (no)
Synchronize via email or chat
Doesn't scale beyond two or three people
Use the version control system (yes!)
Record user ID in the saved difference
Who changed what? When?
Managing Concurrency
What if two (or more) people want to edit the same file at the same time?
Option 1: prevent it
Only allow one person to have a writeable copy of the file at once
Pessimistic concurrency
Microsoft Visual SourceSafe
Option 2: patch up afterwards
Optimistic concurrency
"Easier to get forgiveness than permission"
CVS, Perforce, Subversion
Sharing Example
Angela and Hassan both have copies of a.java#1.5
Angela commits her changes
Creates a.java#1.6 as usual
Then Hassan wants to check in his changes
Conflict!
Must resolve differences by hand
Then commit the change to create a.java#1.7
![[conflict Example]](../img/version/conflictExample.png)
<<<<<<< a.java
Iterator i = changedGroups.iterator();
while (i.hasNext()) {
if (userNotInGroup(currentUser, (Group)i.next())) {
addUserToGroup(currentUser, (Group)i.next()));
}
}
=======
Iterator i = changedGroups.iterator();
while (i.hasNext()) {
Group g = (Group)i.next();
if (userNotInGroup(currentUser, g)) {
addUserToGroup(currentUser, g));
}
}
>>>>>>> 1.3
CVS
Concurrent Version System
Command-line tool on Unix and Windows
Built on top of older system called RCS
Several graphical and web interfaces
You will use this to submit work in this course!
First step: set your CVSROOT environment variable
TA will explain how in first lab
Common CVS Commands
cvs checkout root |
Get initial copy |
cvs add filenames |
Add new files |
cvs update [filenames] |
Synchronize with repository [1] |
cvs commit [filenames] |
Commit local changes [2] |
cvs remove filenames |
Remove files from repository [3] |
cvs diff [filenames] |
Show differences between local copy and repository |
cvs log [filenames] |
Show history of files |
Notes
[1] Update will copy changes from the repository to local files, and notify you of changes to local files that need to be committed to the repository.
[2] Must update and resolve conflicts before committing.
[3] There is no way to delete directories in CVS.
CVS Example
$ cvs checkout ex01 cvs server: Updating ex01 U ex01/map01.java U ex01/map02.java $ cd ex01 $ ls CVS/ map01.java map02.java $ edit map01.java map03.java $ cvs add map03.java cvs add: scheduling file 'map03.java' for addition $ cvs update cvs update: Updating . M map01.java A map03.java $ cvs commit -m "Started assignment 1" map03.java cvs commit: Examining . RCS file: /repo/ex01/map03.java,v done Checking in map03.java; /repo/ex01/map03.java,v <-- map03.java initial revision: 1.1 done
Keyword Expansion
CVS replaces strings like $Keyword:$ with associated value during check-in
$Author: reid $
$Date: 2004/01/04 05:02:31 $
Always in Universal Time
$Revision: 1.1.1.1 $
Often embed these values in strings, rather than in comments
class Something implements Versioned {
public static final String VERSION = "$Revision: 1.1.1.1 $";
public String getVersion() {
return VERSION.split(' ')[1].trim();
}
}
File Types
CVS treats files as text by default
Tries to perform keyword expansion
Tries to translate Unix and Windows line endings
Often don't want this
E.g. image files
Add with cvs add -kb filename
-kb means "binary"
Manual explains how to set file type after the fact
What To Check In
Don't check in files that are automatically created from others
E.g. class files
Uses disk space and bandwidth for no reason
Do check in:
Your own little test programs
And their expected output
Readme files, notes, build logs, etc.
Anything else you created by hand
When To Check In
Version control is not a backup system
Your computer should have one of those
Don't check in just because you're taking a break to surf the web
Check in files when they are stable
E.g. after adding a new feature
Or when you have to move from location to location
E.g. from home to school or vice versa
For More Information
$Id: version.html,v 1.1.1.1 2004/01/04 05:02:31 reid Exp $