Computer Science 340 :: Software Design and Testing

Using Subversion


Introduction

This tutorial will guide you through setting up a Subversion repository and will help you gain experience using Subversion's most commonly used features. This tutorial assumes that you have already set up your group account.


Setting Up Your Subversion Repository

Once you have a group account set up, you will want to set up a Subversion repository. For this tutorial, you will create a practice repository that we will call sandbox. With the sandbox repository, you can practice using Subversion as a group.

The group account owner will do the following:

In a shell, type:

cd /users/groups/cs340-NN
svnadmin create sandbox
chgrp -R cs340-NN sandbox
chmod -R 2770 sandbox/

The group copy is now set up to be checked out by each group member.


Checking out a Local Copy

Now that you have Subversion repository on the group account, we need to retrieve, or check out, your own copy of it. This copy will be stored on your account.

Each group member will do the following:

In a shell, type:

svn checkout file:///users/groups/cs340-NN/sandbox ~/CS340/sandbox

Each member will receive a message saying:

Checked out revision 0.

You now have a working local copy of your repository stored in ~/CS340/sandbox.

There will be a local copy on each student's account and one group copy in the group account.

Proposing Changes and Synchronizing Copies

Changes are made to the group copy by sending a list of changes – which we will call proposals – to the group copy. Any time a file or directory is added to the local copy, Subversion must be told about this add; the same goes for all file/directory moves and deletions. When the user is ready to alter the group copy to match the local copy, the proposals are sent to the group account and stored. Others will see these changes by updating their local copy. We will now go over each step in more depth.

Copies are synchronized through proposals, commits, and updates.

Adding Files to Your Repository

Now that we have a local copy of the repository, we want to create a file and tell Subversion that we propose to add it during the next commit. Remember, using svn add will only store a proposal on your account.

  1. In the ~/CS340/sandbox directory, create a file test1.txt
  2. In a shell, type: svn add test1.txt

This stores the proposal to add test1.txt to the group copy in a .svn folder in your local copy.

You will receive a message saying:

A test1.txt

Reflecting Changes Through Commit

To reflect the changes done in the local copy, the list of proposals must be sent to the group copy. The commit command sends the proposals to the group copy and incorporates the changes with Subversion's merge feature (discussed later). When a list of proposals are accepted by the group copy, a number, called a revision, is used to label the state of the group copy. Individual files in a local copy may be labeled as revisions earlier, equal to, or newer than the group copy. When committing changes, we must use the -m (message) flag, followed by a message. This message will be stored to tell other users what was changed from the previous revision.

In a shell, type:

svn commit -m 'added a new test file'

You will receive a message saying:

Adding     test1.txt
Transmitting file data .
Committed revision 1.
A commit is done to reflect the changes done in the local copy. This sends the list of proposals to the group copy.

Updating The Local Copy

Updating a local copy will retrieve all of the new changes from the group copy. These changes are incorporated into the local copy with Subversion's merge feature (discussed later).

Any two group members may do this:

  1. Both check out a local copy of the group repository.
  2. One person will create a file test2.txt, use svn add, and svn commit to add it to the group copy.
  3. On another account, in the sandbox folder, type:

    svn update

    You will receive a message saying:

    A      test2.txt
    Updated to revision 2.
An update will reflect the changes of all new versions on the local copy. If there is a conflict, a merge will be required.

Merging Revisions

When a commit happens, Subversion checks the proposal list against it's own copy. If the proposed changes are easy to insert, Subversion merges the proposal into it's copy automatically. Often times, two or more people may be working on the same set of files. When this happens, they may have to, at some point, merge the changes by hand.

Let's say that there are two group members named Michael and Chris. Both run svn update and have checked out revision 9. In this revision, test1.txt is just an empty line.:

  1. Michael writes in his version of test1.txt:

    hi

    there
  2. In his own version of test1.txt, Chris writes:

    my name is

    Bond, James Bond
  3. Michael uses svn commit and is now at revision 10.

  4. Chris uses svn commit and gets an error message:

    Sending      test1.txt
    svn: Commit failed (details follow):
    svn: Out of date: 'test1.txt' in transaction '10-1'
  5. Chris now has to run svn update and merge the changes by hand. When he runs svn update, three files will be created: test1.txt.mine, test1.txt.r9, and test1.txt.r10

    test1.txt – contains both the changes from Michael's commit and Chris' changes

    <<<<<<< .mine
    my name is

    Bond, James Bond
    =======
    hi

    there
    >>>>>>> .r10

    test1.txt.mine – contains the text that Chris had when he wanted to commit

    my name is

    Bond, James Bond

    test1.txt.r9 – contains the text that Chris had from revision 9


    test1.txt.r10 – contains the text that Michael's commit created

    hi

    there
  6. Chris must now go into test1.txt and manually merge the text. Here is his resulting test1.txt:

    hi
    there
    James Bond
  7. Now Chris types:

    svn resolved test1.txt
    svn commit -m 'resolved some test1.txt changes'

    Now Chris and Michael's changes are both present in the group copy.


How to Delete a File

The same process that was used in adding a file is used to delete files. A proposal must be sent, telling the group copy that the file is to be deleted. When the proposal is accepted by the group copy, things work out a little differently than possibly expected. The file is not fully erased from the repository. This can be scary if a confidential file is accidentally added to the repository. A repository is designed to keep things, so this situation can require drastic measures to overcome. Lets hope that never happens, but go over the process of actually deleting a file.

In a shell, type:

svn delete test1.txt
svn commit -m 'deleted test1.txt because it contains useless data'

The file will now be removed from both the local copy and the group copy. When a group member performs an update, the file will be deleted from that member's local copy. The following are some examples of problems that may occur when deleting files and how to overcome each situation.


Oops, I Typed rm test1.txt.

This simulates deleting a file from your local copy and getting it back with svn update.

In a shell, type:

rm test1.txt

Notice that the test1.txt file is gone from your local copy.

Now type:

svn update

You will receive a message saying:

Restored 'test1.txt'
At revision 2.

Oops, I Typed svn delete test2.txt. Using the Revert Command.

This will schedule the files for deletion on your next commit. If you commit, the change will be sent to the repository. That issue will be addressed next.

Subversion has a revert command that will revert a file or directory to the state it was in immediately after your last update, abolishing any changes done to it (including the delete proposal). Essentially, svn revert file-or-dir-name will delete a file from the local copy and use svn update file-or-dir-name to get the repository version back.

In a shell, type:

svn delete test2.txt

This will store the proposal and will not delete the file from the local copy yet.

svn revert test2.txt

You will receive a message saying:

Reverted 'test2.txt'

Oops, I Typed svn delete test2.txt and Committed the Changes. Using the Copy Command.

This will both delete the file from the local and group (current revision) copy. To get the file back, we will simply copy the file from the previous revision on the group copy and commit the change again. Subversion's copy command takes a revision tag that specifies which revision to copy a file or directory from.

In a shell, type:

svn copy --revision 2 file:///users/groups/cs340-NN/sandbox/test2.txt ./test2.txt
svn commit -m 're-added test2.txt'

We have specified that we want test2.txt from revision 2.


Using svn log to Read Repository Histories

When we commit a set of proposals, we are required to include a message along with our proposals. Where are these messages found? How can I tell which revisions changed test1.txt? Subversion keeps a history of changes done to each file and directory. Subversion also keeps a history of commit messages.

Subversion will print out each log in plain text or xml format. Subversion can also be told to print the history for a specific revision or range of revisions with the -r #[:#] flag. The plain text format will look similar to this:

------------------------------------------------------------------------
r10 | <submitter-name> | 2006-07-31 13:34:05 -0600 (Mon, 31 Jul 2006) | 2 lines
this is the message printed
when we committed revision 10
------------------------------------------------------------------------
r17 | <submitter-name> | 2006-08-02 13:34:25 -0600 (Wed, 02 Aug 2006) | 1 line
this is a different commit message

Practice with your sandbox now and see what some of the log commands can do.

  1. This will print a log of each commit message when test1.txt was changed.

    svn log test1.txt
  2. This will get you a log of all of the commit messages from revision 10 to 20.

    svn log -r 10:20
  3. This will print in xml format the commit messages from revision 3-13.

    svn log -r 3:13 --xml
  4. This will print into the file log.xml the commit messages when test1.txt was changed from revision 4 to 19 in xml format. This is useful when printing large logs and using the produced xml file to create a web page.

    svn log test1.txt -r 4:19 --xml >> log.xml

Using svn diff to See Changes Between Revisions

Looking at the changes in revisions is as simple as using the Linux diff command. To compare a file with a previous revision, we use svn diff file-or-dir-name -r #[:#]. The diff output is a series of difference lines:

Lets say that Chris is working on hello.cpp. The current revision on the local and group copy is revision 7 and the file is blank. Chris now adds the following to hello.cpp and commits the changes.

int main() {
return 0;
}

Later Chris types svn diff test1.txt -r 7:8 and sees the difference between revision 7 (the blank file) and revision 8. Here is the output on the command line:

===================================================================
--- test2.txt (revision 7)
+++ test2.txt (revision 8)
@@ -1 +1,3 @@
-
+int main() {
+ return 0;
+}

This basically says that the first (blank) line was deleted and the following three lines were added. More specifically, diff first names the two files it is comparing. Second, diff prints a line to the effect of:

@@ from-file-range to-file-range @@

In our example, the block covers line 1 of test2.txt (revision 7) and lines 1-3 of test2.txt (revision 8). Third diff shows that the first line was deleted and then the next three lines were added.


Importing an Existing Source Tree

Now that we have gone over the basics of using Subversion, we will now create a new repository and store the student version of Test Tracker in it.

One group member will do the following:

  1. In a shell, type: /users/groups/cs340-NN
    svnadmin create test-tracker
    chgrp -R cs340-NN test-tracker/
    chmod -R 2770 test-tracker/
  2. Now import the test-tracker initial source tree.

    Download the current student distribution of test-tracker from:

    test-tracker-source.zip

  3. Unzip the folder in a temp folder such as /tmp/test-tracker-source

  4. In a shell, type:

    svn import /tmp/test-tracker-source file:///users/groups/cs340-NN/test-tracker -m 'original import'

Now your group members can each check out a local copy and start working.

Each group member will now run:

svn checkout file:///users/groups/cs340-NN/test-tracker ~/CS340/test-tracker

You can now work on and run test-tracker with Apache Ant or Eclipse


Subversion on Windows

If you wish to have Subversion on your windows computer (as a client), I recommend TortoiseSVN.

If you want Subversion capabilities for Eclipse, I recommend the Eclipse plug-in: Subclipse (in Pure Java mode). Instructions are here.

  1. Download from http://tortoisesvn.tigris.org/
  2. You may check the MD5 sum for security
  3. Run the installer
  4. You will have to restart your computer
  5. Now you need to set the ssh client to TortoisePlink.exe
    1. Open Windows Explorer and right click on an empty space
    2. Select "TortoiseSVN -> Settings"
    3. Select "Network" from the tree on the left
    4. Set the SSH client to TortoisePlink.exe
      • Perhaps C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe
    5. Press OK, to leave the settings
  6. Checkout your repository
    1. From the folder you wish to download your repository to:
    2. Right click and select "SVN Checkout"
    3. For the URL, write:
      • svn+ssh://<USERNAME>cs.byu.edu/users/groups/<GROUPNAME>/test-tracker
    4. You will be prompted for your password (multiple times?)

September 28th, 2006 : Written by Christopher Hansen