wiki
Wiki: Subversion Client FAQ

Edit this page | Links to this page | Page information | Attachments | Refresh page

 


CollabNet Subversion Client FAQ

Subversion Server FAQ -- FAQ Index -- Find Page -- Community Home

This FAQ was created by the Subversion open source community and CollabNet.


Contents

  1. General questions
    1. What is the difference between CollabNet Subversion and Subversion?
    2. Common SVN Error Messages
    3. What is Subversion's client/server interoperability policy?
    4. What operating systems does Subversion run on?
    5. Why does the entire repository share the same revision number? I want each of my projects to have their own revision numbers.
    6. Does Subversion have Changesets?
    7. Does Subversion support symlinks?
  2. How-to
    1. How do I check out the Subversion code?
    2. How do I create a repository? How do I import data into it?
    3. What if I'm behind a proxy?
    4. How do I merge code from two completely separate repositories?
    5. How can I do an in-place 'import' (i.e. add a tree to Subversion such that the original data becomes a working copy directly)?
    6. I can't use tags to merge changes from a branch into the trunk like I used to with CVS, can I?
    7. Why doesn't the $Revision$ keyword do what I want? It expands to the file's last-changed revision, but I want something that will expand to the file's current revision.
    8. Does Subversion have a keyword which behaves like $Log$ in CVS?
    9. When I access a repository using svn+ssh, my password is not cached in ~/.subversion/auth/. How do I avoid having to type it so often?
    10. How can I set certain properties on everything in the repository? Also, how can I make sure that every new file coming into the repository has these properties?
    11. How do I deal with spaces in the editor path? Also, how can I define command line options for the editor?
    12. I'm managing a website in my repository. How can I make the live site automatically update after every commit?
    13. How do I check out a single file?
    14. How do I detect adds, deletes, copies and renames in a working copy after they've already happened?
    15. How does Subversion handle binary files?
    16. How can I make svn diff show me just the names of the changed files, not their contents?
    17. How can I maintain a modified version (a "vendor branch") of third-party software using Subversion?
  3. Troubleshooting
    1. Every time I try to run a svn command, it says my working copy is locked. Is my working copy corrupt?
    2. I've contributed a patch to a project and the patch added a new file. Now svn update does not work.
    3. I just built the distribution binary, and when I try to check out Subversion, I get an error about an "Unrecognized URL scheme." What's up with that?
    4. I'm having trouble doing write operations to a Subversion repository over a network.
    5. Why does the svn revert require an explicit target? Why is it not recursive by default? These behaviors differ from almost all the other subcommands.
    6. I'm getting occasional "Access Denied" errors on Windows. They seem to happen at random. Why?
    7. I can see my repository in a web browser, but 'svn checkout' gives me an error about "301 Moved Permanently". What's wrong?
    8. I'm trying to look at an old version of my file, but svn says something about "path not found". What's going on?
    9. I checked out a directory non-recursively (with -N), and now I want to make certain subdirectories "appear". But svn up subdir doesn't work.
    10. Why does my --diff-cmd complain about '-u'? I tried to override it with --extensions, but it's not working.
    11. I just discovered that my Subversion client is caching passwords in plain-text on disk
    12. I cannot see the log entry for the file I just committed. Why?
    13. Why do I get occasional, seemingly inconsistent errors when checking out over from a repository running on MacOS X 10.4 (Tiger)?
    14. I can't add a directory because Subversion says it's "already under version control".
    15. When performing Subversion operations involving a lot of data over SSL, I get the error SSL negotiation failed: SSL error: decryption failed or bad record mac.
    16. I get an error that says "This client is too old".
    17. Why doesn't svn switch work in some cases?
    18. In Windows, when doing an update with the command-line client, I get an error saying "The system cannot find the path specified" and suggesting that my working copy might be corrupt. But I can update with TortoiseSVN just fine. What's going on?
    19. I got an error saying "This client is too old to work with working copy '...' ". How can I fix it without upgrading Subversion?


General questions

What is the difference between CollabNet Subversion and Subversion?

CollabNet Subversion is a distribution of Subversion with added-value:

  • CollabNet-certified binaries for Windows, Linux and Solaris

  • Separate server and client installers to make distribution inside your company easier
  • CollabNet-supported IDE integrations

  • CollabNet Integrations such as connectors to HP Mercury Quality Center and IBM Rational ClearCase

  • Enterprise-grade support, training and consulting services

CollabNet Subversion provides a unified environment to successfully deploy Subversion at our company. Because our support staff is very familiar with the CollabNet Subversion distribution, CollabNet offers a discount on support contracts for CollabNet Subversion.

The binaries of CollabNet Subversion are compiled from the open source code and are compatible with other Subversion binaries.


Common SVN Error Messages

See the separate wiki page Common SVN Error Messages.


What is Subversion's client/server interoperability policy?

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.


What operating systems does Subversion run on?

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.


Why does the entire repository share the same revision number? I want each of my projects to have their own revision numbers.

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.


Does Subversion have Changesets?

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.


Does Subversion support symlinks?

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.


How-to

How do I check out the Subversion code?

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.


How do I create a repository? How do I import data into it?

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.


What if I'm behind a proxy?

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.

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.


How do I merge code from two completely separate repositories?

Check this blog post.


How can I do an in-place 'import' (i.e. add a tree to Subversion such that the original data becomes a working copy directly)?

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.


I can't use tags to merge changes from a branch into the trunk like I used to with CVS, can I?

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."


Why doesn't the $Revision$ keyword do what I want? It expands to the file's last-changed revision, but I want something that will expand to the file's current revision.

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:

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:

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

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.


Does Subversion have a keyword which behaves like $Log$ in CVS?

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.


When I access a repository using svn+ssh, my password is not cached in ~/.subversion/auth/. How do I avoid having to type it so often?

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:

My svnserve binary is in a directory that isn't on my users' default PATHs, they use svn+ssh, and I can't figure out how to modify their PATH so that they can run svnserve.

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. I want to allow access via svn+ssh://, but am paranoid. I hate the idea of giving each user a login; I would then have to worry about what they are, and are not, allowed to access on my machine.

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.


How can I set certain properties on everything in the repository? Also, how can I make sure that every new file coming into the repository has these properties?

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.


How do I deal with spaces in the editor path? Also, how can I define command line options for the editor?

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.


I'm managing a website in my repository. How can I make the live site automatically update after every commit?

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 [/subversion/svnbook/svn.reposadmin.create.html#svn.reposadmin.create.hooks 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.

If you have problems getting the hook to work, see "Why aren't my repository hooks working?".

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>


How do I check out a single file?

Subversion does not support checkout of a single file, it only supports checkout of directory structures. Subversion 1.5 will support sparse directories.

However, you can use 'svn export' to export a single file. This will retrieve the file's contents, it just won't create a versioned working copy.


How do I detect adds, deletes, copies and renames in a working copy after they've already happened?

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.


How does Subversion handle binary files?

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:

  • Files with no svn:mime-type
  • Files with a svn:mime-type starting "text/"
  • Files with a svn:mime-type equal to "image/x-xbitmap"
  • Files with a svn:mime-type equal to "image/x-xpixmap"

All other files are treated as binary, meaning that Subversion will:

  • Not attempt to automatically merge received changes with local changes during svn update or svn merge
  • Not show the differences as part of svn diff
  • Not show line-by-line attribution for svn blame

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.


How can I make svn diff show me just the names of the changed files, not their contents?

svn diff doesn't have an option to do this, but

  • If you only are interested in the diffs between, say, revision 10 and the revision just before it,
    • svn log -vq -r10 does exactly what you want;
  • otherwise, if you're using Unix, this works for any range of revisions:
    • svn log -vq -r123:456 | egrep '^ {3}[ADMR] ' | cut -c6- | sort | uniq

Version 1.4 of the svn diff command will have a "--summarize" option. How can I use wildcards or globbing to move many files at once?

You want to do something like

svn mv svn://server/trunk/stuff/* svn://server/trunk/some-other-dir

but it fails with

svn: Path 'svn://server/trunk/stuff/*' does not exist in revision 123

... or some other inscrutable error message.

The short, unhappy answer is: there's no built-in way to do this; many commands, like mv, refuse to take an arbitrary number of arguments ... and in any case, Subversion doesn't expand wildcards like "*" the way the shell does.

If you happen to have a working copy that contains all the source files as well as the destination directory, then you can exploit your shell's wildcard feature to do the move, like this (for Bash):

  • for i in stuff/*; do svn mv $i some-other-dir; done svn ci -m "moved all the stuff into some other dir"

In any case, you can always accumulate a list of the names of the source files, and then run "svn mv" on each item in that list, like this:

  • s=svn://server/trunk/stuff/ svn ls "$s" | \ while read f
    • do svn mv "$s/$f" svn://server/trunk/some-other-dir -m "Moved just one file"
    done

Note, however, that this will generate one commit per source file; that's in contrast to the above method (using a working copy) which generates just one commit total.

There is a program called "svnmucc" or "mucc" depending upon which version of Subversion you have, whose source is distributed with Subversion (in .../contrib/client-side/mucc/mucc.c for Subversion 1.4 or earlier, in .../contrib/client-side/svnmucc/svnmucc.c for Subversion 1.5 or later), that appears to solve this problem for you.

Rumor has it that with release 1.5, Subversion will in fact allow you to "cp" and "mv" multiple files at once.


How can I maintain a modified version (a "vendor branch") of third-party software using Subversion?

People frequently want to use Subversion to track their local changes to third-party code, even across upgrades from the third-party — that is, they want to maintain their own divergent branch, while still incorporating new releases from the upstream source. This is commonly called a vendor branch (the term long predates Subversion), and the techniques for maintaining one in Subversion are described here.

If the vendor code is hosted in a remote Subversion repository, then you can use Piston to manage your copy of the vendor's code.

As a last resort, if using svn_load_dirs.pl is taking too much time or you're looking for the lazy solution, see also Jon Stevens' step-by-step explanation at Subversion Vendor Branches Howto. This solution does not make use of the space saving features in the Subversion backend when you copy new code over old code; in this solution, each import of a vendor code gets an entire new copy and there is no space savings for identical files.


Troubleshooting

Every time I try to run a svn command, it says my working copy is locked. Is my working copy corrupt?

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

I'm trying to commit, but Subversion says my working copy is out of date?

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 get 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.


I've contributed a patch to a project and the patch added a new file. Now svn update does not work.

In order to include your new file in the patch you likely ran the svn add command so that the svn diff command would include the new file in the patch. If your patch is committed to the code base and you run an svn update, then you might receive an error message of: "svn: Failed to add file 'my.new.file': object of the same name already exists".

The reason that you recieved this error is that you still have your local copy of the file in your working copy. The steps to correct this problem are:

  1. Run the svn revert command to remove the scheduled add within Subversion.
  2. Delete the file or move it to a location outside your working copy.
  3. Now you should be able to run the svn update command.

You might want to compare the new file from the repository with your original file.


I just built the distribution binary, and when I try to check out Subversion, I get an error about an "Unrecognized URL scheme." What's up with that?

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.


I'm having trouble doing write operations to a Subversion repository over a network.

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).


Why does the svn revert require an explicit target? Why is it not recursive by default? These behaviors differ from almost all the other subcommands.

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. When I start Apache, mod_dav_svn complains about a "bad database version", that it found db-3.X, rather than db-4.X.

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".


I'm getting occasional "Access Denied" errors on Windows. They seem to happen at random. Why?

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 to fix. 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.


I can see my repository in a web browser, but 'svn checkout' gives me an error about "301 Moved Permanently". What's wrong?

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.


I'm trying to look at an old version of my file, but svn says something about "path not found". What's going on?

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 ...


I checked out a directory non-recursively (with -N), and now I want to make certain subdirectories "appear". But svn up subdir doesn't work.

Subversion 1.4.x

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.

Subversion 1.5

Subversion 1.5 supports sparse directories.


Why does my --diff-cmd complain about '-u'? I tried to override it with --extensions, but it's not working.

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.


I just discovered that my Subversion client is caching passwords in plain-text on disk

On Windows 2000 or later, svn 1.2 and above uses standard Windows APIs to encrypt the data, so only the user can decrypt the cached password.

On Mac OS X, svn 1.4 and later uses the system Keychain facility to encrypt/store your svn password.

On UNIX/Linux, there are no standard system encryption facilities, so the password is stored in ~/.subversion/auth/. Notice, however, that the directory which contains the cached passwords (usually ~/.subversion/auth/) has permissions of 700, meaning only you can read them.

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). More information on password cacheing is in chapter 6 of the "Nightly Build" Subversion book, under "Client Credentials Caching".


I cannot see the log entry for the file I just committed. Why?

Assume you run 'svn checkout' on a repository and receive a working copy at revision 7 (aka, r7) with one file in it called foo.c. You modify the file and commit it successfully. Two things happen:

  • The repository moves to r8 on the server.
  • In your working copy, only the file foo.c moves to r8. The rest of your working copy remains at r7.

You now have what is known as a mixed revision working copy. One file is at r8, but all other files remain at r7 until they too are committed, or until 'svn update' is run.

  • $ svn -v status 7 7 nesscg . 8 8 nesscg foo.c $

If you run the 'svn log' command without any arguments, it prints the log information for the current directory (named '.' in the above listing). Since the directory itself is still at r7, you do not see the log information for r8.

To see the latest logs, do one of the following:

  1. Run 'svn log -rHEAD'.
  2. Run 'svn log URL', where URL is the repository URL.
  3. Ask for just that file's log information, by running 'svn log foo.c'.
  4. Update your working copy so it's all at r8, then run 'svn log'.

After upgrading to Berkeley DB 4.3 or later, I'm seeing repository errors.

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:

  • Make sure no process is accessing the repository (stop Apache, svnserve, restrict access via file://, svnlook, svnadmin, etc.)

  • Using an older svnadmin binary (that is, linked to an older Berkeley DB):
    1. Recover the repository: 'svnadmin recover /path/to/repository'
    2. Make a backup of the repository.
    3. Delete all unused log files. You can see them by running 'svnadmin list-unused-dblogs /path/to/repeository'
    4. Delete the shared-memory files. These are files in the repository's db/ directory, of the form db.00*

The repository is now usable by Berkeley DB 4.3.

Why do I get occasional, seemingly inconsistent errors when checking out over {{{http://}}} from a repository running on MacOS X 10.4 (Tiger)?

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 64Kb. 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 upgrade to APR 1.2.0+.

Alternately, you can 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.


I can't add a directory because Subversion says it's "already under version control".

The directory you're trying to add already contains a .svn subdirectory, but it's from a different repository than the directory to which you're trying to add it. This probably happened because you used your operating system's "copy" command to copy one working copy into the current one.

The quick and dirty solution is to delete all .svn directories contained in the directory you're trying to add; this will let the "add" command complete. If you're using Unix, this command will delete .svn directories under dir:

  • find dir -type d -name .svn -exec rm -rf {} \;

However, you should ask yourself why you made this copy; and you should ensure that by adding this directory, you won't be making an unwanted copy of it in your repository. Accessing non-public repositories via svnserve is really slow sometimes.

This often happens when APR is compiled to use /dev/random and the server is unable to gather enough entropy. If Subversion is the only application using APR on the server, you can safely recompile APR with the --with-devrandom=/dev/urandom option passed to configure. This should not be done on systems that use APR for other processes, however, as it could make other services insecure.


When performing Subversion operations involving a lot of data over SSL, I get the error SSL negotiation failed: SSL error: decryption failed or bad record mac.

This can occur due to a problem with OpenSSL 0.9.8. Downgrading to an older version (or possibly upgrading to a newer version) is known to fix this issue.


I get an error that says "This client is too old".

You're using both an older (pre-1.4) version of the Subversion command-line client, and Subclipse. You recently upgraded Subclipse, and now your command-line client says

svn: This client is too old to work with working copy '/path/to/your/working/copy'; please get a newer Subversion client

This happened because Subversion's working-copy format changed incompatibly—the new version of Subclipse upgraded your working copy, so now your command-line program, which is old, cannot read it. (This problem isn't specific to Subclipse; it would also have happened if you'd used a command-line client that was 1.4 or newer, along with your older command-line client.) The fix is simply to upgrade your command-line client to 1.4 or newer.


Why doesn't svn switch work in some cases?

In some cases where there are unversioned (and maybe ignored) items in the working copy, svn switch can get an error. The switch stops, leaving the working copy half-switched.

Unfortunately, if you take the wrong corrective action you can end up with an unusable working copy. Sometimes with these situations, the user is directed to do svn cleanup. But the svn cleanup may also encounter an error. See issue #2505.

The user can manually remove the directories or files causing the problem, and then run svn cleanup, and continue the switch, to recover from this situation.

Note that a switch from a pristine clean checkout always works without error. There are three ways of working if you are using svn switch as part of your development process:

  1. Fully clean your working copy of unversioned (including ignored) files before switching.
    • WARNING! This deletes all unversioned dirs/files. Be VERY sure that you do not need anything that will be removed.
      • # Check and delete svn unversioned files:

        svn status --no-ignore | grep '[I?]' | sed 's/[I?]//' svn status --no-ignore | grep '[I?]' | sed 's/[I?]//' | xargs rm -rf

  2. Keep a pristine clean checkout. Update that, then copy it, and switch the copy when a switch to another branch is desired.
  3. Live dangerously :). Switch between branches without cleaning up BUT if you encounter a switch error know that you have to recover from this properly. Delete the unversioned files and the directory that the error was reported on. Then "svn cleanup" if needed and then resume the switch. Unless you delete all unversioned files, you may have to repeat this process multiple times.

Some examples are detailed here in issue 2505. The problem is that the svn client plays it safe and doesn't want to delete anything unversioned.

Two specific examples are detailed here to illustrate a problem like this. There are also other svn switch errors, not covered here, which you can avoid by switching only from a pristine checkout.

  1. If any directory has been moved or renamed between the branches, then anything unversioned will cause a problem. In this case, you'll see this error:
    • wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx

      svn: Won't delete locally modified directory '<dir>' svn: Left locally modified or unversioned files

    • Removing all unversioned files, and continuing the switch will recover from this.
  2. If a temporary build file has ever been added and removed, then a switch in a repository with that unversioned file (likely after a build) fails. You'll see the same error:
    • wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx

      svn: Won't delete locally modified directory '<dir>' svn: Left locally modified or unversioned files

    • In this case, just removing the unversioned items will not recover. A cleanup fails, but svnswitch directs you to run "svn cleanup".
      • wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx

        svn: Directory '<dir>/.svn' containing working copy admin area is missing wc/$ svn cleanup svn: '<dir>' is not a working copy directory wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx svn: Working copy '.' locked svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)

      Removing the directory (and all other unversioned files, to prevent "switch" from breaking on a similar error repeatedly), and continuing the switch will recover from this.

The TortoiseSVN cleanup error is a bit different. You might encounter this:

  • Subversion reported an error while doing a cleanup!

    <dir>/<anotherdir> is not a working copy directory

In each case here, the "svn switch" breaks leaving you with a half-switched working copy. "svn status" will show items with S for switched items (different from top directory), ! for directories with problems, and ~ for the files that are the problem (and with maybe L for locked). Like this:

  • wc/$ svn status ! .

    ! <dir>

    • S <switched_things>

    ~ <dir>/<thing_that_is_now_unversioned>

In Windows, when doing an update with the command-line client, I get an error saying "The system cannot find the path specified" and suggesting that my working copy might be corrupt. But I can update with TortoiseSVN just fine. What's going on?

A careful examination of the Windows API documentation regarding Naming a File reveals the most common reason why this happens. In short, you can address significantly longer path names when using the Unicode versions of the Windows path functions, and providing absolute path specifiers instead of relative path specifiers. Fortunately, the Apache Portable Runtime (APR) library that Subversion uses transparently converts absolute paths (like C:\?WorkingCopy\file.txt) into the form required by the Windows APIs (\\?\C:\?WorkingCopy\file.txt), and back again. Unfortunately, you only get these long-path benefits when using absolute paths.

To see if path length is the reason for the problem you're seeing, try providing an absolute target path to the Subversion command-line client instead of a relative one (or none at all). In other words, instead of doing this:

  • C:\> svn up ?WorkingCopy

or this:

  • C:\> cd C:\?WorkingCopy C:\?WorkingCopy> svn up

do this:

  • C:\> svn update C:\?WorkingCopy

If the problem goes away, congratulations — you've hit a Windows path length limitation. And now you know the workaround.

Why does this problem not affect TortoiseSVN? Because TortoiseSVN always provides absolute paths to the Subversion APIs.

Why, then, does the Subversion command-line client not always convert its input into absolute paths and use those? The Subversion developers have been operating under the principle that, for reasons of user experience, the display of paths in the tool's output should match the syntax of the paths provided as input. And while conversion to an absolute path from a relative one is a fairly trivial operation, the reverse transformation is fraught with complexities. (In other words, it's a hard problem not high on our priority list.)


I got an error saying "This client is too old to work with working copy '...' ". How can I fix it without upgrading Subversion?

Sometimes the working copy metadata format changes incompatibly between minor releases. For example, say you have a working copy created with Subversion 1.4.4, but one day you decide to try out Subversion 1.5.0. Afterwards, you attempt to switch back to 1.4.4, but it doesn't work — it just gives the above error.

This is because 1.5.0 upgraded your working copy format to support some new features (in this case, changelists, the keep-local flag, and variable-depth directories). Although 1.4.4 doesn't know anything about these new features, it can at least recognize that the working copy format has been upgraded to something higher than it can handle.

1.5.0 upgraded the working copy for a good reason: it realizes that 1.4.4 does not know about these new features, and that if 1.4.4 were to meddle with the working copy metadata now, important information might be lost, possibly causing corruption (see issue #2961, for example).

But this automatic upgrade behavior can be annoying, if you just want to try out a new release of Subversion without installing it permanently. For this reason, we distribute a script that can downgrade working copies when doing so is safe:

Run that script with the "--help" option to see how to use it. As future versions of Subversion are released, we will try to keep this FAQ entry up-to-date with potential downgrade scenarios and their implications.

>> Subversion Server FAQ.

Subversion Client FAQ (last edited 2008-04-29 18:53:57 -0700 by ?ghaarmans)