Rob's Favorite Subversion (svn) Commands

Quick Links:

  1. Creating a repository
  2. Checking out a repository
  3. Adding, deleting, moving files
  4. Checking status
  5. Locking files
  6. Resolving conflicts
  7. Getting information about a repository
  8. Migrating repositories

Creating a repository

Incredibly easy, as the manual says. Just log into the machine hosting your svn root directory, and enter:
  svnadmin create /path/to/repos
Then once the new repository is created, it is easy to check it out and then start adding files to it. First, for example, on the svn host computer:
  svnadmin create ~/svnroot/teaching
Then go to a remote computer and check out a copy with
  svn co svn+ssh:// Teaching
  cd Teaching
  cp some_files .
  svn add files
  svn commit -m "adding new files" 
To create a repository that is to be shared by other users (with accounts on the same computer as the repository) there are some additional steps.
  1. Ensure that the other users of the repository have accounts on the repository computer AND
    make sure they are all members of one group, in this example, the "svn" group.
  2. Log into the repository computer and cd to the root directory
      cd ~/svnroot  
  3. Make sure umask is 002 (e.g., execute the "umask 002" command)
      umask 002  
  4. Create the repository as usual, e.g.,
      svnadmin create ~/svnroot/afib-nih09 
  5. Change the group of all the directories in the repository, e.g.:
      chgrp -R svn afib-nih09/ 

Checking out a repository

Often someone will send you a link to an svn repository and this makes life easy, just copy and paste the command or the pointer after the appropriate svn command, typically
 svn co 
. For more details, keep reading....

Adding, deleting, moving files

Always tell svn when you add or otherwise change the contents of the repository.
   svn add filename/directory-name
adds files or directories. The directory must already exist and when added, it will (be default) add all the contents of the directory.

When adding a binary file, i.e., on that contains more than just plain text, an additional command can reduce the overhead of carrying out diff operations each time these files are updated:

   svn add filename(s)
   svn propset svn:mime-type application/pdf filename(s)

To remove a file, both from your local directory and the repository, enter the following:

   svn rm filename/directory-name

When done with adding, deleting, and moving, it is necessary to commit the changes with

   svn commit -m "message_text"

Checking status

To check the status of the local version against the repository, use the commands svn status and svn diff, e.g.
    svn status
will return a list of files that have changed or are otherwise interesting. The meaning of the code letters to the left of each file are as follows:
   svn status -u
Stands for --show-updates and will talk to the repository and show changes relative to it; otherwise, status only looks locally.

Locking Files

Unlike CVS, svn allows locking of files! The mechanism is simple and transparent, well, it is kind of simple and not very transparent at times.

To lock a file in a repository:

  1. Make sure the working copy is up to date with an
       svn up
  2. Lock the desired file(s) with the command
       svn lock file_names  -m "optional comment"
  3. Go about editing the file as usual.
  4. When editing is complete, check in the new version and release the lock with the usual commit command and a specific unlock:
       svn commit file_names  -m "optional comment"
       svn unlock file_names
    Note that this will unlock ALL files in the directory, not just the one(s) that have changed. Or so it sometimes work.
  5. If you wish to keep the files locked after committing, add the
    option to the command:
       svn commit file_names  -m "optional comment" --no-unlock
  6. To simply unlock file without checking it back in
       svn unlock file_names  

Check lock status

Any user trying to change the file will be blocked with an error message that sounds truly scary. To discover status of a file, use the following command:

   svn status -u letters-chris.tex
   O    *     letters-chris.tex
and look for an "O" (stands for owned by Others) in the entry for any locked files. Your own locked files should have a "K", e.g., when I execute this command on my own files
  svn -u status letters-rob.tex
  K     743   letters-rob.tex
To see who has locked the file, use the info command
   svn info file_names
   Lock Token: opaquelocktoken:4ca4b536-70fa-4902-9a7c-8f9a7422fd86
   Lock Owner: macleod
   Lock Created: 2013-11-16 06:57:09 -0700 (Sat, 16 Nov 2013)

Forcing unlock

It can happen that a file gets locked and the own is not available or the system otherwise fails. To force open a locked file, use unlock, e.g.,
   svn --force unlock file_names
   'file_names' unlocked
At least this is how it is supposed to work--sometimes it does (-:

Note that locking is tied to a session, a single terminal window, so that if you change windows, you suddenly do not look like the owner of the files. If files start appearing in a status list marked with an "O" (instead of "K"), then it could be that you have locked them but you are not you any more! This is when forcing an unlock (and then relocking) is the valuable escape!

Resolving conflicts

When changes happen in two different versions or local copies of the file, there can be conflicts. When svn cannot work out those conflicts automatically, it places the two temporary copies of the conflicting versions in the local directory along with the older version---so there are three copies of what should be the same file. To resolve a conflict, do one of three things:
  1. Merge the conflicted text "by hand" (by examining and editing the conflict markers within the file).
  2. Copy one of the temporary files on top of your working file.
  3. Run
     svn revert filename 
    to throw away all of your local changes.
Whichever root taken, it is necessary to let Subversion know by running
      svn resolved  filename 
This removes any three temporary files and Subversion no longer considers the file to be in a state of conflict.

Getting information about a repository

info command

Often it is nice find out where a repository was from which a project has come. This and other info is available by means of the info command, e.g.,
    svn info
will return information about the repository of the project in the current directory, e.g.,
  Path: .
  Repository Root:
  Repository UUID: 76038eab-591d-0410-bf0b-a17c1341c730
  Revision: 29
  Node Kind: directory
  Schedule: normal
  Last Changed Author: macleod
  Last Changed Rev: 29
  Last Changed Date: 2007-02-27 14:45:08 -0700 (Tue, 27 Feb 2007)

list command

For a view of respository contents, even one you do not have checked out yet, this is a nice command. It has multiple use scenarios, here are a few:
  svn list
will make a simple list of the current repository. Note, you must first "cd" to the repository. A nicer, more detailed version of the output comes from this variation:
  svn list -v
If you know the URL of your possible repository, there is this varation, in a few examples:
  svn list -v svn+ssh://
  svn list
A specific example, to review the contents of the CIBC 2014 renewal repository.
  svn list -v
will list all the directories in the repository,
    886 macleod               Mar 13 05:30 ./
      2 macleod               Jul 09  2014 Management/
    886 macleod               Mar 13 05:30 Planning/
    884 macleod               Feb 17 22:21 Proposal/
    885 macleod               Mar 11 10:18 WWW/
  svn list -v --depth infinity
will list all the files in the entire repository.

ls command

The command
    svn ls
provides a listing of the contents of a repository, much like the same command works in Unix. Simply go to the directory that is under svn control and enter svn ls, e.g.,
  cd ~/www/docs
  svn ls
You may be prompted one or more time for the password of the repository but eventually there will be a list of the files and directories as the level of the current working directory. To get a high level view of the repository, enter the following command:
  svn ls full_repository_path
where full_repository_path is whatever you are using, e.g.,
  svn ls file:///Home/macleod/svnroot/www
The "-v" option will add more detail to any svn ls command.

svnlook command

The command svnlook is what provides access to the database containing the repository files; otherwise, there is not real way to examine a repository, unlike the CVS repositories. For example, the command

   svnlook tree ~/svnroot/www | more
will reveal the contents, down to the files, of the entire www repository in my svnroot area. The output is long, hence the more command.
   svnlook tree ~/svnroot/roblibs | more
does the same for another repository of mine that actually contains several pieces, including cutil, fids, and gfilelib. This repository also contains the full set of trunk, branches, and tags organization that is the standard svn way of doing things for code development.

Cleanup command

Often there are locked files that end up hanging around when an operation is interrupted. To deal with the error message
   svn: Working copy '/Users/macleod/www' locked
Then run the cleanup command but always FROM THE TOP LEVEL OF THE REPOSITORY!!!. In the case above, I went to the ~/www and ran the command, e.g.,
   cd ~/www
   svn cleanup
and it seemed to work.

Migrating repositories

You can hope you never have to do this but it can happen and the commands are not too awful.

Taking the contents of one repository and moving it another happens like this:

To tell your local repository to point to the new place, requires the following command:

      svn switch --relocate  old_URL  new_URL
So for a specific case of moving my tex directory, the commands looked like this on the old computer:
    svnadmin dump ~/svnroot/tex > tex.dump
    scp tex.dump new_computer:svnroot/
and then on the new computer
     svnadmin load --force-uuid ~/svnroot/tex < tex.dump
and finally on my local working copy
     svn switch --relocate 
all written on the same line.