Beware that a lot of the online documentation covers older versions of subversion. I am now running 1.6.6 and a lot of the online documentation covers 1.4 or older. This is not a terrible situation since none of the basics have changed, but newer features are not documented and limitations have been removed. For example the move command now moves multiple files, a command svnsync has been added, and things like that, which are hard to find out about.
First of all, take a look at:
Beware that a lot of the online documentation covers older versions of subversion.
Second, get a copy of the Subversion book, and/or view it online at online subversion book.
Long ago I tried using RCS, but then CVS came along and that really saved the day. Now subversion promises (and people say delivers) all that CVS did, and fixes all of its major shortcomings, so here we go!
If you must, you could take a look at the random collection of junk I accumulated on how to use CVS.
First of all you have to decide how you want to handle your repositories, if you want more than one, etc. etc. Of course setting this up right is vitally important, but you don't have a clue when you are starting out. Nonetheless, it is the first thing you need to do to get started. What to do?
What I do is have one repository per project (totally unlike how I handled CVS) and keep all these repositories in some directory (typically~/SVN). I already had some toy project from the first time I began playing with subversion, so I renamed this repository to be ~/SVN/bogus. Then I made a new repository for the myproject, via the command:
svnadmin create ~/SVN/myproject
Now, somewhere outside the repository, and in this case on an entirely different machine, I create a template directory holding what I plan to import:
cd myproject mkdir branches tags trunk cd trunk tar xzvf myproject.tgz . cd ..
Now we do the import. This project has a lot of binary stuff and hidden files so we can really see how this is going to work. The binary files are mostly images as .gif files. To do this to a server on a different machine:
cd myproject svn import . svn+ssh://myserver.com/home/sam/SVN/myproject -m "initial import"
To do this on the same machine:
cd myproject svn import . file:///home/sam/SVN/myproject -m "initial import"
This being done, I delete the whole template and then check out a working copy via:
rm -rf branches tags trunk svn checkout svn+ssh://myserver.com/home/sam/SVN/myproject/trunk src
Now the trunk business (see the book) has vanished and the only visible (or not so visible) artifact of going in and out of the repository is the .svn directory, the files themselves are unchanged.
Note that you are by no means required to do the trunk, branches, tags thing. In fact if you never intend to use branches (and you never should intend to) and you never use tags, it will just get in your way.
To look at a repository, you can use:
svnlook tree /path_to_repos
You can specify a given revision by number, or one of the following keywords. (These all refer to some version in the repository:
The command svn status is the quickest handiest way to see how your current copy relates to the repository.
Be warned! Branches have bitten me big time. Be careful about making branches and keep track of what you do when you create them or you are in for a world of hell when it comes time to merge them back into the trunk!! Making the branch is easy, deceptively easy. The pain and suffering comes when it is time to do the merge.
You make a branch by creating a copy within the repository, then checking out the copy. Something like this:
svn copy http://host/repo/project/trunk http://host/repo/project/branches/test -m "comment" svn checkout http://host/repo/project/branches/test mytestThe copy knows that it has a history originating in the trunk, (which can continue on its own path). The trunk has no idea whatsoever than a branch exists. Making the copy increments the revision number. It is your job to keep track of the branch point, subversion does not do it for you!!. If you don't remember the revision at which the branch was created, do this:
svn log --verbose --stop-on-copy
svn checkout svn+ssh://host/repo/project/trunk trunk cd trunk svn update
svn log --stop-on-copy svn+ssh://host/repo/project/branches/yada
If you have an up to date working copy of the branch, the following will yield the current revision number. (which had better be fully committed to the repository).
cd branch svn log
cd trunk svn merge -r r-split:r-branch svn+ssh://host/repo/project/branches/yadaThe files in the current directory get updated by the merge. The trick in all of this is giving the correct revision number range to the merge command. The range is not at all what I would expect. You are saying to compare the branch now to the trunk at the time of branching (i.e. sublimate all the change activity done on the branch), then apply that set of diffs to the trunk. You do NOT compare the current trunk to the current branch (which is what I would have expected).
cd branch svn merge -r r-split:r-trunk svn+ssh://host/repo/project/trunkThink of this as doing a diff, within the trunk itself, from the trunk at the time of the split to the trunk at the present time, then applying these diffs to the current directory (which is the branch). Again the whole trick is getting the version numbers. To get r-split, you will need something like:
svn log --stop-on-copy svn+ssh://host/repo/project/branches/yadaThe lowest numbered revision (at the end) is the number you want.
You will also want r_trunk, which you can get from:
cd trunk svn log
svn resolved fixedfile.c
The deal here is to monkey with the file /etc/httpd/conf.d/subversion.conf and to restart apache, repeating this process until things work.
All in all this is not too painful and pretty soon http://myserver.com/svn/myproject will be giving a view of your repository. This would be frightening except that there are two layers of protection. User apache can read but not write these files and the directive in the configuration file limits access to GET and other innocuous uses.
But, what do you do if you are running lighttpd and also want to offer access to a svn repository? At this point in time (mid 2007) there is nothing like the mod_dav_svn thing, and there is not likely to be any time soon. See my subversion with lighttpd notes for full details. In short, what you do is to run apache on an alternate port (like 8080) and set up the mod_dav_svn business. Then what you do is have lighttpd use mod_proxy to proxy requests to apache on that port via something like the following:
$HTTP["host"] == "projects.example.com" { server.document-root = "/var/www/projects.example.com/httpdocs" proxy.server = ( "/svn/test" => (("host" => "127.0.0.1", "port" => 8080)) ) }
svnadmin dump /path/to/repository > repository-name.dmp scp repository-name.dmp new_host: ssh new_host: cd /path/to/new-repository svnadmin create repository-name svnadmin load repository-name< repository-name.dmpAfter doing this, you will need to tell your working copies that the repository is in the new location. Do this via:
svn switch --relocate oldurl newurlAlternately you could just check out a new working copy and ditch the old one.
After I moved my repository from a local file (actually a link to an NFS mounted directory) to another machine entirely, I used the following command, and it worked like a champ:
svn switch --relocate file://localhost/svn/myproject/trunk svn+ssh://new_server/mmt/tom/SVNarchive/myproject/trunk
In my case I have a collection of repositories (one per project) that I would like to convert to projects within a grand repository (which is also under TRAC) on another machine. This will require extra fussing.
The basic task is to modify the original single project repository so that instead of just having the 3 directories (trunk, branches, tags) at the base level, it instead has a directory with the project name (and containing trunk, branches, and tags) at the base level. After this is done, a dump can be generated and just loaded into the grand repository as described above.
I am (as of 1/2010) running Subversion version 1.6.6 - this makes this whole business
easy. (In the old days (prior to version 1.5) you had to write scripts with loops
external to subversion.)
With the nice modern subversion, I can do what I want via:
svn mkdir svn+ssh://server/home/svn/project/project svn move svn+ssh://server/home/svn/project/tags svn+ssh://server/home/svn/project/project svn move svn+ssh://server/home/svn/project/branches svn+ssh://server/home/svn/project/project svn move svn+ssh://server/home/svn/project/trunk svn+ssh://server/home/svn/project/projectThen to clue in my working copy about what I have done, I need to do:
svn switch svn+ssh://server/home/svn/project/project/trunkAll of this seems to work fine, and sets the stage for moving this to the grand repository on a different server, as follows:
svnadmin dump /home/svn/project > project.dump scp project.dump new_server: ssh new_server svnadmin load /home/repo < project.dumpAfter this, in an attempt to clue in my working copy, I do this:
svn switch --relocate svn+ssh://old_server/home/svn/project svn+ssh://new_server/home/repoThis yields an unpleasant looking error:
svn: The repository at 'svn+ssh://new_server/home/repo/project/trunk' has uuid '...cdac2', but the WC has '...0899d'This means that the working copy has discovered that the repository has changed, and the generally recommended fix is to checkout a new working copy (which is what I do).
Suppose you have two repositories (repoA and repoB). Suppose also that repoA contains some project "P" that you would like to move to repoB. Here is how to do it:
svnadmin dump --quiet /home/svn/repoA | svndumpfilter include P > P.dmp svnadmin load --quiet /home/svn/repoB < P.dmp svn remove /home/svn/repoA/POf course, the first two steps above could be done in one big pipeline if the repositories were on the same machine.
# On the destination "mirror" machine cd NEW_REPOS nc -l -p 2345 | tar xv # On the source machine tar c OLD_REPOS > /dev/tcp/DOTTED.IP.OF.MIRROR/2345You pick a port number like 2345 for the task, then wonder what operating system supports the /dev/tcp scheme.
Look for svnsync on more recent versions of subversion.
sh: line 1: svn-commit.tmp: command not found svn: Commit failed (details follow): svn: system(' svn-commit.tmp') returned 32512This was a mistake in my .bashrc setting the EDITOR environment variable (which svn insists on). A typo caused it to be set to an empty string, and then svn was just blithely using that empty string as the name of an editor to run, yikes!