
Table of Contents
SVN configuration is saved in a file named ~/.subversion/config. The most useful part of this file is the ability to let SVN set properties automatically. These properties allow you to configure things like $Id: svn.xml 43 2006-06-07 15:12:28Z adalton $ expanding to a version string, doing end-of-line translation, etc. Below is a sample of the appropriate section of the config file:
### Automatic properties are defined in the section 'auto-props'. enable-auto-props = yes ### Section for configuring automatic properties. [auto-props] ### The format of the entries is: ### file-name-pattern = propname[=value][;propname[=value]...] ### The file-name-pattern can contain wildcards (such as '*' and ### '?'). All entries which match will be applied to the file. ### Note that auto-props functionality must be enabled, which ### is typically done by setting the 'enable-auto-props' option. # Scripts *.sh = svn:eol-style=native;svn:executable,svn:keywords=Id *.bash = svn:eol-style=native;svn:executable,svn:keywords=Id # Text files, source files Makefile = svn:eol-style=native;svn:keywords=Id *.xml = svn:eol-style=native;svn:keywords=Id *.c = svn:eol-style=native;svn:keywords=Id *.nc = svn:eol-style=native;svn:keywords=Id *.cpp = svn:eol-style=native;svn:keywords=Id *.cxx = svn:eol-style=native;svn:keywords=Id *.h = svn:eol-style=native;svn:keywords=Id *.sql = svn:eol-style=native;svn:keywords=Id *.java = svn:eol-style=native;svn:keywords=Id *.properties = svn:eol-style=native;svn:keywords=Id *.shtml = svn:eol-style=native;svn:keywords=Id *.html = svn:eol-style=native;svn:keywords=Id *.htm = svn:eol-style=native;svn:keywords=Id *.css = svn:eol-style=native;svn:keywords=Id *.jsp = svn:eol-style=native;svn:keywords=Id .htaccess = svn:eol-style=native;svn:keywords=Id *.txt = svn:eol-style=native;svn:keywords=Id *.tex = svn:eol-style=native;svn:keywords=Id *.dsp = svn:eol-style=CRLF;svn:keywords=Id *.dsw = svn:eol-style=CRLF;svn:keywords=Id # Images *.gif = svn:mime-type=image/gif *.png = svn:mime-type=image/png *.jpg = svn:mime-type=image/jpeg *.jpeg = svn:mime-type=image/jpeg # Binary *.jar = svn:mime-type=application/octet-stream *.pdf = svn:mime-type=application/pdf
First, create the repository:
$ svnadmin create /home/userid/svn $ ls /home/userid/svn README.txt conf/ dav/ db/ format hooks/ locks/Next, create the initial directory structure for the repository. The authors of SVN suggest there be one directory per project, and that directory be subdivided into three subdirectories, branches, tags, and trunk. We will discuss the purpose of each of these subdirectories later in this document.
$ cd /tmp $ mkdir -p temp/project/trunk/project temp/project/tags temp/project/branchesNow we are ready to import the initial directory structure for the project:
$ svn import /tmp/temp file:///home/userid/svn -m "Importing initial project structure"
Adding /tmp/temp/project
Adding /tmp/temp/project/trunk
Adding /tmp/temp/project/trunk/project
Adding /tmp/temp/project/branches
Adding /tmp/temp/project/tags
Committed revision 1.
You may now safely delete/move the temp project directory
structure.
$ rm -rf /tmp/temp
Note: You may import an unrestricted number of projects into a repository.
Next, we will check out a copy of our empty project from SVN and add project files to it:
$ cd /home/userid $ svn checkout svn checkout file:///home/userid/svn/project/trunk/project Checked out revision 1. $ cd project $ cp -r /home/userid/src/project/* . $ svn add * A lab1 A lab1/Makefile A lab2 $ svn commit -m "Initial code added" Adding lab1 Adding lab1/Makefile Adding lab2 Transmitting file data . Committed revision 2.
Now that our project has been checked out, we are free to make changes to it. Once you have made your changes, you must commit them to the repository. Each time you commit to the repository, SVN will prompt you to enter a log message that describes the changes. You may supply the message using the -m flag; if you do not supply a message at the command line, SVN will open an instance of $EDITOR.
To see what would happen if you were to commit:
$ echo "# This is a comment" >> /home/userid/project/lab1/Makefile
$ svn status
M lab1/Makefile
To see what has changed since last you committed:
$ svn diff Index: lab1/Makefile =================================================================== --- lab1/Makefile (revision 2) +++ lab1/Makefile (working copy) @@ -0,0 +1 @@ +# This is a comment
To get detailed information about a file or directory in the repository:
$ svn info lab1/Makefile Path: lab1/Makefile Name: Makefile URL: file:///home/userid/svn/project/trunk/project/lab1/Makefile Repository Root: file:///home/userid/svn Revision: 2 Node Kind: file Schedule: normal Last Changed Author: userid Last Changed Rev: 2 Last Changed Date: 2006-06-07 03:10:38 -0400 (Wed, 07 Jun 2006) Text Last Updated: 2006-06-07 03:10:09 -0400 (Wed, 07 Jun 2006) Properties Last Updated: 2006-06-07 03:10:24 -0400 (Wed, 07 Jun 2006) Checksum: d41d8cd98f00b204e9800998ecf8427e
To view the revision log for a file or directory in the repository:
$ svn log lab1/Makefile
------------------------------------------------------------------------
r2 | userid | 2006-06-07 03:10:38 -0400 (Wed, 07 Jun 2006) | 1 line
Initial code added
------------------------------------------------------------------------
To actually commit the changes we have made:
$ svn commit -m "Added comment to Makefile" Sending lab1/Makefile Transmitting file data . Committed revision 3.
Eventually, you will want to add more files to your project:
$ cd /home/userid/project/lab1
$ touch draw.c
$ svn add draw.c
A draw.c
$ svn commit -m "Added draw.c"
Adding lab1/draw.c
Transmitting file data .
Committed revision 4.
You will likely want to remove files as well:
$ cd /home/userid/project/lab1
$ svn remove draw.c
D draw.c
$ svn commit -m "Removed draw.c"
Deleting lab1/draw.c
Committed revision 5.
You might even want to move (or rename) something:
$ cd /home/userid/project/
$ svn mv ./lab1/Makefile ./lab2
A lab2/Makefile
D lab1/Makefile
$ svn commit -m "Moved Makefile to lab2"
svn commit -m "Moved Makefile to lab2"
Deleting lab1/Makefile
Adding lab2/Makefile
Committed revision 6.
Before you commit your changes, you'll need to have the latest version of the project. If other users are simultaneously updating your project, you must keep your local version in sync with the repository. To update your workspace:
$ cd /home/userid/project
$ svn update
A lab1/hello.c
Updated to revision 7.
Here we see that another user has added the file
hello.c to the lab1 directory since the time
we checked out the project.
To restore a project to its state at a given revision number in the past, use the --revision flag:
$ cd /home/userid/tmp $ svn log file:///home/userid/svn/project/trunk/project ------------------------------------------------------------------------ r7 | userid | 2006-06-07 03:14:59 -0400 (Wed, 07 Jun 2006) | 1 line Added hello.c ------------------------------------------------------------------------ r6 | userid | 2006-06-07 03:14:07 -0400 (Wed, 07 Jun 2006) | 1 line Moved Makefile to lab2 ------------------------------------------------------------------------ r5 | userid | 2006-06-07 03:13:42 -0400 (Wed, 07 Jun 2006) | 1 line Removed draw.c ------------------------------------------------------------------------ r4 | userid | 2006-06-07 03:13:19 -0400 (Wed, 07 Jun 2006) | 1 line Added draw.c ------------------------------------------------------------------------ r3 | userid | 2006-06-07 03:12:36 -0400 (Wed, 07 Jun 2006) | 1 line Added comment to Makefile ------------------------------------------------------------------------ r2 | userid | 2006-06-07 03:10:38 -0400 (Wed, 07 Jun 2006) | 1 line Initial code added ------------------------------------------------------------------------ r1 | userid | 2006-06-07 03:07:45 -0400 (Wed, 07 Jun 2006) | 1 line Importing initial project structure ------------------------------------------------------------------------ $ svn checkout --revision 5 file:///home/userid/svn/project/trunk/project A project/lab1 A project/lab1/Makefile A project/lab2 Checked out revision 5.We could also use a date and time as a revision:
$ svn checkout --revision "{2006-06-07 03:14:07 -0400}" file:///home/userid/svn/project/trunk/project
A project/lab1
A project/lab1/Makefile
A project/lab2
Checked out revision 5.
Branches allow you to maintain separate versions of a projects, e.g. a development version, a testing version, and an unstable version. This is where the branches subdirectory comes into play. To create a branch, simply create a copy of what you want to branch from to the branches directory:
$ svn copy file:///home/userid/svn/project/trunk file:///home/userid/svn/project/branches/new_feature_dev \ -m "Create development branch for new feature" Committed revision 12.After this copy has been created, you can check out a copy of that branch for development:
$ cd /home/userid $ mkdir development $ cd development $ svn checkout file:///home/userid/svn/project/branches/new_feature_dev/project A project/lab1 A project/lab1/hello.c A project/lab2 A project/lab2/Makefile Checked out revision 12.Now we might add a new directory and a new source file:
$ cd project $ mkdir lab3 $ touch lab3/shape.c $ svn add lab3 A lab3 A lab3/shape.c $ svn commit -m "Added lab3" Adding lab3 Adding lab3/shape.c Transmitting file data . Committed revision 13.
Eventually, you'll be finished with your development effort and will want to merge your changes back to the trunk. The problem is another user may have already merged changes to the trunk. First, we'll merge any changes from trunk to our development branch (make sure everything is okay), then merge our changes to trunk.
First, find out what was the revision was before the branch:
$ svn log file:///home/userid/svn/project/branches/new_feature_dev ------------------------------------------------------------------------ r13 | userid | 2006-06-07 03:29:17 -0400 (Wed, 07 Jun 2006) | 1 line Added lab3 ------------------------------------------------------------------------ r12 | userid | 2006-06-07 03:20:57 -0400 (Wed, 07 Jun 2006) | 1 line Create development branch for new feature ------------------------------------------------------------------------ r7 | userid | 2006-06-07 03:14:59 -0400 (Wed, 07 Jun 2006) | 1 line Added hello.c ------------------------------------------------------------------------ r6 | userid | 2006-06-07 03:14:07 -0400 (Wed, 07 Jun 2006) | 1 line Moved Makefile to lab2 ------------------------------------------------------------------------ r5 | userid | 2006-06-07 03:13:42 -0400 (Wed, 07 Jun 2006) | 1 line Removed draw.c ------------------------------------------------------------------------ r4 | userid | 2006-06-07 03:13:19 -0400 (Wed, 07 Jun 2006) | 1 line Added draw.c ------------------------------------------------------------------------ r3 | userid | 2006-06-07 03:12:36 -0400 (Wed, 07 Jun 2006) | 1 line Added comment to Makefile ------------------------------------------------------------------------ r2 | userid | 2006-06-07 03:10:38 -0400 (Wed, 07 Jun 2006) | 1 line Initial code added ------------------------------------------------------------------------ r1 | userid | 2006-06-07 03:07:45 -0400 (Wed, 07 Jun 2006) | 1 line Importing initial project structure ------------------------------------------------------------------------Here, we see that revision 7 was the revision prior to the creation of our branch.
Next, we'll check for any changes to trunk since that revision:
$ svn diff -r 7:HEAD file:///home/userid/svn/project/trunk/project
Index: lab4/io.c
===================================================================
Property changes on: lab4/io.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Here, we see there have been changes we'll need to merge. Next,
we'll merge those changes from trunk to our development branch:
$ cd /home/userid/development $ svn merge -r 7:HEAD file:///home/userid/svn/project/trunk/project A lab4 A lab4/io.c $ svn commit -m "Back-merge of revisions 7:HEAD of trunk to development branch" Adding lab4 Adding lab4/io.c Committed revision 15.
Now, we check to make sure that our code still works after we've merged the changes from trunk. If everything is OK, we'll merge our changes back to trunk:
$ cd /home/userid/project $ svn update At revision 15. $ svn merge -r 12:13 file:///home/userid/svn/project/branches/new_feature_dev/project A lab3 A lab3/shape.c
And finally, we commit our changes:
$ svn commit -m "Merge changes 12:13 from branch 'new_feature_dev' to trunk" Adding lab3 Adding lab3/shape.c Committed revision 16.
Sometimes you might want to take a snapshot of your project at a given point in time. This might be especially useful if you release multiple versions of your software, to take a snapshot of those versions. To do this with SVN, you use tags.
Creating tags with SVN is exactly like creating branches; however, by convention you don't modify code in a tag copy. The tag copy is only for checking out the snapshot.
To create a tag:
$ svn copy file:///home/userid/svn/project/trunk file:///home/userid/svn/project/tags/0.9.4 \ -m "Tag version 0.9.4 of the project" Committed revision 17.
To do its job, SVN adds many auxiliary files to your workspace. To obtain a copy of the project without these added files:
$ cd /home/userid/public_html $ svn export file:///home/userid/svn/project/tags/0.9.4/project A project A project/lab1 A project/lab1/hello.c A project/lab2 A project/lab2/Makefile A project/lab3 A project/lab3/shape.c A project/lab4 A project/lab4/io.c Exported revision 17.