Subversion (SVN) is a very popular open source versioning system. It manages files, directories, and changes made to files and directories over time by single of multiple users. If you have the time to thoroughly learn SVN, the only book you should read is available online for free. It can be found at http://svnbook.red-bean.com. However, if all you want to do is get started with SVN within an hour, you have come to the right place.
A decade ago Concurrent Versioning System (CVS) was the most-widely used versioning. It is built on Revision Control System (RCS) and thus inherits its flaws and this inheritance is precisely the reason it is very difficult to fix these flaws in CVS. SVN was created to overcome the flaws of CVS. It offers all the benefits of CVS without its flaws.
Although SVN is primarily used by programmer to track their project, it is capable of managing any sort of file collection. Important features of SVN are:
Following are some important features which make SVN a better choice over CVS.
SVN stores all project files in a repository. Every user checks out files from this repository and uploads their modification to this repositories. This way every user has the most recent version of the project files.
Step 1: Create repository
The repository holds all files in a project.
cd ~ svnadmin create svnrespos svn mkdir file:///home/me/svnrepos/trunk \ file:///home/me/svnrepos/branches \ file:///home/me/svnrepos/tags \ -m "creating repository layout"
To see what you created
svn list file:///home/me/svnrepos
Step 2: Import project into the repository
Here we import project files into the SVN repository. Assuming that the project files are in ~/myproject and it contains files a.xml and a.dtd
cd ~ svn import myproject file:///home/me/svnrepos/trunk -m "importing project"
To see what was imported
svn list file:///home/me/svnrepos/trunk
Step 3: Check out a working copy
Every collaborator works on his working copy rather than the repository itself.
cd ~ svn checkout file:///home/me/svnrepos/trunk xml-project
This would create a directory called xml-project and copy all project files from the repository to this directory. User can edit these files.
Sharing you modification with other users and updating your local copy with modifications made by other users.
In the previous page, we checked out a directory with the following command:
$ cd ~ $ svn checkout file:///home/me/svnrepos/trunk xml-project
Now we create another local working copy
$ cd ~ $ svn checkout file:///home/me/svnrepos/trunk xml2-project
We will be editing the file painting.xml which looks like the following the repository
$ svn cat file:///home/nazim/svnrepos/trunk/painting.xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE painting SYSTEM "painting.dtd"> <painting> <name>Mona Lisa</name> <painter>Leonardo da Vinci</painter> <year>1504</year> </painting>
svn cat command prints the contents of the file in the repository to screen. To edit the file, you can use vi, gedit or any other editor. Change the year in the file from 1504 to 1506 and save the file. Once you have edited and saved the file, you can commit it to the repository with the following command.
$ cd ~/xml-project $ svn commit -m "changed painting year"
Now the painting.xml file in the local working copy xml-project and the repository are identical. However, the copy in the local working directory still has the older version of paintings.xml. To update this file, in the xml2-project, we need to use the following command:
$ cd ~/xml2-project $ svn update
Now the programmer using xml2-project has the updated versions of painting.xml committed by the programmer using xml-project local working copy.
To get help on any svn command, all the user needs to do is type:
$ svn help usage: svn[options] [args] Type
Following is a list of subcommands. Aliases are in parentheses. Aliases were created to make SVN friendlier for CVS users switching to SVN.
add blame (praise, annotate, ann) cat checkout (co) cleanup commit (ci) copy (cp) delete (del, remove, rm) diff (di) export help (?, h) import info list (ls) log merge mkdir move (mv, rename, ren) propdel (pdel, pd) propedit (pedit, pe) propget (pget, pg) proplist (plist, pl) propset (pset, ps) resolved revert status (stat, st) switch (sw) update (up)
Example
$ svn help add add: Put files and directories under revision control, scheduling them for addition to repository. They will be added in next commit. usage: add PATH [PATH [PATH ... ]] Valid options: --targets arg : pass contents of file ARG as additional args -N [--non-recursive] : operate on single directory only -q [--quiet] : print as little as possible
It is assumed that your svn has the following structure:
|-- /branches |-- /tags |-- /trunk
To copy trunk to the branch
$ svn copy trunk branches/new-branch -m 'created a new branch'
To delete a branch
$ svn delete branches/new-branch -m 'deleted obsolete branch'
svn diff lists all differences two files or a set of files
$ svn diff file1 file2
-r option shows difference between two versions of a files or set of files
$ svn diff -r5:10 some_directory
This code shows all changes made to the directory and all its contents between version 5 and version 10
$ svn diff --summarize some_directory
This code only lists files which have changes, not the details of what has changed inside them.
The purpose of versioning systems is to facilitate collaborative editing and sharing between different participants while making sure that no one accidentally overwrites someone else's work. Verioning systems also ensure that everyone has the current version of the resource, helps in avoiding duplication, and enables users to track changes. A version control system is a necessity for any software development project employing multiple programmers.
Versioning system use either the Locking (Lock-Modify-Unlock) Model or the Nonlocking (Copy-Modify-Merge) Model. The locking model allows only one user to edit a file at a time. This is accomplished by using locks. While someone is editing a file, it is locked and other users can only view it. Once a user is finished editing a file, the file is unlocked and available for editing by other users. User's are often frustrated with Locking Model's restrictiveness e.g. a user is editing a file and then runs off to a 2 hour meeting while another user can't progress because he needs to edit this file.
Nonlocking Model is used by SVN, CVS and many other versioning systems. In this model, every user works on a local copy of the repository rather than on the repository itself. Once a user is done editing a file, he commits it to the repository. All other users can update their local copy by updating their local copies. If two users are working are editing a file simultaneously, their changes are merged into a file. Merging is not possible with binary files such as images and video. In such cases, SVN allows users to use a locking model.
SVN is a client-server application where the SVN repository serves the tasks of a server. It is a central storage place which stores information in the form of a filesystem tree. Users share data by reading and writing to the repository. The repository keeps track of all changes written to the file i.e. modifications to the files, file contents, and directory structure. Users see the latest version of the filesystem by default but they can view every change ever make to the contents of the repository.
Accessing SVN repository
SVN repositories can be accessed in many different ways based on how it is configured by the administrator. Note that SVN is a client-server application and as such the repository location is always a URL. Following are different methods to access the repository:
file:// repository is on local disk
http:// access through WebDAV protocol and Apache server
https:// access through WebDAV protocol and Apache server with SSL encryption
svn:// svnserve server
svn+ssh:// svn:// through SSH tunnel
SVN Repository Layout
User can structure the SVN repository any way he wants but following is the recommended layout
cd ~ $ svnadmin create svnrespos $ svn mkdir file:///home/me/svnrepos/trunk \ file:///home/me/svnrepos/branches \ file:///home/me/svnrepos/tags \ -m "creating repository layout" $ svn list file:///home/me/svnrepos /trunk /branches /tags
The main development goes into the trunk. Branch development copies go in branches. Tag copies go into tags directory.
Getting data into SVN repository
User can copy data to the repository using either svn import or svn add commands. svn import is used to import files from a directory which is not a local working copy.
$ svn import my_directory file:///home/me/svnrepos/trunk -m "importing ..."
To add a file using svn add, first create a file x.txt with an editor of you choice inside you local working copy. Then run the following command.
$ svn add myfile
Now SVN can recognize this as a file related to the project. Next commit it to the repository
$ svn commit file:///home/me/svnrepos/trunk
SVN working copy is just another directory on the system. Files in this directory can be edited with any editing software the user wishes to use. The changes will be incorporated into the repository only when the user explicity instructs SVN to do so using
$ svn commit
command. Changes made by other users will be incorporated into a working copy only when its owner explicitly instructs SVN to do so using
$ svn update
command. Multiple working copies can be create on a system. SVN creates and maintains extra files inside .svn directory (inside the working copy) which are necessary for SVN to performs its tasks such as update, commit, etc. The .svn directory should never be edited with operating system commands. This could lead to nasty problems.
Any editing software can be used to edit file contents. These modifications would automatically be detected by SVN. Changes to the filesystem tree such as moving, copying, deleting and renaming files and directories should NOT be made using shell commands such as mv, cp, rm, and mkdir. Instead use svn move, svn copy, svn delete and svn mkdir. These SVN commands make the necessary modification in the working copy and these changes are copied to the repository upon svn commit.
svn status
The svn status command provides an overview of changes made in the working copy since the last update or commit. svn status run at the top of the working copy detects all changes made in the tree. svn status run with a specified path gives information relevant to that address.
$ svn status database/flatfile
The specified path could be directory of file
$ svn status -v
With the -v option, svn status shows every file even if it wasn't changed
$ svn status -u
With the -u option, svn status shows outdated files.
Following is a sample output of svn status
A 45 23 user1 testscript.php M 45 20 user2 index.html
Take a look at the left most column. Following is these letters mean:
A: scheduled for addition
C: conflict detected, resolve before committing
D: scheduled for deletion
M: file contents modified
The second column is the revision number, followed by revision where the file was changed, user name of the person who made the modification, and file name.
svn log
svn log shows log messages, date, author, revisions, and more.
$ svn log $ svn log 9 $ svn log -r 4:5 $ svn log -r 5:3 $ svn log index.php $ svn log -v -r 3
The first command gives a simple svn log
The second command shows log for revision 9
The third command shows logs for revisions 3, 4, and 5
The fourth command is the same as the third command with the exception the logs are printed in reverse order i.e. revisions 5, 4, and 3
The fifth command shows all logs for a specified file
The last command shows logs in verbose mode
svn diff
svn diff shows each and every change that was made.
$ svn diff $ svn diff -r 3 index.php $ svn diff -r 3:4 index.php
The first command show all changes in the working copy.
The second command compares the file in the working copy to the file in the repository
The last command compares repository revisions
svn revert
svn revert filename
undos changes make to a file in the working copy.
Resolving Conflicts
If you two or more users have modified a file, between commits, there would be a conflict. To resolve a conflict, users can either postpone the conflict, merge conflicts by hand, override the file with your changes, or discard your changes. To postpone conflict resolution, type p when svn update notifies of a conflict. To merge conflicts manually, edit the file using any non-formatting text editor such as vi, emacs, gedit, notepad, etc. All the content between <<<<.mine and ====== are your modifications. All the content between ===== and >>>>>>.r2 is the other user's modification. Then type:
$ svn resolve --accept file
To discard your changes and accept the other user's changes:
$ svn resolve --accept theirs-full index.php
To override the file with your changes:
$ svn resolve --accept mine-full index.php
FSFS and BDB are Subversion filesystem implementations. Traditionally Berkeley DB (BDB) was the standard filesystem used by Subversion. FSFS was developed at MIT. It solves many serious concerns with BDB such as data corruption and added improvements such as smaller space requirements. Now the FSFS is the standard, the default setting, and recommended by Subversion developers. How is FSFS better than BDB:
- platform independent
- smaller repositories
- can host on network filesystem
- insensitive to interruptions
- other geeky details
Following are steps to copy svn repository from one server to another.
$ svnadmin dump /path/to/repository > repository.dump
$ scp repository.dump username@new.server.address:~/
$ svnadmin create new-repository
$ svnadmin load new-repository < repository.dump
$ svnadmin checkout file:///path/to/repository /path/to/working-copy
1. First line creates a repository dump
2. Second line copies the dump file to the new server
3. creates new repository
4. loads the repository dump into the new repository
5. create a working copy of the new repository
The proper way to delete file(s) from SVN repository is to run the following command:
$ svn delete somefile -m 'deleting some file'
This command would delete the file from the working directory. To delete the file(s) from the repository as well, simply commit your changes.
$ svn commit
A svn conflict results when a file in the repository is changed by another user before you committed your work. For example, you checked out revision 10024 and you are editing my.php. In the meanwhile, another user edits and commits my.php. Then you try to commit your changes, getting the following message:
$ svn commit -m 'added authentication to my.php' Sending my.php Transmitting file data .svn: Commit failed (details follow): svn: Out of date: '/mod/my.php'
If you can't commit, you should update to get the latest copy of the file
$ svn update C my.php Updated to revision 10024
The C stands for conflict. Let's see what is conflicting.
$ vi my.php
<<<<<<< .mine
if ($auth) { continue; } else { exit; }
=======
if (!$auth) { exit; } else { continue; }
>>>>>>> .r10024
Now you can:
1. remove your changes
$ svn revert my.php $ svn update my.php
2. remove other user's changes
$ cp my.php.mine my.php $ svn resolved my.php
3. merge the two
svn resolved my.php
Obviously, you should be careful how you resolve the conflict. In this particular example, all three options would work, but this would rarely work in most conflicts. It would also be prudent to talk to the other coder before you remove his code.
The best SVN GUI client is Tortoise SVN. Unfortunately, it is not a viable solution on Ubuntu. KDESVN is a good alternate to Tortoise SVN.
Installing kdesvn
To install,
$ sudo apt-get install kdesvn
You might also be prompted to install Subversion, kompare and a few other libraries.
Running kdesvn
Once the installation is complete, run
$ kdesvn
on the commandline to start kdesvn.
Adding kdesvn to right-click menu
Create a file ~/.gnome2/nautilus-scripts/kdesvn.sh and add the following two lines of code:
#!/bin/sh kdesvn $1
Assuming that your shell in located at /bin/sh. Type:
which sh
if you do not know where the shell is installed. The assign execution priviledges:
$ chmod 755 ~/.gnome2/nautilus-scripts/kdesvn.sh
In your file browser right click on any file or directory and you would see link for "open with kdesvn".
Creating a Subversion repository with kdesvn
On kdesvn, click on File > Subversion Admin > Create and open new repository. A window would open. For Path to repository, type or browse to your address. For Type of repository, choose FSFS. For details on this, see FSFS vs BDB. Check only "create main folders" option.
Checking out a Subversion repository with kdesvn
On the left window, select "trunk". The select Subversion > Repository > checkout current repository path. A window would open. Select target directory, choose revision, and uncheck "Append source url name to subfolder".