60
May
2003
www.linux-magazine.com
Subversion
SYSADMIN
ples of both database and version controlsystems is that either your entire changeis accepted or your entire change isrejected. This behaviour is called atomic-ity (this is the A in ACID). In CVS, this isnot guaranteed.Atomicity is only guaranteed on a file-by-file basis. This means that if you arecommitting changes to 10 files, andsomeone else starts a commit at roughlythe same time as you which changes the8th file in your list, the changes for thefirst 7 files in your change get accepted,and the rest gets rejected. After thishappens, it is very likely that therepository will be in an inconsistent stateuntil you resolve the conflict you’ve justfound and commit the rest of yourchange.In addition, because CVS has no wayof grouping changes to a number of filestogether, it isn’t even possible to revertyour partial commit while ensuring thatthe successful commit which happenedat the same time doesn’t get reverted aswell.An illustration might help explainthe problem. Tom and Dick are workingon the same source code tree whichhas 3 files in it – a.c, b.c and c.c. By coin-cidence, Tom and Dick try to commitchanges at the same time. They bothcheck that they are up to date with therepository, and then at the same timethey try to commit their changes.While Tom is writing his changes toa.c, Dick starts writing to b.c. Before Dickhas finished, Tom starts writing to c.c.Dick’s commit finds that Tom has lockedc.c, and informs him that his c.c is nolonger up to date. Dick does an update toget Tom’s changes, and finds that there’sa conflict in c.c which he has to resolve(perhaps in conference with Tom).Meanwhile, Harry checks out thesources and has Tom’s changes to a.cand c.c, and Dick’s change to b.c, but notDick’s change to c.c. He tries to build theproject, and finds that he can’t. In brief,until Tom and Dick resolve Dick’s con-flict, neither Tom, Dick or Harry has aworking copy of the source code.Subversion implements atomic com-mits. When you commit to a Subversionrepository, you start a transaction withthe repository, and if any part of thecommit fails, the transaction is rolledback and the entire commit is rejected.
Files & versioning history
CVS has no way to rename files and keepversioning history. Renaming “file1” to“file2” in CVS means doing thefollowing:
$ mv file1 file2$ cvs remove file1$ cvs add file2$ cvs commit
This creates a new “file2” with no recordof a common history with the old “file1”(which is now stored in the Attic).In Subversion, the above operation isperformed by
$ svn move file1 file2$ svn commit
and the common history of “file1” and“file2” is conserved.In addition, Subversion has dramati-cally increased the things that can beversioned. Directories and file metadata,as well as renamed or copied files, allhave their own versioning. This meansthat not only can you move and copyfiles, you can move and copy directoriestoo.These copies are very cheap, becausethey’re lazy copies – the first copy is sim-ilar to a hard-link to a particular versionof the directory. As you change files onthe branch, only those files you changeget copied onto the branch. This meansthat making and maintaining branches isa cheap operation, both in terms of spacein the repository and in terms of time.
Branching and tagging
When we tag a repository in CVS, everyfile in the directory tree we are tagging is“stamped” with the tag. Likewise, whenwe are branching, the branch tag iscreated in each file affected. This meansthat branching and tagging are expensiveoperations for big repositories and direc-tory trees, which has a cost proportionalto the number of files being branched ortagged.Subversion has made both branchingand tagging constant time operations. Infact, Subversion makes no distinctionbetween a tag and a branch. Both of these are implemented simply by copy-ing the directory you are tagging, andhave a cost the same as any other copy.Logically there is no differencebetween branching and tagging – a tag isa copy of a group of files at a certainpoint of time, and a branch is a copy of agroup of files at a certain point in timewhich can be changes independentlyof the rest of the tree. In brief, a tagis a branch that we don’t change. InSubversion, this is the case. If youchange a file in a tagged tree and com-mit, the tag suddenly becomes a branch.In addition, requesting a file off abranch in CVS requires time proportionalto the number of revisions since thebranch point with the HEAD branch,plus the number of revisions made inHEAD since the branch point. RCS filesstore the latest revision in HEAD as fulltext, and any time you request the text of another version, it has to be constructed.This means, for a file on a branch,
Figure 1:Screenshotof Mozilla pointing atthe Subversion repository
Leave a Comment