To take over the CVS user base. Specifically, we're writing a new version control system that is very similar to CVS, but fixes many things that are broken. See our front page.
No, Subversion is open source / free software. CollabNet pays the salaries of several full-time developers, and holds the copyright on the code, but that copyright is an Apache/BSD-style license which is fully compliant with the Debian Free Software Guidelines. In other words, you are free to download, modify, and redistribute Subversion as you please; no permission from CollabNet or anyone else is required.
Yes, absolutely. It's ready for prime-time production.
Subversion has been in development since 2000, and became self-hosting after one year. A year later when we declared "alpha", Subversion was already being used by dozens of private developers and shops for real work. After that, it was two more years of bugfixing and stabilization until we reached 1.0. Most other projects probably would have called the product "1.0" much earlier, but we deliberately decided to delay that label as long as possible. We were aware that many people were waiting for a 1.0 before using Subversion, and had very specific expectations about the meaning of that label. So we stuck to that same standard.
The client and server are designed to work as long as they aren't more than one major release version apart. For example, any 1.X client will work with a 1.Y server. However, if the client and server versions don't match, certain features may not be available.
See the client/server interoperability policy is documented in the "Compatibility" section of the Hacker's Guide to Subversion.
All modern flavors of Unix, Win32, BeOS, OS/2, MacOS X.
Subversion is written in ANSI C and uses APR, the Apache Portable Runtime library, as a portability layer. The Subversion client will run anywhere APR runs, which is most places. The Subversion server (i.e., the repository side) is the same, except that it will not host a Berkeley DB repository on Win9x platforms (Win95/Win98/WinME), because Berkeley DB has shared-memory segment problems on Win9x. FSFS repositories (introduced in version 1.1) do not have this restriction; however, due to a limitation in Win9x's file-locking support, they also don't work in Win9x.
To reiterate, the Subversion client can be run on any platform where APR runs. The Subversion server can also be run on any platform where APR runs, but cannot host a repository on Win95/Win98/WinMe.
No. The "Subversion Filesystem" is not a kernel-level filesystem that one would install in an operating system. Instead, it is Subversion's repository interface, which is a "versioned filesystem" in the sense that it stores a directory tree whose state is remembered from revision to revision. Writing programs to access the repository is similar to writing programs that use other filesystem APIs. The main difference is that this particular filesystem doesn't lose data when written to; old tree states can be retrieved as easily the most recent state.
Server requirements depend on many factors, such as number of users, frequency of commits and other server related operations, repository size, and the load generated by custom repository hooks. When using Apache, it is likely that Apache itself will be the biggest factor in memory usage. See this discussion on the mailing list for some concrete answers.
Remember to take in account other applications running on the same server; for example, repository browsers use resources too, independently of Subversion itself.
In general, you can expect to need much less server memory than you would for comparable CVS repositories.
No. Subversion is a set of libraries. It comes with a command-line client that uses them. There are two different Subversion server processes: either svnserve, which is small standalone program similar to cvs pserver, or Apache httpd-2.0 using a special mod_dav_svn module. svnserve speaks a custom protocol, while mod_dav_svn uses WebDAV as its network protocol. See chapter 6 in the Subversion book to learn more.
The short answer: no.
The long answer: if you just want to access a repository, then you only need to build a Subversion client. If you want to host a networked repository, then you need to set up either Apache2 or an "svnserve" server.
For more details about setting up a network accessible Subversion server, see chapter 6 in the Subversion book.
No, you can run svnserve as a Subversion server. It works extremely well.
If you want WebDAV and all the other "goodies" that come with the Apache server, then yes, you'll need Apache 2.0. It's always an option to run Apache 2.0 on a different port while continuing to run Apache 1.x on port 80. Different versions of Apache can happily coexist on the same machine. Just change the Listen directive in httpd.conf from "Listen 80" to "Listen 8080" or whatever port number you want, and make sure to specify that port when you publish your repository URL (e.g., http://svn.mydomain.com:8080/repos/blah/trunk/).
We aren't attempting to break new ground in SCM systems, nor are we attempting to imitate all the best features of every SCM system out there. We're trying to replace CVS. See the first question.
The global revision number attached to the repository as a whole is meaningless from a user's perspective. It's an internal mechanism that accomplishes the goal of the underlying schema design. It just so happens to be exposed so that the user's interface can sometimes be a little more convenient than always having to type obnoxiously long date/time strings.
The revision number is only relevant to the repository, and user convenience. It has no impact on any other factor of what you store in the repository. Repository revision number bumps aren't nearly useful enough to be an accurate indication of the real rate of change of a given code base. There are other more complicated ways to get a much better picture of a code-base's rate of change.
The question is a bit loaded, because everyone seems to have a slightly different definition of "changeset", or a least a slightly different expectation of what it means for a version control system to have "changeset features".
For the purposes of this discussion, here's a simple definition of changeset: it's a collection of changes with a unique name. The changes might include textual edits to file contents, modifications to tree structure, or tweaks to metadata. In more common speak, a changeset is just a patch with a name you can refer to.
Subversion manages versioned trees as first order objects (the repository is an array of trees), and the changesets are things that are derived (by comparing adjacent trees.) Systems like Arch or Bitkeeper are built the other way around: they're designed to manage changesets as first order objects (the repository is a bag of patches), and trees are derived by composing sets of patches together.
Neither philosophy is better in absolute terms: the debate goes back at least 30 years. The two designs are better or worse for different types of software development. We're not going to discuss that here. Instead, here's an explanation of what you can do with Subversion.
In Subversion, a global revision number 'N' names a tree in the repository: it's the way the repository looked after the Nth commit. It's also the name of an implicit changeset: if you compare tree N with tree N-1, you can derive the exact patch that was committed.
For this reason, it's easy to think of "revision N" as not just a tree, but a changeset as well. If you use an issue tracker to manage bugs, you can use the revision numbers to refer to particular patches that fix bugs -- for example, "this issue was fixed by revision 9238." Somebody can then run 'svn log -r9238' to read about the exact changeset which fixed the bug, and run 'svn diff -r9237:9238' to see the patch itself. And svn's merge command also uses revision numbers. You can merge specific changesets from one branch to another by naming them in the merge arguments: 'svn merge -r9237:9238 branchURL' would merge changeset #9238 into your working copy.
This is nowhere near as complicated as a system built around changesets as primary objects, but it's still a vast convenience over CVS.
See our status page, http://subversion.tigris.org/project_status.html.
Subversion 1.1 (and later) has the ability to put a symlink under version control, via the usual svn add command.
Details: the Subversion repository has no internal concept of a symlink. It stores a "versioned symlink" as an ordinary file with an 'svn:special' property attached. The svn client (on unix) sees the property and translates the file into a symlink in the working copy. Win32 has no symlinks, so a win32 client won't do any such translation: the object appears as a normal file.
Vectorized versions of the Subversion logo are available in the logo directory of the www tree of the Subversion repository.
Specifically, an EPS version, as well as an Adobe Illustrator document are available.
If you don't find an answer after browsing this FAQ, there are several other resources available:
Our mailing lists are moderated to prevent spam from getting through, so your first post to any list may be delayed, until the moderator has a chance to let it through. Once that post is allowed through, all subsequent posts from the same address are automatically approved, so you should experience no more delay. Of course, if your sending address changes, then you'll have to go through moderation again.
Use the subversion client:
$ svn co http://svn.collab.net/repos/svn/trunk subversion
That will check out a copy of the Subversion source tree into a directory named subversion on your local machine.
See http://svn.collab.net/repos/svn/trunk/README; specifically, look at section IV, the "Quickstart Guide".
For even more detail, read chapter 5 in The Subversion Book.
Members of the Subversion development community created and maintain a tool called cvs2svn. You can find it at http://cvs2svn.tigris.org/. Be sure to read the cvs2svn documentation.
If cvs2svn.py does not work for you, (e.g. your repository causes it to crash, or it doesn't deal with branches and tags quite how you would like), there are at least two other conversion utilities you can try. These have different features (and possibly different bugs):
See also the Subversion links page.
The Subversion client can go through a proxy, if you configure it to do so. First, edit your "servers" configuration file to indicate which proxy to use. The files location depends on your operating system. On Linux or Unix it is located in the directory "~/.subversion". On Windows it is in "%APPDATA%\Subversion". (Try "echo %APPDATA%", note this is a hidden directory.)
There are comments in the file explaining what to do. If you don't have that file, get the latest Subversion client and run any command; this will cause the configuration directory and template files to be created.
Older versions of Subversion, including the 0.14.3 bootstrap tarball, use the file ~/.subversion/proxies to define the proxy settings. This file is ignored by the current version of Subversion.
Next, you need to make sure the proxy server itself supports all the HTTP methods Subversion uses. Some proxy servers do not support these methods by default: PROPFIND, REPORT, MERGE, MKACTIVITY, CHECKOUT. In general, solving this depends on the particular proxy software. For Squid, the config option is
# TAG: extension_methods # Squid only knows about standardized HTTP request methods. # You can add up to 20 additional "extension" methods here. # #Default: # none extension_methods REPORT MERGE MKACTIVITY CHECKOUT
(Squid 2.4 and later already knows about PROPFIND.)
See also "What are all the HTTP methods Subversion uses?" for advice on additional HTTP methods to allow through your proxy.
If it's difficult or impossible to get the proxy to allow Subversion traffic, but you want to check out the Subversion sources, you may be able to go around the proxy. Some proxies that filter port 80 nevertheless allow anything on port 81. For this reason, the svn.collab.net repository server listens on port 81 as well as on port 80. Try:
svn checkout http://svn.collab.net:81/repos/svn/trunk subversion
and maybe the proxy will let you through. Another strategy is to attempt the checkout over SSL, which many proxies allow:
svn checkout https://svn.collab.net/repos/svn/trunk subversion
Of course, your svn client will have to have been built with ssl support; just pass --with-ssl to subversion's ./configure script. You can check to see whether the 'https' scheme is supported by running svn --version.
A simple option is to use the svnserve server instead of Apache. See chapter 6 in the Subversion book for details.
However, if your admins don't want you to run Apache, it's very likely they don't want you to run a custom server process on port 3690 either! So the rest of this answer assumes that your admins are okay with you using an existing SSH infrastructure.
If you previously used CVS, you may have used SSH to login to the CVS server. The ra_svn Subversion access method is the equivalent way of doing this with Subversion. Just use the "svn+ssh" prefix to your Subversion repository URL.
$ svn checkout svn+ssh://your.domain.com/full/path/to/repository
This makes your SSH program launch a private 'svnserve' process on the remote box, which accesses the repository as your UID and tunnels the information back over the encrypted link.
However, another solution that can be used instead is to leverage SSH port forwarding to connect to the protected server via ra_dav. You would connect via SSH to a machine behind your firewall that can access your Subversion server. Note that this SSH server does not have to be the same as where Subversion is installed. It can be, but it doesn't have to be.
Then, you create a local port forward that connects to the HTTP server that houses your Subversion repository. You would then 'connect' to the Subversion repository via this local port. Then, the request will be sent 'tunneled' via SSH server to your Subversion server.
An example: a Subversion ra_dav setup is behind your company firewall at 10.1.1.50 (call it svn-server.example.com). Your company allows SSH access via publicly accessible ssh-server.example.com. Internally, you can access the Subversion repository via http://svn-server.example.com/repos/ours.
Example: client connecting to ssh-server with port-forwarding and checking out via the port forward
% ssh -L 8888:svn-server.example.com:80 me@ssh-server.example.com % svn checkout http://localhost:8888/repos/ours
Note that your svn-server.example.com could also have its httpd instance running on an unprivileged port by a non-trusted user. This will allow your Subversion server not to require root access.
Joe Orton notes
The server is sensitive to the hostname used in the Destination header in MOVE and COPY requests, so you have to be a little careful here - a "ServerAlias localhost" may be required to get this working properly.
Some links on SSH port forwarding
It depends upon the projects involved. If the projects are related, and are likely to share data, then it's best to create one repository with several subdirectories like this:
$ svnadmin create /repo/svn $ svn mkdir file:///repo/svn/projA $ svn mkdir file:///repo/svn/projB $ svn mkdir file:///repo/svn/projC
If the projects are completely unrelated, and not likely to share data between them, then it's probably best to create separate and unrelated repositories.
$ mkdir /repo/svn $ svnadmin create /repo/svn/projA $ svnadmin create /repo/svn/projB $ svnadmin create /repo/svn/projC
The difference between these two approaches is this (as explained by Ben Collins-Sussman <sussman@collab.net>):
If you don't care about retaining all the history of one of the repositories, you can just create a new directory under one project's repository, then import the other.
If you care about retaining the history of both, then you can use 'svnadmin dump' to dump one repository, and 'svnadmin load' to load it into the other repository. The revision numbers will be off, but you'll still have the history.
Peter Davis <peter@pdavis.cx> also explains a method using svn's equivalent to CVS modules:
As long as the merging takes place in separate directory trees, you can use svn's version of CVS modules.
Set the svn:externals property on a directory to checkout directories from other repositories whenever the original directory is checked out. The repository remains separate, but in the working copy it appears that they have been merged. If you commit to the imported directory, it will affect the external repository.
The merge isn't completely clean: the import only affects working copies, so you won't be able to use a URL in the first repository to access modules imported from the second. They remain separate URLs.
If you are using a repository with the Berkeley DB back end (default for repositories created with Subversion 1.0 and 1.1, not the default thereafter), do not access the repository via NFS. Berkeley DB does not support storage of databases on remote file systems. Some NFS servers claim that they explicitly support use of Berkeley DB on NFS-mounted partitions, but we've only ever seen Berkeley DB databases get corrupted when living on an NFS or SMB network drive.
If you are using the FSFS repository back end, then storing the repository on a modern NFS server (i.e., one that supports locking) should be fine.
Working copies can be stored on NFS (one common scenario is when your home directory is on a NFS server). On Linux NFS servers, due to the volume of renames used internally in Subversion when checking out files, some users have reported that 'subtree checking' should be disabled (it's enabled by default). Please see NFS Howto Server Guide and exports(5) for more information on how to disable subtree checking.
We've had at least one report of working copies getting wedged after being accessed via SMB. The server in question was running a rather old version of Samba (2.2.7a). The problem didn't recur with a newer Samba (3.0.6).
The repository stores all your data in a Berkeley DB "environment" in the repos/db/ subdirectory. The environment contains a collection of tables and bunch of logfiles (log.*). Berkeley DB journals all changes made to the tables, so that the tables can be recovered to a consistent state in case of interruptions (more info).
The logfiles will grow forever, eating up disk space, unless you, (as the repository administrator) do something about it. At any given moment, Berkeley DB is only using a few logfiles actively (see this post and its associated thread); the rest can be safely deleted. If you keep all the logfiles around forever, then in theory Berkeley DB can replay every change to your repository from the day it was born. But in practice, if you're making backups, it's probably not worth the cost in disk space.
Use svnadmin
to see
which log files can be deleted. You may want a cron job to do this.
$ svnadmin list-unused-dblogs /repos /repos/db/log.000003 /repos/db/log.000004 [...] $ svnadmin list-unused-dblogs /repos | xargs rm # disk space reclaimed!
You could instead use Berkeley DB's db_archive
command:
$ db_archive -a -h /repos/db | xargs rm # disk space reclaimed!
See also svnadmin hotcopy
or hotbackup.py
.
Note: If you use Berkeley DB 4.2, Subversion will
create new repositories with automatic log file removal enabled. You
can change this by passing the --bdb-log-keep
option to
svnadmin create
. Refer to the section about the
DB_LOG_AUTOREMOVE
flag in the Berkeley DB manual.
Try to have as few users access the repository as possible. For example, run apache or 'svnserve -d' as a specific user, and make the repository wholly owned by that user. Don't allow any other users to access the repository via file:/// urls, and be sure to run 'svnlook' and 'svnadmin' only as the user which owns the repository.
If your clients are accessing via file:/// or svn+ssh://, then there's no way to avoid access by multiple users. In that case, read the last section in chapter 6, and pay particular attention to the "checklist" sidebar at the bottom. It outlines a number of steps to make this scenario safer.
Note for SELinux / Fedora Core 3+ / Red Hat Enterprise users:In addition to regular Unix permissions, under SELinux every file, directory, process, etc. has a 'security context'. When a process attempts to access a file, besides checking the Unix permissions the system also checks to see if the security context of the process is compatible with the security context of the file.
Fedora Core 3, among other systems, comes with SELinux installed by default, configured so that Apache runs in a fairly restricted security context. To run Subversion under Apache, you have to set the security context of the repository to allow Apache access (or turn off the restrictions on Apache, if you think all this is overkill). The chcon command is used to set the security context of files (similarly to how the chmod sets the traditional Unix permissions). For example, one user had to issue this command
$ chcon -R -h -t httpd_sys_content_t PATH_TO_REPOSITORY
to set the security context to be able to successfully access the repository.
Certain client operations are "read-only", like checkouts and updates. From an access-control standpoint, Apache treats them as such. But libsvn_fs (the repository filesystem API) still has to write temporary data in order to produce tree-deltas. So the process accessing the repository always requires both read and write access to the Berkeley DB files in order to function.
In particular, the repository responds to many "read-only" operations by comparing two trees. One tree is the usually the HEAD revision, and the other is often a temporary transaction-tree -- thus the need for write access.
This limitation only applies to the Berkeley DB backend; the FSFS backend does not exhibit this behaviour.
There are special cases where you might want to destroy all evidence of a file or commit. (Perhaps somebody accidentally committed a confidential document.) This isn't so easy, because Subversion is deliberately designed to never lose information. Revisions are immutable trees which build upon one another. Removing a revision from history would cause a domino effect, creating chaos in all subsequent revisions and possibly invalidating all working copies.
The project has plans, however, to someday implement an svnadmin obliterate command which would accomplish the task of permanently deleting information. (See issue 516.)
In the meantime, your only recourse is to svnadmin dump your repository, then pipe the dumpfile through svndumpfilter (excluding the bad path) into an svnadmin load command. See chapter 5 of the Subversion book for details about this.
Log messages are kept in the repository as properties attached to each revision. By default, the log message property (svn:log) cannot be edited once it is committed. That is because changes to revision properties (of which svn:log is one) cause the property's previous value to be permanently discarded, and Subversion tries to prevent you from doing this accidentally. However, there are a couple of ways to get Subversion to change a revision property.
The first way is for the repository administrator to enable revision property modifications. This is done by creating a hook called "pre-revprop-change" (see this section in the Subversion book for more details about how to do this). The "pre-revprop-change" hook has access to the old log message before it is changed, so it can preserve it in some way (for example, by sending an email). Once revision property modifications are enabled, you can change a revision's log message by passing the --revprop switch to svn propedit or svn propset, like either one of these:
$ svn propedit -r N --revprop svn:log URL $ svn propset -r N --revprop svn:log "new log message" URL
where N is the revision number whose log message you wish to change, and URL is the location of the repository. If you run this command from within a working copy, you can leave off the URL.
The second way of changing a log message is to use svnadmin setlog. This must be done by referring to the repository's location on the filesystem. You cannot modify a remote repository using this command.
$ svnadmin setlog REPOS_PATH -r N FILE
where REPOS_PATH is the repository location, N is the revision number whose log message you wish to change, and FILE is a file containing the new log message. If the "pre-revprop-change" hook is not in place (or you want to bypass the hook script for some reason), you can also use the --bypass-hooks option. However, if you decide to use this option, be very careful. You may be bypassing such things as email notifications of the change, or backup systems that keep track of revision properties.
FIRST, read the Hacker's Guide to Subversion.
Once you've digested that, send a mail to the dev list with the word [PATCH] and a one-line description in the subject, and include the patch inline in your mail (unless your MUA munges it up totally). Then a committer will pick it up, apply it (making any formatting or content changes necessary), and check it in.
The basic process looks like this:
$ svn co http://svn.collab.net/repos/svn/trunk subversion $ cd subversion/www [ make changes to faq.html ] $ svn diff faq.html > /tmp/foo $ Mail -s "[PATCH] FAQ updates" < /tmp/foo
Of course, the email you send should contain a nice long explanation about what the patch does, as per the Hacker's Guide to Subversion, but you already know that, since you read and completely understood it before actually hacking the code, right? :)
Suppose, for example, that you wanted to put some of /etc under version control inside your repository:
# svn mkdir file:///root/svn-repository/etc \ -m "Make a directory in the repository to correspond to /etc" # cd /etc # svn checkout file:///root/svn-repository/etc . # svn add apache samba alsa X11 # svn commit -m "Initial version of my config files"
This takes advantage of a not-immediately-obvious feature of svn checkout: you can check out a directory from the repository directly into an existing directory. Here, we first make a new empty directory in the repository, and then check it out into /etc, transforming /etc into a working copy. Once that is done, you can use normal svn add commands to select files and subtrees to add to the repository.
There is an issue filed for enhancing svn import to be able to convert the imported tree to a working copy automatically; see issue 1328.
Subversion's repository database schema has changed occasionally during development. Old repositories, created with a pre-1.0 development version of Subversion, may require the following operation when upgrading. If a schema change happens between Subversion releases X and Y, then repository administrators upgrading to Y must do the following:
See http://svnbook.red-bean.com/html-chunk/ch05s03.html#svn-ch-5-sect-3.4 for more details on dumping and loading.
Note: Most upgrades of Subversion do not involve a dump and load. When one is required, the release announcement and the CHANGES file for the new version will carry prominent notices about it. If you don't see such a notice, then there has been no schema change, and no dump/load is necessary.
TortoiseSVN has an excellent document that describes setting up a Subversion server on Windows. Go to http://tortoisesvn.sourceforge.net/docs/release/TortoiseSVN_en/ch03.html#tsvn-serversetup-apache-5, to see the section on SSPI authentication.
An important part of the configuration is the line:
SSPIOfferBasic On
Without this line, browsers that support SSPI will prompt for the user's credentials, but clients that do not suppport SSPI such as Subversion will not prompt. (The current release of Neon - Subversion's HTTP library - handles only basic authentication.) Because the client never asks for credentials, any action that requires authentication will fail. Adding this line tells mod_auth_sspi to use basic authentication with the client, but to use the Windows domain controller to authenticate the credentials.
We recommend that you live with ".svn" if you possibly can. However, if you are using ASP.NET under Windows, you might need to set the environment variable SVN_ASP_DOT_NET_HACK, as described here.
Or you could use a completely custom name for the administrative directory. We recommend against this, because your working copy would probably not work with Subversion clients other than the one you customized. However, if you absolutely must do this, just change this line in subversion/include/svn_wc.h from
#define SVN_WC_ADM_DIR_NAME ".svn"
to (for example)
#define SVN_WC_ADM_DIR_NAME "SVN"
then recompile your client.
This problem comes up in two situations. If you're adding files on an operating system with a case-insensitive filesystem, such as Windows, you might find you accidentally add a file with the wrong case in the filename. Alternatively, you may just decide to change the case of an existing file in the repository.
If you're working in a case-sensitive file system, this is no problem at all. Just move the file to the new name, e.g.,
svn mv file.java File.java
But this won't work in a case-insensitive operating system like Windows. In Windows you can accomplish this by copying the file somewhere temporary, deleting the file from Subversion, then adding the copy with the correct case. Or a better way is to perform a move operation with Subversion URLs. Using URLs is recommended, because it will preserve history for the file, and will take effect immediately.
Both ways will leave Windows working copies with problems, however, because Windows can still get confused when trying to update the conflicting filenames. (You'll get a message like svn: Failed to add file 'File.java': object of the same name already exists). One way of fixing the problem is to delete your working copy and check out again. If you do not want to do this, you must perform a two step update.
For each file with the wrong case, the following command will change the case:
svn mv svn://svnserver/path/to/file.java svn://svnserver/path/to/File.java
To update the working copy, change to the relevant directory and do:
svn update file.java svn update
The first update will remove file.java from your working copy, the second update will add File.java, leaving you with a correct working copy. Or if you had a lot of problematic files, you can update the working copy this way:
svn update * svn update
As you can see, adding a file with the wrong case is tricky to fix on an operating system that has a case insensitive filesystem. Do try to get it right when you add the file the first time! To prevent the problem from occurring in the first place, you can create a pre-commit hook that calls the file check-case-insensitive.pl. That file lives in the Subversion source tarball, in the directory contrib/hook-scripts.
As shown below it is possible to merge from a branch to the trunk without remembering one revision number. Or vice versa (not shown in the example).
The example below presumes an existing repository in /home/repos in which you want to start a branch named bar containing a file named foo you are going to edit.
For the purpose of tracing branch merges, this repository has set up tags/branch_traces/ to keep tags.
# setup branch and tags $ svn copy file:///home/repos/trunk \ file:///home/repos/branches/bar_branch \ -m "start of bar branch" $ svn copy file:///home/repos/branches/bar_branch \ file:///home/repos/tags/branch_traces/bar_last_merge \ -m "start" # checkout branch working copy $ svn checkout file:///home/repos/branches/bar_branch wc $ cd wc # edit foo.txt file and commit $ echo "some text" >>foo.txt $ svn commit -m "edited foo" # switch to trunk and merge changes from branch $ svn switch file:///home/repos/trunk $ svn merge file:///home/repos/tags/branch_traces/bar_last_merge \ file:///home/repos/branches/bar_branch # Now check the file content of 'foo.txt', it should contain the changes. # commit the merge $ svn commit -m "Merge change X from bar_branch." # finally, update the trace branch to reflect the new state of things $ svn delete -m "Remove old trace branch in preparation for refresh." \ file:///home/repos/tags/branch_traces/bar_last_merge $ svn copy file:///home/repos/branches/bar_branch \ file:///home/repos/tags/branch_traces/bar_last_merge \ -m "Reflect merge of change X."
Subversion increments the revision number of the repository as a whole, so it can't expand any keyword to be that number - it would have to search and possibly modify every file in your working copy on every update and commit.
The information you want (the revision of your working copy) is available from the command svnversion; it gives you information on the revision level of a working copy given a path (see svnversion --help for details).
You can incorporate it into your build or release process to get the information you need into the source itself. For example, in a build environment based on GNU make, add something like this to your Makefile:
## ## To use this, in yourfile.c do something like this: ## printf("this program was compiled from SVN revision %s\n",SVN_REV); ## SVNDEF := -D'SVN_REV="$(shell svnversion -n .)"' CFLAGS := $(SVNDEF) ... continue with your other flags ...
(Note that this will not work on non-GNU versions of make. Don't use it if your build process needs to be portable.)
Or try this recipe:
## ## on every build, record the working copy revision string ## svn_version.c: FORCE echo -n 'const char* svn_version(void) { const char* SVN_Version = "' \ > svn_version.c svnversion -n . >> svn_version.c echo '"; return SVN_Version; }' >> svn_version.c ## ## Then any executable that links in svn_version.o will be able ## to call the function svn_version() to get a string that ## describes exactly what revision was built. ##
Windows users may want to use SubWCRev.exe, available from the TortoiseSVN download page; it replaces all $WCREV$ tags in a given file with the current working copy revision.
No. There is no equivalent for the $Log$ keyword in CVS. If you want to retrieve a log for a specific file, you can run 'svn log your-file-name' or 'svn log url-to-your-file'. From the mailing list some explanations why $Log$ is bad:
"$Log$ is a total horror the moment you start merging changes between branches. You're practically guaranteed to get conflicts there, which -- because of the nature of this keyword -- simply cannot be resolved automatically."
And:
Subversion log messages are mutable, they can be changed by setting the svn:log revision property. So the expansion of $Log:$ in any given file could be out of date. Update may well need to retrieve the appropriate log message for each occurrence of the $Log:$ keyword, even if the file that contained it was not otherwise updated.
I don't care about that. I want to use it anyway. Will you implement it?
No. There are no plans to implement it ourselves or accept patches which implement this feature. If you want to distribute your files with some kind of changelog included, you might be able to work around this limitation in your build system.
The answer is: don't put that file under version control. Instead, put a template of the file under version control, something like "file.tmpl".
Then, after the initial 'svn checkout', have your users (or your build system) do a normal OS copy of the template to the proper filename, and have users customize the copy. The file is unversioned, so it will never be committed. And if you wish, you can add the file to its parent directory's svn:ignore property, so it doesn't show up as '?' in the 'svn status' command.
ssh has its own passphrases and its own authentication-caching scheme. Its auth caching is external to Subversion, and must be set up independently of Subversion.
OpenSSH includes ssh-keygen to create the keys, ssh-agent to cache passphrases, and ssh-add to add passphrases to the agent's cache. A popular script to simplify usage of ssh-agent is keychain. On Windows, PuTTY is a popular alternative ssh client; see PuTTYgen to import OpenSSH keys and pageant to cache passphrases.
Setting up ssh-agent is outside the scope of this document, but a Google search for "ssh-agent" will quickly get you answers. Or if you're really impatient, try one of these:
http://www.csua.berkeley.edu/ssh-howto.html http://mah.everybody.org/docs/ssh http://kimmo.suominen.com/docs/ssh/
Note: this all assumes you're using OpenSSH. There are other ssh implementations out there, and presumably they will allow you to do something similar, but we don't yet know the details.
You've tried fiddling with their various login files, like .bash_profile, and nothing works! That's because ssh ignores those files when the subversion client invokes it. But there's no need to modify PATH; instead, you can directly give ssh the full name of the svnserve command. Here's how to do it:
For each user who needs svn+ssh access, generate a new ssh public-key pair which they will use only for subversion—not for logging in normally. Have them give the keypair a distinctive name, like ~/.ssh/id_dsa.subversion. Add the public part of the key to their ~/.ssh/authorized_keys file on the server machine, after first inserting a bit of magic at the beginning of the line before the word ssh-rsa or ssh-dss, like this:
before |
---|
ssh-dss AAAAB3Nblahblahblahblah |
after |
command="/opt/subversion/bin/svnserve -t" ssh-dss AAAAB3Nblahblahblahblah |
Obviously, replace /opt/subversion/bin/svnserve with whatever is appropriate for your system. You also might want to specify the full path to the subversion repository in the command (by using the -r option), to save your users some typing.
The command= magic causes sshd on the remote machine to invoke svnserve, even if your user tries to run some other command. See the sshd(8) man page (section AUTHORIZED_KEYS FILE FORMAT) for details.
Now when your users run the subversion client, make sure they have an SVN_SSH environment variable that "points to" the private half of their keypair, by doing something like this (for the Bourne Again shell):
SVN_SSH="ssh -i $HOME/.ssh/id_dsa.subversion" export SVN_SSH
This file discusses this topic in more detail.
See the section about hacking the ~/.ssh/authorized_keys file in the answer to this other question; ignore the stuff about getting svnserve on your PATH.
Subversion will not change a file's contents by default; you have to deliberately set the svn:eol-style or svn:keywords property on a file for that to happen. That makes Subversion a lot safer than CVS's default behavior, but with that safety comes some inconvenience.
Answering the first question: to set properties on all files already in the repository, you'll need to do it the hard way. All you can do is run svn propset on every file (in a working copy), and then svn commit. Scripting can probably help you with this.
But what about future files? Unfortunately, there's no server mechanism to automatically set properties on files being committed. This means that all of your users need to remember to set certain properties whenever they svn add a file. Fortunately, there's a client-side tool to help with this. Read about the auto-props feature in the book. You need to make sure all your users configure their clients' auto-props settings appropriately.
You could write a pre-commit hook script to reject any commit which forgets to add properties to new files (see http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/check-mime-type.pl for example). However, this approach may be overkill. If somebody forgets to set svn:eol-style, for example, it will be noticed the minute somebody else opens the file on a different OS. Once noticed, it's easy to fix: just set the property and commit.
Note: many users have asked for a feature whereby the server automatically "broadcasts" run-time settings to clients, such as auto-props settings. There's already a feature request filed for this (issue 1974), though this feature is still being debated by developers, and isn't being worked on yet.
The Subversion command line client will invoke the editor defined in the environment variable SVN_EDITOR. This environment variable is passed directly to the operating system along with the name of a temporary file used to enter/edit the log message.
Due to the fact that the SVN_EDITOR string is passed as-is to the system's command shell, spaces in the editor name, or in the path name to the editor, will not work unless the editor name is in quotes.
For example, on Windows if your editor is in
C:\Program Files\Posix Tools\bin\vi
you would
want to set the variable as follows:
set SVN_EDITOR="C:\Program Files\Posix Tools\bin\vi"
Note that there is no need to escape the quotes in the Windows
shell as they are not part of the syntax for the set
command.
On UNIX systems you would need to follow your shell's specific methods for setting the variable. For example, in a bash shell, the following should work:
SVN_EDITOR='"/usr/local/more editors/bin/xemacs"' export SVN_EDITOR
In case a command line option would be needed for the invocation
of the editor, just add that after the editor name in the SVN_EDITOR
environment variable just like you would us on the command line.
For example, if the options -nx -r
would be wanted for
the above editors, the following will provide those options:
For Windows:
set SVN_EDITOR="C:\Program Files\Posix Tools\bin\vi" -nx -r
For UNIX/bash:
SVN_EDITOR='"/usr/local/more editors/bin/xemacs" -nx -r' export SVN_EDITOR
Note that SVN_EDITOR is the Subversion specific environment variable setting for the editor selection. Subversion also supports using the more generic EDITOR variable but if you need special behaviors with Subversion it is best to use the SVN_EDITOR variable.
If it's a live repository, then the easy answer is "Whatever version of Berkeley DB you have installed". If, however, it is a repository from a backup, or some unknown source, and you have no idea which version of Berkeley DB it was made with, here's how you find out:
Run some command to view the two 4-byte integers at offsets 12 and 16 (decimal) in the highest-numbered db/log.* file in the repository. Here is an example using GNU od: "od -j12 -N8 -tx4 log.<number>". Here is an example using Mac OS X hexdump: "hexdump -s12 -n8 -x log.<number>". The first integer should be the magic number 0x00040988, which identifies the file as a Berkeley DB logfile. The second number is the log format version - match it to a Berkeley DB version using the table below:
Log format version | Berkeley DB version |
---|---|
5 (0x00000005) | 4.0 |
7 (0x00000007) | 4.1 |
8 (0x00000008) | 4.2 |
10 (0x0000000a) | 4.3 |
11 (0x0000000b) | 4.4 |
This is done all the time, and is easily accomplished by adding a post-commit hook script to your repository. Read about hook scripts in Chapter 5 of the book. The basic idea is to make the "live site" just an ordinary working copy, and then have your post-commit hook script run 'svn update' on it.
In practice, there are a couple of things to watch out for. The server program performing the commit (svnserve or apache) is the same program that will be running the post-commit hook script. That means that this program must have proper permissions to update the working copy. In other words, the working copy must be owned by the same user that svnserve or apache runs as -- or at least the working copy must have appropriate permissions set.
If the server needs to update a working copy that it doesn't own (for example, user joe's ~/public_html/ area), one technique is create a +s binary program to run the update, since Unix won't allow scripts to run +s. Compile a tiny C program:
#include <stddef.h> #include <stdlib.h> #include <unistd.h> int main(void) { execl("/usr/local/bin/svn", "svn", "update", "/home/joe/public_html/", (const char *) NULL); return(EXIT_FAILURE); }
... and then chmod +s the binary, and make sure it's owned by user 'joe'. Then in the post-commit hook, add a line to run the binary.
Also, you'll probably want to prevent apache from exporting the .svn/ directories in the live working copy. Add this to your httpd.conf:
# Disallow browsing of Subversion working copy administrative dirs. <DirectoryMatch "^/.*/\.svn/"> Order deny,allow Deny from all </DirectoryMatch>
Subversion does not support checkout of a single file, it only supports checkout of directory structures.
However, you can use 'svn cat' to export a single file. This will retrieve the file's contents, it just won't create a versioned working copy.
You don't. It's a bad idea to try.
The basic design of the working copy has two rules: (1) edit files as you please, and (2) use a Subversion client to make any tree-changes (add, delete, move, copy). If these rules are followed, the client can sucessfully manage the working copy. If renames or other rearrangements happen outside of Subversion, then the UI has been violated and the working copy might be broken. The client cannot guess what happened.
People sometimes run into this problem because they want to make version control "transparent". They trick users into using a working copy, then have a script run later that tries to guess what happened and run appropriate client commands. Unfortunately, this technique only goes a short distance. 'svn status' will show missing items and unversioned items, which the script can then automatically 'svn rm' or 'svn add'. But if a move or copy has happened, you're out of luck. Even if the script has a foolproof way of detecting these things, 'svn mv' and 'svn cp' can't operate after the action has already occurred.
In summary: a working copy is wholly under Subversion's control, and Subversion wasn't designed to be transparent. If you're looking for transparency, try setting up an apache server and using the "SVNAutoversioning" feature described in appendix C of the book. This will allow users to mount the repository as a network disk, and any changes made to the volume cause automatic commits on the server.
The svnserve binary itself cannot be installed as a Windows service, but there are a number of “service wrappers” that can do the job; for example:
There is a bit more about running svnserve as a service in the TortoiseSVN manual.
There are two steps:
Say you have a repository /svn/myrepos which is using the BDB backend and you would like to switch to using the FSFS backend:
Once you are happy that all is well with your new repository delete the old one.
To do the reverse and migrate from FSFS to BDB change the svnadmin create command to specify BDB.
When you first add or import a file into Subversion, the file is examined to determine if it is a binary file. Currently, Subversion just looks at the first 1024 bytes of the file; if any of the bytes are zero, or if more than 15% are not ASCII printing characters, then Subversion calls the file binary. This heuristic might be improved in the future, however.
If Subversion determines that the file is binary, the file receives an svn:mime-type property set to "application/octet-stream". (You can always override this by using the auto-props feature or by setting the property manually with svn propset.)
Subversion treats the following files as text:
All other files are treated as binary, meaning that Subversion will:
In all other respects, Subversion treats binary files the same as text files, e.g. if you set the svn:keywords or svn:eol-style properties, Subversion will perform keyword substitution or newline conversion on binary files.
Note that whether or not a file is binary does not affect the amount of repository space used to store changes to that file, nor does it affect the amount of traffic between client and server. For storage and transmission purposes, Subversion uses a diffing method that works equally well on binary and text files; this is completely unrelated to the diffing method used by the 'svn diff' command.
svn diff doesn't have an option to do this, but
svn log -vq -r10does exactly what you want;
svn log -vq -r123:456 | egrep '^ {3}[ADMR] ' | cut -c6- | sort | uniq
The Berkeley DB database in your repository is sensitive to interruptions. If a process accessing the database exits without "cleanly" closing the environment, then the database is left in an inconsistent state. Common causes of this include:
For most of these cases, you should run "svnadmin recover", which rewinds the repository back to a consistent state; see this question for details. Note that running out of disk space, combined with frequent checkouts or updates, can cause the repository to crash in a way where recovery is not possible (so keep backups).
Segfaults, forced killings, and running out of disk space are pretty rare. Permission problems are far more common: one process accesses the repository and accidentally changes ownership or permissions, then another process tries to access and chokes on the permissions.
The best way to prevent this is to get your repository permissions and ownership set up correctly. See here for our recommendations.
Your repository is not corrupt, nor is your data lost. If your process accesses the repository directly (mod_dav_svn, svnlook, svnadmin, or if you access a `file://' URL), then it's using Berkeley DB to access your data. Berkeley DB is a journaling system, meaning that it logs everything it is about to do before it does so. If your process is interrupted (Control-C, or segfault), then a lockfile is left behind, along with a logfile describing unfinished business. Any other process that attempts to access the database will just hang, waiting for the lockfile to disappear. To awaken your repository, you need to ask Berkeley DB to either finish the work, or rewind the database to a previous state that is known to be consistent.
WARNING: you can seriously corrupt your repository if you run recover and another process accesses the repository.
Make absolutely sure you disable all access to the repository before doing this (by shutting down Apache, removing executable permissions from 'svn'). Make sure you run this command as the user that owns and manages the database, and not as root, else it will leave root-owned files in the db directory which cannot be opened by the non-root user that manages the database, which is typically either you or your Apache process. Also be sure to have the correct umask set when you run recover, since failing to do so will lock out users that are in the group allowed to access the repository.
Simply run:
svnadmin recover /path/to/repos
Once the command has completed, check the permissions in the
db
directory of the repository.
Sometimes "svnadmin recover" doesn't work. You may see it give errors like this:
Repository lock acquired. Please wait; recovering the repository may take some time... svnadmin: DB_RUNRECOVERY: Fatal error, run database recovery svnadmin: bdb: Recovery function for LSN 175 7066018 failed on backward pass svnadmin: bdb: PANIC: No such file or directory svnadmin: bdb: PANIC: fatal region error detected; run recovery
or like this:
Repository lock acquired. Please wait; recovering the repository may take some time... svn: DB_RUNRECOVERY: Fatal error, run database recovery svn: bdb: DB_ENV->log_flush: LSN of 115/802071 past current end-of-log of 115/731460 svn: bdb: Database environment corrupt; the wrong log files may have been removed or incompatible database files imported from another environment [...] svn: bdb: changes: unable to flush page: 0 svn: bdb: txn_checkpoint: failed to flush the buffer cache Invalid argument svn: bdb: PANIC: Invalid argument svn: bdb: PANIC: fatal region error detected; run recovery svn: bdb: PANIC: fatal region error detected; run recovery [...]
In that case, try Berkeley DB's native db_recover utility (see http://www.sleepycat.com/docs/utility/db_recover.html). It usually lives in a "bin/" subdirectory of the Berkeley DB installation, for example if you installed Berkeley DB from source, it might be /usr/local/BerkeleyDB.4.2/bin/db_recover; or on systems where Berkeley DB comes prepackaged it might just be /usr/bin/db_recover. If you have multiple versions of Berkeley DB installed, make sure that the version of db_recover you use matches the version of Berkeley DB with which your repository was created.
Run db_recover with the "-c" ("catastrophic recovery") flag. You can also add "-v" for verbosity, and "-h" with an argument telling it what db environment to recover (so you don't have to cd into that directory). Thus:
db_recover -c -v -h /path/to/repos/db
Run this command as the same user that owns the repository, and again, make absolutely sure that no other processes are accessing the repository while you do this (e.g., shut down svnserve or Apache).
If you're using http:// access, "Cannot allocate memory" errors show up in the httpd error log and look something like this:
[Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] (20014) Error string not specified yet: Berkeley DB error while opening 'strings' table for filesystem /usr/local/svn/repositories/svn/db: Cannot allocate memory [Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] Could not fetch resource information. [500, #0] [Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] Could not open the requested SVN filesystem [500, #160029] [Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] (17) File exists: Could not open the requested SVN filesystem [500, #160029]
It usually means that a Berkeley DB repository has run out of database locks (this does not happen with FSFS repositories). It shouldn't happen in the course of normal operations, but if it does, the solution is to run database recovery as described here. If it happens often, you probably need to raise the default lock parameters (set_lk_max_locks, set_lk_max_lockers, and set_lk_max_objects) in the db/DB_CONFIG file. When changing DB_CONFIG in an existing repository, remember to run recovery afterwards.
Your working copy is not corrupt, nor is your data lost. Subversion's working copy is a journaling system, meaning that it logs everything it is about to do before it does so. If the svn client program is interrupted violently (segfault or killed, not with Control-C), then one or more lockfiles are left behind, along with logfiles describing unfinished business. (The `svn status' command will show an 'L' next to locked directories.) Any other process that attempts to access the working copy will fail when it sees the locks. To awaken your working copy, you need to tell the svn client to finish the work. Simply run:
svn cleanup working-copy
Three kinds of situation that can cause this:
Debris from a failed commit is littering your working copy.
You may have had a commit that went sour between the time the new revision was added in the server and the time your client performed its post-commit admin tasks (including refreshing your local text-base copy). This might happen for various reasons including (rarely) problems in the database back end or (more commonly) network dropouts at exactly the wrong time.
If this happens, it's possible that you have already committed the very changes you are trying now to commit. You can use 'svn log -rHEAD' to see if your supposed-failed commit actually succeeded. If it did, run 'svn revert' to revert your local changes, then run 'svn update' to your own changes back from the server. (Note that only 'svn update' brings your local copies up-to-date; revert doesn't do that.)
Mixed revisions.
When Subversion commits, the client only bumps the revision numbers of the nodes the commit touches, not all nodes in the working copy. This means that in a single working copy, the files and subdirectories might be at different revisions, depending on when you last committed them. In certain operations (for example, directory property modifications), if the repository has a more recent version of the node, the commit will be rejected, to prevent data loss. See The Limitations of Mixed Revisions in the Version Control with Subversion for details.
You can fix the problem by running 'svn update' in the working copy.
You might be genuinely out of date — that is, you're trying to commit a change to a file that has been changed by someone else since you last updated your copy of that file. Again, 'svn update' is the way to fix this.
Subversion uses a plugin system to allow access to repositories. Currently there are three of these plugins: ra_local allows access to a local repository, ra_dav which allows access to a repository via WebDAV, and ra_svn allows local or remote access via the svnserve server. When you attempt to perform an operation in subversion, the program tries to dynamically load a plugin based on the URL scheme. A `file://' URL will try to load ra_local, and an `http://' URL will try to load ra_dav.
The error you are seeing means that the dynamic linker/loader can't find the plugins to load. This normally happens when you build subversion with shared libraries, then attempt to run it without first running 'make install'. Another possible cause is that you ran make install, but the libraries were installed in a location that the dynamic linker/loader doesn't recognize. Under Linux, you can allow the linker/loader to find the libraries by adding the library directory to /etc/ld.so.conf and running ldconfig. If you don't wish to do this, or you don't have root access, you can also specify the library directory in the LD_LIBRARY_PATH environment variable.
See this faq.
You probably have old copies of /usr/local/bin/apr-config and /usr/local/bin/apu-config on your system. Remove them, make sure the apr/ and apr-util/ that you're building with are completely up-to-date, and try again.
It turns out that there's a small build-bug Apache httpd: not all of mod_dav's public APIs were properly declared "exportable" on Windows. And Subversion 1.2's mod_dav_svn is now using these APIs. This means that out-of-the-box, Subversion 1.2 will not compile on Windows against any released httpd sourceball.
This problem is already fixed on httpd's /trunk, and has been backported to the httpd 2.0.x branch. If you're using a released httpd source tree, you're out of luck. Until httpd-2.0.54 is released, you will need to manually apply the same patch to your httpd tree. (It's r155345 of httpd's trunk, for reference.)
Probably you just need to get the latest platform SDK. The one that ships with VC++ 6.0 is not recent enough.
Like this:
svn import file:///d:/some/path/to/repos/on/d/drive
See Repository URLs in the Subversion Book for more details.
VS.Net has a subsystem called ASP.Net, which uses WebDAV to do remote publishing through IIS. This subsystem rejects any pathname that starts with ".". This causes a problem when you try to remotely publish a Subversion working copy, because of the ".svn" subdirectories. The error message says something like "unable to read project information".
To work around this, set the environment variable SVN_ASP_DOT_NET_HACK to any value — this will tell Windows clients to use "_svn" as a directory name in your working copy. See the relevant section of the Subversion 1.3 release notes for more details, and see this question for other ways to customize the administrative directory name.
For example, one user reported that imports worked fine over local access:
$ mkdir test $ touch test/testfile $ svn import test file:///var/svn/test -m "Initial import" Adding test/testfile Transmitting file data . Committed revision 1.But not from a remote host:
$ svn import http://svn.sabi.net/test testfile -m "import" nicholas's password: xxxxxxx svn_error: #21110 : <Activity not found> The specified activity does not exist.
We've seen this when the REPOS/dav/ directory is not writable by the httpd process. Check the permissions to ensure Apache can write to the dav/ directory (and to db/, of course).
You need to install Window XP Service Pack 1. You can get all sorts of information about that Service Pack here:
Use Ethereal to eavesdrop on the conversation:
port 80
for Filter, and turn off
promiscuous mode.The above instructions are specific to the graphical version of Ethereal, and do not apply to the commandline version (whose binary is usually named tethereal).
Alternatively, you may set the neon-debug-mask parameter in your servers configuration file to cause neon's debugging output to appear when you run the svn client. The numeric value of neon-debug-mask is a combination of the NE_DBG_... values in the header file ne_utils.h. For current versions of neon, setting neon-debug-mask to 130 (i.e. NE_DBG_HTTP+NE_DBG_HTTPBODY) will cause the HTTP data to be shown.
You may well want to disable compression when doing a network trace—see the http-compression parameter in the servers configuration file.
The short answer: it's for your own good.
Subversion places a very high priority on protecting your data, and not just your versioned data. Modifications that you make to already-versioned files, and new files scheduled for addition to the version control system, must be treated with care.
Making the svn revert command require an explicit target—even if that target is just '.'—is one way of accomplishing that. This requirement (as well as requiring you to supply the --recursive (-R) flag if you want that behavior) is intended to make you really think about what you're doing, because once your files are reverted, your local modifications are gone forever.
Your apr-util linked against DB-3, and svn linked against DB-4. Unfortunately, the DB symbols aren't different. When mod_dav_svn is loaded into Apache's process-space, it ends up resolving the symbol names against apr-util's DB-3 library.
The solution is to make sure apr-util compiles against DB-4. You can do this by passing specific switches to either apr-util's or apache's configure: "--with-dbm=db4 --with-berkeley-db=/the/db/prefix".
This is not really a problem with Subversion, but it often affects Subversion users.
Red Hat 9 and Fedora ship with a Berkeley DB library that relies on the kernel support for NPTL (the Native Posix Threads Library).
The kernels that Red Hat provides have this support built in, but if you compile your own kernel, then you may well not have the NPTL support. If that is the case, then you will see errors like this:
svn: Berkeley DB error svn: Berkeley DB error while creating environment for filesystem tester/db: Function not implemented
This can be fixed in one of several ways:
LD_ASSUME_KERNEL
is set
to 2.2.5
, and if so, unset it before starting
Subversion (Apache). (You usually would set this variable to run
Wine or Winex on Red Hat 9)To use the NPTL version of Berkeley DB you also need to use a glibc library with NPTL support, which probably means the i686 version. See http://svn.haxx.se/users/archive-2004-03/0488.shtml for details.
If you allow anonymous write access to the repository via Apache, the Apache server never challenges the SVN client for a username, and instead permits the write operation without authentication. Since Subversion has no idea who did the operation, this results in a log like this:
$ svn log ------------------------------------------------------------------------ rev 24: (no author) | 2003-07-29 19:28:35 +0200 (Tue, 29 Jul 2003)
See the Subversion Book ("Networking a Repository") to learn about configuring access restrictions in Apache.
These appear to be due to the various Windows services that monitor the filesystem for changes (anti-virus software, indexing services, the COM+ Event Notification Service). This is not really a bug in Subversion, which makes it difficult for us to fix. A summary of the current state of the investigation is available here. A workaround that should reduce the incidence rate for most people was implemented in revision 7598; if you have an earlier version, please update to the latest release.
This is usually due to a lack of available entropy on the system. You probably need to configure the system to gather entropy from sources such as hard-disk and network interrupts. Consult your system manpages, specifically random(4) and rndcontrol(8) on how to effect this change.
It means your httpd.conf is misconfigured. Usually this error happens when you've defined the Subversion virtual "location" to exist within two different scopes at the same time.
For example, if you've exported a repository as <Location /www/foo>, but you've also set your DocumentRoot to be /www, then you're in trouble. When the request comes in for /www/foo/bar, apache doesn't know whether to find a real file named /foo/bar within your DocumentRoot, or whether to ask mod_dav_svn to fetch a file /bar from the /www/foo repository. Usually the former case wins, and hence the "Moved Permanently" error.
The solution is to make sure your repository <Location> does not overlap or live within any areas already exported as normal web shares.
It's also possible that you have an object in the web root which has the same name as your repository URL. For example, imagine your web server's document root is /var/www and your Subversion repository is located at /home/svn/repo. You then configure Apache to serve the repository at http://localhost/myrepo. If you then create the directory /var/www/myrepo/ this will cause a 301 error to occur.
A nice feature of Subversion is that the repository understands copies and renames, and preserves the historical connections. For example, if you copy /trunk to /branches/mybranch, then the repository understands that every file in the branch has a "predecessor" in the trunk. Running svn log --verbose will show you the historical copy, so you can see the rename:
r7932 | joe | 2003-12-03 17:54:02 -0600 (Wed, 03 Dec 2003) | 1 line Changed paths: A /branches/mybranch (from /trunk:7931)
Unfortunately, while the repository is aware of copies and renames, almost all the svn client subcommands are not aware. Commands like svn diff, svn merge, and svn cat ought to understand and follow renames, but don't yet do this. It's scheduled as post-1.0 feature, currently issue #1093. For example, if you ask svn diff to compare two earlier versions of /branches/mybranch/foo.c, the command will not automatically understand that the task actually requires comparing two versions of /trunk/foo.c, due to the rename. Instead, you'll see an error about how the branch-path doesn't exist in the earlier revisions.
The workaround for all problems of this sort is to do the legwork yourself. That is: you need to be aware of any renamed paths, discover them yourself using svn log -v, and then provide them explicitly to the svn client. For example, instead of running
$ svn diff -r 1000:2000 http://host/repos/branches/mybranch/foo.c svn: Filesystem has no item svn: '/branches/mybranch/fooc..c' not found in the repository at revision 1000...you would instead run
$ svn diff -r1000:2000 http://host/repos/trunk/foo.c ...
This is probably due to a known bug in Apache HTTP Server (versions 2.0.48 and earlier), for which a patch is available, see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25040. You may also want to read over http://subversion.tigris.org/issues/show_bug.cgi?id=1608 to see if the description there matches your symptoms.
Adding -qlanglvl=extended to the environment variable CFLAGS for configuration and build will make xlc a bit more flexible and the code should compile without error. See http://svn.haxx.se/dev/archive-2004-01/0922.shtml and its associated thread for more details.
See issue 695. The current implementation of svn checkout -N is quite broken. It results in a working copy which has missing entries, yet is ignorant of its "incompleteness". Apparently a whole bunch of CVS users are fairly dependent on this paradigm, but none of the Subversion developers were. For now, there's really no workaround other than to change your process: try checking out separate subdirectories of the repository and manually nesting your working copies.
The error message in this case is a little misleading. Most likely Apache is unable to load one or more DLLs that mod_dav_svn.so relies on. If Apache is running as a service it will not have the same PATH as a regular user. Make sure that libdb4*.dll, libeay32.dll and ssleay32.dll are present in either \Apache\bin or \Apache\modules. You can copy them from your Subversion installation directory if they are not there.
If this still does not resolve the problem, you should use a tool like Dependency Walker on mod_dav_svn.so to see if there are any other unresolved dependencies.
They're supposed to invoke external programs, but the invocations never seem to happen.
Before Subversion calls a hook script, it removes all variables -- including $PATH on Unix, and %PATH% on Windows -- from the environment. Therefore, your script can only run another program if you spell out that program's absolute name.
Debugging tips:
If you're using Linux or Unix, try running the script "by hand", by following these steps:
Note the first argument to "env" is a dash; that's what ensures the environment is empty.$ env - ./post-commit /var/lib/svn-repos 1234
When using an external diff command, subversion builds a fairly complicated command line. First is the specified --diff-cmd. Next comes the specified --extensions (although empty --extensions are ignored), or '-u' if --extensions is unspecified (or specified as ''). Third and fourth, Subversion passes a '-L' and the first file's label (e.g. "project_issues.html (revision 11209)"). Fifth and sixth are another '-L' and the second label. Seventh and eighth are the first and second file names (e.g. ".svn/text-base/project_issues.html.svn-base" and ".svn/tmp/project_issues.html.tmp").
If your preferred diff command does not support these arguments, you may need to create a small wrapper script to discard arguments and just use the last couple file paths.
Warning: Beware that Subversion does not expect the external diff program to change the files it receives, and doing so may scramble the working copy.
For further information, see issue #2044.
Calm down, take a deep breath.
First of all, notice that the directory which contains the cached passwords (usually ~/.subversion/auth/ on Unix systems) has permissions of 700, meaning only you can read them. Trust your OS to protect data on disk.
Secondly, if you're really worried, you can permanently turn off password caching. With an svn 1.0 client, just set 'store-auth-creds = no' in your run-time config file. With an svn 1.1 client or later, you can use the more narrowly-defined 'store-passwords = no' (so that server certs are still cached.)
Lastly, we point out that CVS has been caching passwords for years in the .cvspass file. It may look like the passwords in .cvspass are encrypted, but in fact they're only lightly scrambled with an algorithm that's the moral equivalent to rot13. They can be cracked instantly. The only utility of the the scrambling is to prevent users (like root) from accidentally seeing the password. Nobody's cared enough to to do this for Subversion yet; if you're interested, send patches to the dev@ list.
Berkeley DB 4.1 has shown itself to be rather unstable - both 4.0 and 4.2 are better. This error message is a symptom of one unique way in which 4.1 will sometimes break.
The problem is that the database format field for one of the tables that make up a Subversion repository using the Berkeley DB backend has become corrupted. For unknown reasons, this is almost always the 'copies' table, which switches from the 'btree' type to the 'recno' type. Simple recovery procedures are outlined below - if they do not succeed, you should contact the Subversion Users mailing list.
Early versions of APR on its 0.9 branch, which Apache 2.0.x and Subversion 1.x use, have no support for copying large files (2Gb+). A fix which solves the 'svnadmin hotcopy' problem has been applied and is included in APR 0.9.5+ and Apache 2.0.50+. The fix doesn't work on all platforms, but works on Linux.
Prior to Berkeley DB 4.3, svnadmin recover worked to upgrade a Berkeley DB repository in-place. However, due to a change in the behaviour of Berkeley DB in version 4.3, this now fails.
Use this procedure to upgrade your repository in-place to Berkeley DB 4.3 or later:
The repository is now usable by Berkeley DB 4.3.
Note: this assumes the repository is being served by Apache 2.0.x.
There is a bug in APR 0.9.6 that is present when it is running on Tiger, and shows up when you attempt to check out a file larger than 64K. The resulting checkout fails, often with unpredictable error messages. Here are some examples of what you might see on the client side, the specific errors may differ for you:
svn: Invalid diff stream: [tgt] insn 1 starts beyond the target view position
svn: Unexpected end of svndiff input
svn: REPORT request failed on '/path/to/repository' svn: REPORT of '/path/to/repository/!svn/vcc/default': Chunk delimiter was invalid
There may also be errors in the Apache error_log, such as:
[error] Provider encountered an error while streaming a REPORT response. [500, #0] [error] A failure occurred while driving the update report editor [500, #190004]
To confirm the presence of this bug — assuming you have access to the machine that the repository is being served from — try checking out using a file:// URL, which will access the filesystem directly instead of going through Apache. If the resulting checkout completes successfully, then it is almost certain that this is the problem.
Currently, the best solution is to rebuild Apache and Subversion from their respective sources, setting the following environment variable before running configure for Apache:
setenv ac_cv_func_poll no
or in Bourne shell syntax, like this:
ac_cv_func_poll=no; export ac_cv_func_poll
If you built APR / APRUTIL separately (i.e., you did not use the ones that come as part of the Apache tarball), you must set that environment variable before running configure for APR, as this is where the problem lies.
If you see errors like this in the final link stage of a Subversion trunk source build:
/usr/local/apache2/lib/libaprutil-0.so.0: undefined reference to `db_create' /usr/local/apache2/lib/libaprutil-0.so.0: undefined reference to `db_strerror'
it might be because you're on a Debian GNU/Linux system and need to upgrade 'libtool'. (I've also heard that the Debian packagers had to tweak 'libtool' and that this may cause some problems for Subversion builds. But that's hearsay — I didn't have time to verify the details before writing this FAQ entry. However, see http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=112617 and the thread it spawned for a detailed discussion.)
In any case, after encountering this problem on a Debian GNU/Linux system running a newly-dist-upgraded 'testing' distribution on 15 Nov 2005, the solution was to build libtool 1.5.20 from source, using the standard "./configure && make && sudo make install" recipe. After that, I did a 'make clean' in my Subversion working copy tree, './autogen.sh', './configure', 'make', and everything worked fine.
Note that another report of these symptoms appeared at http://svn.haxx.se/dev/archive-2003-01/1125.shtml, though the solution described here was not mentioned in that thread.
Test execution can be dramatically sped up by keeping Subversion test data on a RAM disk. On a Linux system, add lines like the following in your /etc/fstab file:
tmpfs /home/brane/svn/obj-sh/subversion/tests tmpfs defaults,user,noauto,exec,size=64m
tmpfs /home/brane/svn/obj-st/subversion/tests tmpfs defaults,user,noauto,exec,size=64m
The minimum required size for testing ramdisk is approximately 700MB. However, flagging your test targets for cleanup dramatically reduces the space requirements (as shown in the example configuration above), and thus your memory usage. Cleanup means more I/O, but since test data is in-memory, there will be no performance degradation. Example:
make check CLEANUP=true
See http://svn.haxx.se/dev/archive-2003-02/0068.shtml for the original authoritative discussion on use of RAM disks.
The Subversion client speaks a subset the WebDAV/DeltaV protocol to the mod_dav_svn server module. The short answer is:
OPTIONS, PROPFIND, GET, REPORT, MKACTIVITY, PROPPATCH, PUT, CHECKOUT, MKCOL, MOVE, COPY, DELETE, LOCK, UNLOCK, MERGE
The details of the protocol are documented here:
http://svn.collab.net/repos/svn/trunk/subversion/libsvn_ra_dav/protocolSee Poul-Henning Kamp's post to freebsd-hackers: http://www.freebsd.org/doc/en_US.ISO8859-1/books/faq/misc.html#BIKESHED-PAINTING.
Jim Blandy, who gave Subversion both its name and repository design, pronounces "Subversion" "Subversion".
Throughout subversion's source code there are many references to 'baton' objects. These are just void * datastructures that provide context to a function. In other APIs, they're often called void *ctx or void *userdata Subversion developers call the structures "batons" because they're passed around quite a bit.
corrupted repository:A Subversion repository consists of two different internal parts, a working compartment and a storage compartment. A wedged repository is a repository where the working compartment is unaccessible for some reason, but the storage compartment is intact. Therefore, a wedged repository has not suffered any loss of data, but the working compartment has to be corrected before you can access the repository. See this entry for details how to do that.
A corrupted Subversion repository is a repository where the storage compartment has been damaged, and therefore there is some degree of real data loss in the repository.
You might also like to check The Jargon File's definition for 'wedged'.