http://ralf.alfray.com/.izumi/LinuxTips.blog?s=20060904_svn_for_the_cvs_dummies
This is a very highly summarized overview of how to use Subversion for those of us who are used to CVS. Note that none of this is original, it is all extracted from the Subversion Book, available freely online.
So first let's install subversion, that's the easy part:
% apt-get install subversion
That's the only thing needed as root, unless you want the to use webdav or https over Apache, which I don't care for right now. For using subversion over my lan, I used svnserve.
Now, under whatever user is going to use the repository, we need to create the initial repository itself:
$ svnadmin create /home/user/svnroot
Subversion typically calls the repository repos. However I'm used to having a cvsroot around so I choose svnroot accordingly.
To serve this over the lan, we'll use svnserver. There are lots of possible configuration, including inetd and ssh-tunnel based. The basic command-line manual daemon will work just fine, see the link above for other methods:
$ svnserver -d -r /home/user/svnroot
Now that's all we need for administration, we can start fiddling with projects.
First, we need to understand what Subversion is and is not:
The only things in common between Subversion and CVS are that both do version control and they have similar patterns for basic operations, meaning the words import, add, update and commit are used to mean the same concepts (contrast this with Perforce where one performs syncs and submits.) The words branches and tags however do not mean the same thing. Nor is the repository concept the same.
So let's be blunt: if you want something that is exactly like CVS, then just stay with CVS. However a quick overview of Subversion instantly shows that it's worth spending the time to adjust to some of its own paradigms:
If you want to understand what this really means, I urge you to read the basic concepts and the branching and merging chapters of the book.
In contrast to CVS, the repository is a unique directory that contains all projects merged together. This is not like CVS where each project is its own little repository. The layout of projects inside the subversion repository is left to the user. There is a canonical layout advocated by the book and it can help to mimic those (so that others accessing your repository can recognize the layout immediately.)
The layout goes like this:
svnroot/projectA/trunk/file1.cc svnroot/projectA/trunk/file2.cc svnroot/projectA/branches/somebranch/... svnroot/projectA/branches/anotherbranch/... svnroot/projectA/tags/sometag/... svnroot/projectB/trunk/... svnroot/projectB/branches/onemorebranch/... svnroot/projectB/tags
That is the top-level directories of the repository are the projects, which each contain trunk (main development line), branches (full copies of the trunk for branching) and tags (full copies of the trunk for tagging.) It is important to note that the names used (trunk, branches and tags) are pure convention, the names themselves are not special to subversion — we could use "premium, cheese and pythons" except for the fact the users would be totally lost.
Note than one key difference with CVS here is that all projects are just directories in the same repository and remember that revisions are just snapshots (aka sequence numbers of these snapshots) on the ''full' repository. So committing one file in one project essentially snapshots all projects at once. Although it may sound odd at first, one benefit of this is obvious: if one project is a main software and another one is a a common library used by many other projects, you get automatic synchronization between the main software and all its libraries. This makes it easier to create tags and branches that are consistent, where in CVS you'd have to manually tag or branch each individual project.
Another important difference with CVS is how to deal with branches and tags. Contrary to CVS, subversion doesn't have branches or tags per see at all. All it has is the concept of a repository snapshot at time T and a concept of a shadow copy (a.k.a. copy-on-write) which they call cheap copies in Subversion linguo. So really branches and tags are "full" copies of the repository within itself. So the idea is to have the following convention:
Remember that the "branches" and "tags" directories are pure conventions. So in fact you don't even need to bother creating them until you actually need them. And if you plan to never use branches or tags, there's not even the need to have a "trunk" directory in the first place.
So here's an alternate layout that might work better for me:
svnroot/trunk/projectA/... svnroot/trunk/projectB/... svnroot/stable/sometag/projectA/... svnroot/stable/sometag/projectB/... svnroot/unstable/...
The thing is that I generally don't need branches. However I use tags to mark releases and I have stable releases vs unstable releases.
So let's try this for my repository:
$ mkdir tmpsvn $ mkdir tmpsvn/cs $ cp -r /oldcvs/Project tmpsvn/cs/. $ svn import tmpsvn file:///home/user/svnroot
Note that this will import all the content of tmpsvn, and not the top directory itself.
Now we can trash the tmpsvn and perform a real checkout. The thing is that whatever is checkout will be made a directory, just like a CVS project. So the following svn checkout will only yield workarea/cs/:
$ mkdir workarea $ cd workarea $ svn checkout file:///home/user/svnroot/cs $ ls -la cs
However there's a problem here: the top-level of the checkout doesn't seem to have a .svn associated with it, so I can't act on it.
Seems like what I want is really to get svnroot:
$ svn checkout file:///home/user/svnroot $ mv svnroot workarea
Note the URL-like argument above. If we want to use a LAN based svnserve server, we would probably do something like this:
$ svn checkout svn://hostname/path/relative/to/the/svnserve/argument
This gets tedious very fast. Of course once you have a working copy you no longer need the URL thing (i.e. just svn status, svn commit, etc.) But still, I miss my old $CVSROOT:
$ export S=svn://hostname/path $ svn checkout $S/cs
Now back to my repository, I just realized I wanted the following layout:
svnroot/<language-name>/<project-name>
So in practice I'll have this:
svnroot/python/Rig2 svnroot/csharp/AppSkeleton svnroot/csharp/DualTimeZone svnroot/csharp/LibUtils/LibUtils{2,Test...} svnroot/tags/...
Language name is going to be a full word (shell, python, ruby, csharp, php.) Oops above I started with "cs" instead of csharp. No biggie:
$ cd workarea $ svn rename cs csharp $ svn commit -m "Renamed cs to csharp"
And let's create a bunch of language directories since I'll need them:
$ svn mkdir python ruby shell php misc cpp $ svn commit -m "Language top-level dirs"
However, once I get a bunch of other languages in my repository, I want to be able to only extract a part of it:
$ cd workarea $ mkdir csharp && cd sharp $ svn checkout file:///home/user/svnroot/csharp
-> creates a csharp directory here
$ mv csharp svn $ pwd
-> workarea/csharp/svn
The good part here is that contrary to CVS I can screw up my layout and directory naming scheme and easily fix it. That means I can safely adopt my own repository layout and go back to the traditional trunk/branches/tags later if necessary. The other good part, as seen above, is that you can checkout just a part of an existing bigger repository and not pull everything at once — which incidentally can be used to mimic CVS's per-project repository paradigm.
documented on: 2007-09-22