Subversion

What is Subversion?
Subversion is a free/open-source version control system. That is, Subversion manages files and directories over time. A tree of files is placed into a central repository. The repository is much like an ordinary file server, except that it remembers every change ever made to your files and directories. This allows you to recover older versions of your data, or examine the history of how your data changed. In this regard, many people think of a version control system as a sort of “time machine”.

Subversion can access its repository across networks, which allows it to be used by people on different computers. At some level, the ability for various people to modify and manage the same set of data from their respective locations fosters collaboration. Progress can occur more quickly without a single conduit through which all modifications must occur. And because the work is versioned, you need not fear that quality is the trade-off for losing that conduit—if some incorrect change is made to the data, just undo that change.

Some version control systems are also software configuration management (SCM) systems. These systems are specifically tailored to manage trees of source code, and have many features that are specific to software development—such as natively understanding programming languages, or supplying tools for building software. Subversion, however, is not one of these systems. It is a general system that can be used to manage any collection of files. For you, those files might be source code—for others, anything from grocery shopping lists to digital video mixdowns and beyond.

Important Links

 * Subversion Official Website
 * Binaries for download
 * SVN books

Client Software
 * SmartSVN (client)

Subversion's Features
When discussing the features that Subversion brings to the version control table, it is often helpful to speak of them in terms of how they improve upon CVS's design. If you're not familiar with CVS, you may not understand all of these features.

Directory versioning
CVS only tracks the history of individual files, but Subversion implements a “virtual” versioned filesystem that tracks changes to whole directory trees over time. Files and directories are versioned.

True version history
Since CVS is limited to file versioning, operations such as copies and renames—which might happen to files, but which are really changes to the contents of some containing directory—aren't supported in CVS. Additionally, in CVS you cannot replace a versioned file with some new thing of the same name without the new item inheriting the history of the old—perhaps completely unrelated—file. With Subversion, you can add, delete, copy, and rename both files and directories. And every newly added file begins with a fresh, clean history all its own.

Atomic commits
A collection of modifications either goes into the repository completely, or not at all. This allows developers to construct and commit changes as logical chunks, and prevents problems that can occur when only a portion of a set of changes is successfully sent to the repository.

Versioned metadata
Each file and directory has a set of properties—keys and their values—associated with it. You can create and store any arbitrary key/value pairs you wish. Properties are versioned over time, just like file contents.

Choice of network layers
Subversion has an abstracted notion of repository access, making it easy for people to implement new network mechanisms. Subversion can plug into the Apache HTTP Server as an extension module. This gives Subversion a big advantage in stability and interoperability, and instant access to existing features provided by that server— authentication, authorization, wire compression, and so on. A more lightweight, standalone Subversion server process is also available. This server speaks a custom protocol which can be easily tunneled over SSH.

Consistent data handling
Subversion expresses file differences using a binary differencing algorithm, which works identically on both text (human-readable) and binary (human-unreadable) files. Both types of files are stored equally compressed in the repository, and differences are transmitted in both directions across the network.

Efficient branching and tagging
The cost of branching and tagging need not be proportional to the project size. Subversion creates branches and tags by simply copying the project, using a mechanism similar to a hard-link. Thus these operations take only a very small, constant amount of time.

Hackability
Subversion has no historical baggage; it is implemented as a collection of shared C libraries with well-defined APIs. This makes Subversion extremely maintainable and usable by other applications and languages.

Subversion's Components
Subversion, once installed, has a number of different pieces. The following is a quick overview of what you get. Don't be alarmed if the brief descriptions leave you scratching your head—there are plenty more pages in this book devoted to alleviating that confusion.


 * svn
 * The command-line client program.


 * svnversion
 * A program for reporting the state (in terms of revisions of the items present) of a working copy.


 * svnlook
 * A tool for inspecting a Subversion repository.


 * svnadmin
 * A tool for creating, tweaking or repairing a Subversion repository.


 * svndumpfilter
 * A program for filtering Subversion repository dump streams.


 * mod_dav_svn
 * A plug-in module for the Apache HTTP Server, used to make your repository available to others over a network.


 * svnserve
 * A custom standalone server program, runnable as a daemon process or invokable by SSH; another way to make your repository available to others over a network.

Installation under Unix

 * Remove previous version of subversion if you are upgrading:

$ rm -f /usr/local/lib/libsvn* $ rm -f /usr/local/lib/libapr* $ rm -f /usr/local/lib/libexpat* $ rm -f /usr/local/lib/libneon* $ rm -f /usr/local/bin/svn* $ rm -f /usr/local/apache2/modules/mod_dav_svn.so

$ tar xvf sqlite-3.6.22.tar.gz $ cd sqlite-3.6.22 $ ./configure $ make $ make install
 * Download the latest source code version of SqlLite for unix and install it:

$ tar xvf subversion-1.6.9.tar.gz $ cd subversion-1.6.9 $ ./configure --with-sqlite==../sqlite-3.6.22/sqlite3.c --with-apxs=/usr/local/apache2/bin/apxs $ make $ make install
 * Download the latest source code version of subversion for unix.


 * copy the backup program hot-backup.py to :

$ cp /root/install/subversion-1.6.9/tools/backup/hot-backup.py /usr/sbin/

Repositories

 * The Subversion repository is the central storehouse of versioned data for any number of projects.
 * There are two types of Repository Data Stores. Each one has advantages and disadvantages described in the Table 5.1. Repository Data Store Comparison of the SVN Book.
 * Berkeley DB: was used in the initial design phase of Subversion. It provides real transaction support, hot backups, is a very reliable database system, but there are some known limitations.
 * FSFS: stores data in ordinary flat files, using a custom format. Because Subversion developers often refer to a repository as the (versioned) filesystem, they have adopted the habit of referring to the latter type of repository as FSFS 2 —a versioned filesystem implementation that uses the native OS filesystem to store data.
 * The FSFS format is used by default.
 * The administrator must decide whether a repository will use Berkeley DB or FSFS.

The following commands create two different repositories. The first one is FSFS, the other Berkeley DB: $ svnadmin create --fs-type fsfs /path/to/repos $ svnadmin create --fs-type bdb /path/to/other/repos
 * Do not create a Berkeley DB repository on a network share.

Basic Apache Configuration
LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so  DAV svn SVNPath 
 * Edit the file  /conf/httpd.conf.
 * Certify that the following modules will be loaded:
 * You now need to tell Apache where you keep your Subversion repository. Use the following syntax:
 *  : is the place that follows the HTTP URI of your server. Example:  =myrepository, then you can access it using http://yourserver/myrepository.
 *  : is the absolute path for your local repository. Example: /absolute/path/to/repository
 * In this case your repository is anonymously accessible to the world:
 * anyone can use their Subversion client to checkout a working copy of a repository URL (or any of its subdirectories).
 * anyone can interactively browse the repository's latest revision simply by pointing their web browser to the repository URL, and
 * anyone can commit to the repository.

$ chown -R daemon:daemon

Basic HTTP Authentication
$htpasswd -mc /svnrepos/conf/svn-auth-file jaraujo New password: ****** Re-type new password: ****** Adding password for user jaraujo
 * The easiest way to authenticate a client is via the HTTP Basic authentication mechanism.
 * Apache provides an htpasswd utility for managing the list of acceptable usernames and passwords, those to whom you wish to grant special access to your Subversion repository.
 * Create an authentication file using the option -c and/or aditional users using only the option -m. Example:

$htpasswd -m /svnrepos/conf/svn-auth-file myuser New password: ****** Re-type new password: ****** Adding password for user myuser Finally protect your repository adding, for example, the following code in the httpd.conf file:  DAV svn SVNPath /svnrepos

# how to authenticate a user AuthType Basic AuthName "Subversion repository" AuthUserFile /svnrepos/conf/svn-auth-file

# only authenticated users may access the repository Require valid-user 

Quick Start
This section is a very short introduction to Subversion, and is designed to give bottom up learners a fighting chance.

Subversion stores all versioned data in a central repository. To begin, create a new repository: $ svnadmin create /path/to/repos $ ls /path/to/repos conf/ dav/ db/ format hooks/ locks/ README.txt This command creates a new directory /path/to/repos which contains a Subversion repository. This new directory contains (among other things) a collection of database files.

In this example, we assume that you already have some sort of project (a collection of files and directories) that you wish to import into your newly created Subversion repository. Begin by organizing them into a single directory called myproject (or whatever you wish). For reasons that will be clear later (see Chapter 4, Branching and Merging), your project's tree structure should contain three top-level directories named branches, tags, and trunk. The trunk directory should contain all of your data, while branches and tags directories are empty:

/tmp/myproject/branches/ /tmp/myproject/tags/ /tmp/myproject/trunk/ foo.c bar.c Makefile … The branches, tags, and trunk subdirectories aren't actually required by Subversion. They're merely a popular convention that you'll most likely want to use later on. Once you have your tree of data ready to go, import it into the repository with the svn import command (see the section called svn import):

$ svn import /tmp/myproject file:///path/to/repos/myproject -m "initial import" Adding /tmp/myproject/branches Adding /tmp/myproject/tags Adding /tmp/myproject/trunk Adding /tmp/myproject/trunk/foo.c Adding /tmp/myproject/trunk/bar.c Adding /tmp/myproject/trunk/Makefile … Committed revision 1. $ Now the repository contains this tree of data. As mentioned earlier, you won't see your files by directly peeking into the repository; they're all stored within a database. But the repository's imaginary filesystem now contains a top-level directory named myproject, which in turn contains your data.

Note that the original /tmp/myproject directory is unchanged; Subversion is unaware of it. (In fact, you can even delete that directory if you wish.) In order to start manipulating repository data, you need to create a new “working copy” of the data, a sort of private workspace. Ask Subversion to “check out” a working copy of the myproject/trunk directory in the repository: $ svn checkout file:///path/to/repos/myproject/trunk myproject A myproject/foo.c A myproject/bar.c A myproject/Makefile … Checked out revision 1.

Now you have a personal copy of part of the repository in a new directory named myproject. You can edit the files in your working copy and then commit those changes back into the repository.


 * Enter your working copy and edit a file's contents.
 * Run svn diff to see unified diff output of your changes.
 * Run svn commit to commit the new version of your file to the repository.
 * Run svn update to bring your working copy “up-to-date” with the repository.

For a full tour of all the things you can do with your working copy, read Chapter 3, Guided Tour. At this point, you have the option of making your repository available to others over a network. See Chapter 6, Server Configuration to learn about the different sorts of server processes available and how to configure them.

Case Study: My-Webserver

 * Create the repository as root:

$ cd /opt/jaraujo $ svnadmin create svnrepos

$ svn import /home/jaraujo/jsfbyexamples file:///opt/jaraujo/svnrepos/jsfbyexamples -m "Erste Importierung" $ chown -R daemon /opt/jaraujo/svnrepos/
 * For every imported project you have to set the right permissions. For example:


 * daemon is the user that apache uses. See the documentation of httpd.conf.
 * You can also use the http protocol to upload a project.


 * Create and insert some users into the authentication file:

$ /usr/local/apache2/bin/htpasswd -mc /opt/jaraujo/svnrepos/conf/svn-auth-file jaraujo $ /usr/local/apache2/bin/htpasswd -m /opt/jaraujo/svnrepos/conf/svn-auth-file coworker2

httpd.conf
Edit and change the file :

 DAV svn SVNPath /opt/jaraujo/svnrepos
 * 1) JAraujo - Subversion Repository
 * 1) JAraujo - Subversion Repository

# how to authenticate a user AuthType Basic AuthName "JAraujo Subversion repository" AuthUserFile /opt/jaraujo/svnrepos/conf/svn-auth-file

# only authenticated users may access the repository Require valid-user 

Removing a Project
Use the following command to remove a project from the repository:

svn delete --username jaraujo -m "Deleting project 'myProject'" file:///D:/svnrepos/myProject

--username is used to log in the repository, if it is password protected.

-m is used to write a message within the new repository version.

Renaming a Project
Use the following command to rename a project:

svn move --username jaraujo -m "Project name changed to LoucoProject" http://myserver/myrepo/Projectname/ http://myserver/myrepo/LoucoProject/

Removing files from version control
The svn:ignore property contains a list of file patterns which certain Subversion operations will ignore. The rationale behind the svn:ignore property is easily explained. Subversion does not assume that every file or subdirectory in a working copy directory is intended for version control. Resources must be explicitly placed under Subversion's management using the svn add or svn import commands. As a result, there are often many resources in a working copy that are not versioned.

In Linux use the following commands:

$ svn delete --force $ export SVN_EDITOR=/usr/bin/vi $ svn propedit svn:ignore $ svn commit -m "My directory ignores the files x, y, z."

Change the   to the file name that is still versioned. Example:

Change the   to the directory which have the files that you want to ignore. The program vi will start and the ignored files will be shown. Or it will be blank if no files are currently being ignored. In each line write the name of a file or use patterns with wildcards

If you are using the Subversive plugin you have two options:
 * Click with the right mouse button on the directory which have the files that you want to ignore and choose the option Team->Add to svn:ignore and follow the instructions.
 * Or click on the properties of the directory which have the files that you want to ignore and choose the SVN Info tab than add a new property svn:ignore. In each line write the name of a file or use patterns with wildcards. Take a look on this example:



Other typical situation is this here : "I have a file in my project that every developer must change, but I don't want those local mods to ever be committed. How can I make ignore the file?"

The answer is: don't put that file under version control. Instead, put a template of the file under version control, something like.

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.

Backuping a Repository
There are generally two types of backup methods available for Subversion repository administrators—incremental and full. We discussed in an earlier section of this chapter how to use svnadmin dump --incremental to perform an incremental backup (see the section called “Migrating a Repository”). Essentially, the idea is to only backup at a given time the changes to the repository since the last time you made a backup.

A full backup of the repository is quite literally a duplication of the entire repository directory (which includes either Berkeley database or FSFS environment). Now, unless you temporarily disable all other access to your repository, simply doing a recursive directory copy runs the risk of generating a faulty backup, since someone might be currently writing to the database.

Even if you also have an incremental backup, you might want to run this program on a regular basis. For example, you might consider adding hot-backup.py to a program scheduler (such as Cron on Unix systems). Or, if you prefer fine-grained backup solutions, you could have your post-commit hook script call hot-backup.py (see the section called “Hook Scripts”), which will then cause a new backup of your repository to occur with every new revision created.


 * copy the backup program hot-backup.py to :

$ cp /root/install/subversion-1.3.2/tools/backup/hot-backup.py /usr/sbin/


 * Use the following syntax to backup a repository:

$ hot-backup.py

Example

$ hot-backup.py /usr/svnrepos /home/myuser/backup

The resulting backup is a fully functional Subversion repository, able to be dropped in as a replacement for your live repository should something go horribly wrong.

There are benefits to both types of backup methods. The easiest is by far the full backup, which will always result in a perfect working replica of your repository. This again means that should something bad happen to your live repository, you can restore from the backup with a simple recursive directory copy. Unfortunately, if you are maintaining multiple backups of your repository, these full copies will each eat up just as much disk space as your live repository.

Incremental backups using the repository dump format are excellent to have on hand if the database schema changes between successive versions of Subversion itself. Since a complete repository dump and load are generally required to upgrade your repository to the new schema, it's very convenient to already have half of that process (the dump part) finished. Unfortunately, the creation of—and restoration from—incremental backups takes longer, as each commit is effectively replayed into either the dump file or the repository.

Using scripts to backup

 * Create a backup script like this:

File: svnbackup
 * 1) !/bin/bash


 * 1) Date : 20.07.2006
 * 2) Autor: Joao Araujo
 * 3) Description: This script makes the backup of the subversion repository.
 * 1) Autor: Joao Araujo
 * 2) Description: This script makes the backup of the subversion repository.
 * 1) Description: This script makes the backup of the subversion repository.

PATH=$PATH:/usr/sbin
 * 1) SET THE PATH

REPOSPATH=/opt/jaraujo/svnrepos REPOSNAME=svnrepos BACKUPPATH=/home/jaraujo/backup/svnrepos VARDATE=`date +%Y%m%d` TARFILE=bkp-svn-$VARDATE.tgz

hot-backup.py $REPOSPATH $BACKUPPATH
 * 1) MAKE THE BACKUP

cd $BACKUPPATH
 * 1) CHANGE THE DIRECTORY

rm *.tgz
 * 1) REMOVE OLD BACKUPS

tar czf $TARFILE $REPOSNAME*
 * 1) COMPRESS THE DIRECTORY

rm -R $REPOSNAME*
 * 1) DELETE THE DIRECTORY


 * Change the file privilege:

$ chmod u+x /root/scripts/svnbackup

Scheduling the backup
It's better to schedule the backup using the command Crontab:

$ crontab -e 00    20      *      *       mon-fri      /root/scripts/svnbackup > /home/jaraujo/backup/svnrepos/bkp.log
 * 1) Mins Hours  Days   Months  Day of the week

See the section Scheduling cron jobs to learn more about this command.

Using Branches
Find more Information about using branches at SVN Book - Using Branches.

Problem description

Let's say that you've been given the task of performing a radical reorganization on the project A that is versionend using SVN. It will take a long time to write, and will affect all the files in the project. The problem here is that you don't want to interfere with the work of other collaborators, who are in the process of fixing small bugs here and there.

The better solution is to create your own branch, or line of development, in the repository. This allows you to save your half-broken work frequently without interfering with others, yet you can still selectively share information with your collaborators. You'll see exactly how this works later on.

Creating a Branch

 * Use the command and make a copy of the project in the repository Wherever you wish—it's a matter of project policy. Normally  your team has a policy of creating branches in the /project/branches area of the repository. Example:

svn copy http://svn.example.com/repos/calc/trunk http://svn.example.com/repos/calc/branches/my-calc-branch -m "Creating a private branch of /calc/trunk." or svn copy file:///opt/jaraujo/svnrepos/jautil/trunk file:///opt/jaraujo/svnrepos/jautil/branches/1_0_1 -m "The project will be adjusted to work with web applications."

There are two important lessons that you should remember from this section.


 * Unlike many other version control systems, Subversion's branches exist as normal filesystem directories in the repository, not in an extra dimension. These directories just happen to carry some extra historical information.


 * Subversion has no internal concept of a branch—only copies. When you copy a directory, the resulting directory is only a “branch” because you attach that meaning to it. You may think of the directory differently, or treat it differently, but to Subversion it's just an ordinary directory that happens to have been created by copying.

Copying Changes To the Branches
From time to time it's better, then, to receive the collaborator's change now, before you start working too heavily in the same places. It it important to copy sometimes the changes from the to the.

For projects that have a large number of contributors, it's common for most people to have working copies of the trunk. Whenever someone needs to make a long-running change that is likely to disrupt the trunk, a standard procedure is to create a private branch and commit changes there until all the work is complete.

Subversion gives you the ability to selectively “copy” changes between branches. And when you're completely finished with your branch, your entire set of branch changes can be copied back into the trunk.

It's time to use the command. This command, it turns out, is a very close cousin to the command.

If you want changes applied somewhere else, you'll need to say so. For example, if you're sitting in the parent directory of your working copy, you'll have to specify the target directory to receive the changes:

$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk my-calc-branch U  my-calc-branch/integer.c