Using Subversion

From CCRMA Wiki
Revision as of 12:37, 13 August 2007 by Wikimaster (Talk | contribs)

Jump to: navigation, search

What is Subversion?

Subversion ("svn") is a version control system; it manages successive revisions of files, keeping track of the latest version of each file, which versions of other files are associated with particular versions of a file, etc. It can be used to:

  • Get a copy of the most recent version of a file or directory
  • Get a copy of a set of files as of a given date, a given version of one particular file, etc.
  • Compare the "working" version of a file to the most recent version
  • Allow multiple people to work on files at the same time
  • Etc., etc.

Comprehensive svn documentation: http://svnbook.red-bean.com

Subversion website: http://subversion.tigris.org

The main terms you need to understand are "repository," "revision," and "working copy". The repository is a central store of all the versions of all the files that are under Subversion's control. A "revision" of the repository is an integer that uniquely identifies the states of all of the files in the repository. A working copy (aka "sandbox" or "working directory") is a local copy of one particular version of one or more files, which you typically edit, test, debug, etc., and then "commit" to Subversion, thereby creating a new revision. If things get complicated, with people working on two or more versions of the same files, you'll want to think about using branches.

Getting and Installing Subversion

It all starts here: http://subversion.tigris.org/project_packages.html

Linux (Planet CCRMA)

The command-line Subversion program is part of the Planet CCRMA distribution, so you don't have to do anything special to use it.

"KSvn is a Konqueror-integrated frontend to the subversion (svn) revision control system for KDE." http://sourceforge.net/projects/ksvn

OSX

I use the command-line Subversion tools on OSX, which came as pre-built and easy-to-install binaries: http://metissian.com/projects/macosx/subversion

There seem to be a few OSX graphical clients for Subversion, all in buggy beta stages:

There are also Subversion plug-ins for BBEdit and other text editors, as well as graphical front-ends.

Some people at CNMAT interact with svn through the text editor called BBEdit:

"Basically it works seamlessly, but you have to install a prefernce panel called sshlogin". You get the preference panel from http://www.bebits.com/app/746 and then you have to check things out using the command-line tools, but then there's a Subversion menu (with an icon that looks like a big stylized letter "S" tilted 45 degrees to the left) in BBEdit that lets you do everything you need to do directly from BBEdit.

It seems to be good for anything involving individual files (even files such as Max patches that BBEdit can't open), and it has a nice graphical way to show you the differences between two text files side by side, but it's terrible at things involving directories. So, for example, BBEdit isn't good at changing the name of something that's already been checked into the repository ("svn rename"), or for adding new directories to the repository ("svn mkdir").

The command-line tools are installed into /usr/local/bin, which isn't in people's path by default when they open an OSX terminal window. After installing Subversion, open a Terminal window and type "svn help". If it prints help, you're fine. Otherwise, type "/usr/local/bin/svn help". If this works, you need to add /usr/local/bin to your path. Otherwise either you didn't really install Subversion or you accidentally installed it somewhere weird.

Information on using subversion with Xcode can be found in the followings:

  • Getting Control with Subversion and Xcode
  • Using Subversion

Windows

I installed Subversion (from http://subversion.tigris.org/project_packages.html), plus the GUI front-end TortiseSVN (http://tortoisesvn.tigris.org).

It didn't work because it couldn't find ssh. Here are my notes on how I fixed this (on CNMAT's Windows machine):

command-line ssh is here:

   C:\Program Files\SSH Communications Security\SSH Secure Shell\ssh2.exe

So you must add that directory to your path:

   Start Menu
   right-click "My Computer"
   Choose "properties"
   "Advanced" tab
   "Environment Variables" button
   In "System variables", scroll down to "Path"
   Select and press "Edit"

Then you have to tell Subversion that "ssh" is named "ssh2":

   cd C:\Documents and Settings\Matt Wright\Application Data\Subversion

Change config so that "[tunnels]" isn't commented out, and then underneath that, so it says

   ssh = ssh2

Configuring Subversion

At some point Subversion will automatically open a text editor to let you type in some important information. If you would like to choose which text editor it will use (instead of the default "vi"), put something like this in your .cshrc file or the equivalent:

  setenv VISUAL emacs
  setenv EDITOR emacs

If you use Bash, put something like this in your .bashrc file:

  export VISUAL='emacs'
  export EDITOR='emacs'

There's only one way that I've ever changed subversion's configuration:

Subversion can be set to "ignore" certain files, which basically means not to try to check them into the repository if they appear in a folder. You mainly need this for files that are created by the build process, which don't belong in the repository. By default Subversion comes configured with a pretty conservative list of these files; I've added quite a few. This configuration goes into the file config inside the "hidden" .subversion subdirectory of your home directory (at least on OSX and Linux). Here's what the appropriate line in ~matt/.subversion/config looks like (note that it's a single long line):

   global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* \
     .DS_Store build-mac build-classic *Data *.macyucky version.h \
     *.sit svn-commit* *.mode1 *.pbxuser build

Making A Repository

Subversion has a client/server architecture in which the repository (all the versions of all the files checked into svn) lives on a server, and people access the files via clients. I recommend that you use one of the CCRMA Linux machines as your server. (Don't use ccrma-gate, because it's running a bad old version of Linux that doesn't work with subversion.)

You have to use an "FSFS" repository at CCRMA (because your home directory is NFS-mounted). Decide where you want the repository to live. If it's going to be enormous because you want to check in zillions of megabytes of media, you should put it on the (not-backed-up) snd disk. Otherwise, you should put it in your home directory somewhere. Here's the magic incantation to create an SVN repository in the directory named "svn-repository" underneath your home directory:

    svnadmin create --fs-type fsfs ~/svn-repository

This creates an empty repository of the given name. The next steps are to check it out, copy files into it, 'add' those files to the repository, and then 'commit'. These steps are summarized below. If you want to read more, here's the whole story: http://svnbook.red-bean.com/en/1.1/ch05s02.html

Checking out a Working Copy

You'll do all your work (i.e., editing, compiling, testing, debugging) in a working copy. First decide where you want your working copy to be, and go there. For example, suppose you want to work in classes/220c:

cd classes/220c

You make the working copy with "svn checkout". Obviously, you have to tell the "svn checkout" command where to find the repository from which you're checking out the working copy.

  • If you're on a CCRMA machine the "path" to your repository will be something like this:
    file:///user/x/xyz/svn-repository
  • If you're on a non-CCRMA machine, the "path" will be something like this:
    svn+ssh://cmn18.stanford.edu/user/x/xyz/svn-repository

Note that you have to type in the full path to your Subversion repository, which in this example is the svn-repository directory in Xyz's account:

Your working copy can contain any of the following:

  1. The entire contents of your repository (good if you only have one project under version control, or if you want to look at everything you've been working on):
    svn co path_to_your_repository
  2. Just a subdirectory (if you want to work on only one project in this particular subdirectory):
    svn co path_to_your_repository/name/of/sub/directory
  3. Just the top-level folder of your repository without any of the subfolders (if you want to add a new top-level directory to the repository without having to check out any of the existing other directories):
    svn co -N path_to_your_repository
    The "-N" option is for "non-recursive"; it avoids checking out the subdirectories of a given directory.
  4. Any complicated subset of the files and directories in your repository. (You're on your own for how to ask for this.)

Adding a Directory to a Working Copy

Go to your working copy and use "svn mkdir" to add the new directory:

cd wherever/my/working/copy/is svn mkdir name-of-my-new-directory

The "svn mkdir" command will make an actual directory in your working copy, but it will also keep track of the fact that you intend for this directory to live in the repository. (Just saying regular Unix "mkdir" would do the former but not the latter.)

Now you must "commit" your new empty directory, so that it will truly go into the repository:

svn commit

It will bring up a text editor so you can type in a "log message", which will probably be something profound like "initial empty directory for such and such a project". If you weren't following instructions above and didn't set the shell variable VISUAL to your favorite text editor, you'll probably be happy to know that you can type ":q" (followed by the return key) to quit vi.

Adding Files and Subdirectories to the Repository

The basic stratgegy is that you start with a working directory, add the files to it, and then commit.

For example, continuing the examples above, assume you have a working directory in /zap/svn-repository/name-of-my-new-directory:

cd wherever/my/working/copy/is/name-of-my-new-directory touch foo.c svn add foo.c svn commit

In this example I used "touch" to create an empty file; in a real situation you'd actually copy an existing file into the directory or make it in a text editor or some other program.

The"svn add" lets subversion know that you intend for the new file to live in the repository. It's somewhat misleading that "add" doesn't actually add the files to the repository, it just "schedules" them to be added the next time you "commit".

How to Avoid Typing Your Password All The Time

This section is cryptic but better than nothing!

man ssh-keygen Make it like this:

matt% ls ~/.ssh

id_rsa id_rsa.pub known_hosts

matt% ssh cmn69 [Feldman:~] matt% ls .ssh/

authorized_keys known_hosts

This link has a step by step instructions on how to do this: how-to-setup-ssh-keys-and-why

Viewing Log History

You can view the log history by typing

svn log

Basic Work Cycle

Here's some great documentation on the basic Subversion Work Cycle: http://svnbook.red-bean.com/en/1.1/ch03s05.html

To summarize this summary,

  1. You must have a working copy. (svn checkout)
  2. Your working copy may be out-of-date because somebody else has checked in improvements since you checked yours out. Fix this (svn update)
  3. Make changes to your files.
    1. If you need to change file names or directory structure, do it through Subversion (svn add, svn delete, svn mkdir, svn rename, svn copy, etc.
  4. Examine your changes:
    1. Which files have I changed (or have changed out from under me)? (svn status)
    2. What changes have I made? (svn diff)
  5. Commit your changes (svn commit). Please write a descriptive log message when you commit any file(s) to svn.

You almost never need to refer to the server in a typed svn command, because working copies remember where they came from. So when you say svn update, svn status, svn diff, svn commit, etc., svn automatically interprets these to mean "with respect to the working copy in the current directory and the repository it came from" and so you don't have to mention the server.

The only time you need to refer to the server is when you check out a working copy in the first place (where obviously you need to tell your svn client which server to get the files from):

svn checkout svn+ssh://cmn17.stanford.edu/user/x/xyz/svn-repository 

The svn log command gives you the entire history of the given file, including the revision numbers (of the entire repository) for each different version of the file. If you want to compare two versions of a file from (for example) revisions 111 and 234, you can say

svn diff -r111:234 filename

Best Practices

Never store "derived" files in version control. Check in only source files, makefiles, etc.; the results of the build process (.o files, executable files, etc.) should not be under version control.

Check in often. Any time you make any improvement to any code, check it back in ASAP. If it's untested or has any other potential problems, you can just make a note of them in the comment when you check it in.

More advice:

Troubleshooting

Last Resort

When things really get confused, like when you don't understand SVN's error messages, this always works for me:

  1. Manually move any files that you've modified somewhere safe, i.e., outside your working copy
  2. Delete the troublesome parts of your working copy (files, directories, or the whole thing)
  3. Do "svn update" to restore your working copy with the current version from the repository
  4. Look at the result to see what actually was committed
  5. If necessary, copy your changed files back into you shiny clean new working copy and submit them again.

If things get completely hosed, you can always check out an all new working copy and then copy in any un-checked-in files that you modified.


Example Repository Set Up

Here is the sequence of steps that was taken to set up the source control repository for the REALSIMPLE CCRMA Research Group:

cd /usr/ccrma/group/realsimple
svnadmin create --fs-type fsfs svn
svn mkdir file:////usr/ccrma/group/realsimple/svn/doc -m 'Create REALSIMPLE doc directory'
svn import /usr/ccrma/group/realsimple/doc file:////usr/ccrma/group/realsimple/svn/doc/trunk \
          -m 'Initial import of REALSIMPLE doc project'
mv doc doc-old-CAN-DELETE
svn checkout file:////usr/ccrma/group/realsimple/svn/doc/trunk /usr/ccrma/group/realsimple/doc
cd doc
svn propset svn:keywords 'URL Author Date Rev' *.tex Make* <etc.>
<cd <subdirs> and repeat.>
svn commit -m "Enable keywords URL Author Date Rev on all Make and .tex files, etc."

Say 'svn help propset', etc., to learn about the various svn commands.

To "check out" your own copy of the REALSIMPLE source tree at CCRMA, you should be able to say, from anywhere in the world,

svn checkout svn+ssh://username@ccrma-gate.stanford.edu/usr/ccrma/group/realsimple/svn/doc/trunk ~/realsimple/doc

for example. This checks out a working copy of the doc subdirectory of the REALSIMPLE svn repository, and places it in the realsimple subdirectory of your home directory (which should already exist).

If you make changes to your local copy, you can upload them via

cd ~/realsimple/doc
svn commit -m 'My changes had to do with ..."

However, to include newly created files in your working copy, you must first use 'svn add filename' to add them to the project, as mentioned above. As also described above, 'svn mkdir dirname' will make a new directory both in your working copy and in the repository, 'svn delete filename' will delete from both, and so on.

To update your local copy with new changes by others, say

svn update

and so on.

How to Change or Switch the Location of Your Repository

Use

svn switch <NEW_URL>

See this svn document for more.