CS 242 Fall 2011 : Subversion Tutorial

This page last changed on Aug 23, 2011 by cemeyer2.

Subversion is a powerful source control tool.  It allows you to upload your code to a central repository where you can save snapshots of your code in development.  It also allows you to revert to any previously saved checkpoint (revision).  We will be using SVN to hand in assignments.

The command-line version of SVN is a free download from http://subversion.tigris.org/ .  Additionally, if you are a windows user and would rather use a mouse than your brain, TortoiseSVN may make your life easier.  If you are a Mac user with similar mouse-brain inclinations, you may want to try SCPlugin, or if you don’t mind paying ~$40, the Versions is a very good GUI-based SVN client.

Be sure to familiarize yourself with the basics of SVN.  The tutorial below is a very detailed explanation of the operations you will likely need to perform:

By Nick Chen (updated by Charlie Meyer):

Accessing your repository for the first time
Type svn list https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>

Replace <netid> with your netid. If this is the first time using it, it will ask if you want to accept the certificate. You should type ʻpʼ to permanently accept it.
It will then prompt you for your password. Use your AD password to login. This is the password that you use to login to the machines in Siebel.
There should be no output at this point since there is nothing in your repository yet.

Adding a project to your repository
Create a subdirectory in your current workspace. To see where you are currently in the filesystem type pwd. To create the subdirectory type mkdir grocery. Change into that directory using cd grocery.
Create two files in the grocery directory.
list1.txt
apples
oranges
peach
strawberries
bananas
list2.txt
tomatoes
celery
potatoes
cucumber
lettuce
Now we add the grocery project to the repository. Make sure that you are in the grocery directory before issuing this command!

svn import . https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/grocery -m
“importing grocery project” [There is a dot after import]
It should reply with:
Adding list1.txt
Adding list2.txt
Committed revision xx. where xx is some number.

Notice that you do not need to type your username or password anymore. Subversion stores this information in a encrypted file in ./subversion.
The -m “some text here” is the text that you describes what you are doing. Ideally, whenever you make any changes, you can leave a short text telling yourself why you make that change. Do not list the changes since Subversion can automatically infer that. This would be a good time to talk about the xx number. Subversion maintains a global revision number. That means that any time you add files to repository (whether it is for the first time like we did here or when we check in a modified version of the file) Subversion gives the entire repository a new number. This number helps you revert back to a particular state of the repository. And this can be a bane for Subversion in this class. Since we have about 105 students, each time a student adds a project2, the revision number is going to increase. This can make it very hard to find the revision that you actually want.

You can go to https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid> in your web browser to see that you indeed have those files. At this point, your files are in the repository. You can safely delete the grocery directory and the files list1.txt and list2.txt within it. In fact, do that now. Since deleting files is risky business, I suggest you go do it in Windows Explorer or the Finder. If you already know the command for doing it in the command line then do it.

Checking a project out

Checking a project out is taking out all the files that you have added from a particular directory in the repository. We will be checking out the files from the grocery directory.

svn checkout https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/grocery
localgrocery
Subversion will reply with:
A localgrocery/list1.txt
A localgrocery/list2.txt
Checked out revision xx.

In this case, we checked out list1.txt and list2.txt into the localgrocery folder. Go to the localgrocery directory using cd localgrocery to make sure that the files are there.

Making changes
In the localgrocery directory, you are going to modify list1.txt. Open list1.txt in your text editor and edit it so that it looks like this:
apples
oranges
peach
strawberries
bananas
grapes
melons
Now in the command line, type svn status. You should see:
M list1.txt

The ʻMʼ stands for modified and it means that Subversion knows that our local copy (the one on our computer, not the repository) has been modified.
In fact you can inspect the changes using svn diff list1.txt
Index: list1.txt
===================================================================
— list1.txt (revision xx)
+++ list1.txt (working copy)
@@ -2,4 +2,6 @@
oranges
peach
strawberries
-bananas
No newline at end of file
+bananas
+grapes
+melons
No newline at end of file

Depending on how you type you list, the text displayed will probably be slightly different.

Updating the repository
Now we want to checkin the modified copy of list1.txt into the repository. In the localgrocery directory, type svn commit -m “Need to buy more fruit “
And Subversion will reply with:
Sending list1.txt
Transmitting file data .
Committed revision xx.
The commit function is used to save any changes weʼve made back to the repository. As before while we were adding the files to the repository, the -m option is used to attach a meaningful message to the changes. If you omit the -m, then an editor (usually vim in unix based machines) will pop up for you to write the message. It is not a good habit to leave the message blank. You can go to https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/grocery in your web browser to see that you indeed have those files. Or you can use the log command to see the list of changes made so far by typing svn log list1.txt
————————————————————————
rxx | <netid> | 2006-09-05 23:28:27 -0500 (Tue, 05 Sep 2006) | 1 line
importing grocery project
————————————————————————

Updating your local copy
For this part, we are going to have two copies of the grocery project on our computer. The new
one would be called localgrocerydup. We will make changes to list2.txt in both localgrocery and
localgrocerydup.
First we need to checkout localgrocerydup from the repository. Make sure that you are not in the localgrocery directory. You can go to your home directory by typing: cd ~. Then do: svn checkout https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/grocery
localgrocerydup
Subversion will reply with:
A localgrocerydup/list1.txt
A localgrocerydup/list2.txt
Checked out revision xx.
In localgrocery make the following changes to list2.txt
tomatoes
celery
potatoes
cucumber
lettuce
endives
asparagus
The commit those changes: svn commit -m “Adding more vegetables”
Now, in localgrocerydup, type: svn status –show-updates
Subversion tells you that:
xx list2.txt
Status against revision: xx
So that tells you that there are some difference between list2.txt in localgrocerydup and the latest file in the repository (that is what HEAD stands for). To see the actual difference, issue this command: svn diff -rHEAD list2.txt. Here is a sample output
Index: list2.txt
===================================================================
— list2.txt (revision xx)
+++ list2.txt (working copy)
@@ -2,6 +2,4 @@
celery
potatoes
cucumber
-lettuce
-endives
-asparagus
No newline at end of file
+lettuce
No newline at end of file
In localgrocerydup, do svn update.
Subversion will reply with:
U list2.txt
Updated to revision xx.
The ʻUʼ stands for updated. If you open list2.txt in localgrocerydup you notice that ʻendivesʼ and ʻasparagusʼ has been added.

Merging changes
Here we see the abilities and limitations of Subversion.

Assuming that you have done the steps above, we are going to simulate the situation where two developers are working on the same file at the same time. In localgrocery, edit list2.txt so that it looks like this:
carrots
tomatoes
celery
potatoes
cucumber
lettuce
endives
asparagus
In localgrocerydup, edit list2.txt so that it looks like this:
tomatoes
celery
potatoes
cucumber
lettuce
endives
asparagus
cabbage

Now, in this simulation, the changes made in localgrocery gets checked in first. So, in localgrocery do svn commit -m “Added more important vegetable”
Subversion tells you that it has received the changes:
Sending list2.txt
Transmitting file data .
Committed revision xx.

Now in localgrocerydup, do this svn commit -m “Added less important vegetable”

Subversion replies with this verbose message:
Sending list2.txt
subversion/libsvn_client/commit.c:873: (apr_err=160024)
svn: Commit failed (details follow):
subversion/libsvn_ra_dav/commit.c:570: (apr_err=160024)
svn: Your file or directory ‘list2.txt’ is probably out-of-date
subversion/libsvn_ra_dav/util.c:389: (apr_err=160024)
svn: The version resource does not correspond to the resource within the transaction. Either the requested version resource is out of date (needs
to be updated), or the requested version resource is newer than the transaction root (restart the commit).

Basically, it tells us that our copy of list2.txt in localgrocerydup is out of date. So what we do is svn update. Here is the result:
G list2.txt
Updated to revision xx.

The ʻGʼ tells us that Subversion successfully merged the difference between our local copy and
the version in HEAD. This is a case of automatic merger.

Now, remember that even though it has been merged, we have not yet committed the changes
in the list2.txt file in localgrocerydup. So do svn commit -m “Added less important vegetable”.

Next we are going to simulate a case where it is not possible for Subversion to perform an automatic merge.

Go back to localgrocery and do svn update. This ensures that both localgrocery and localgrocerydup have the latest version. You should verify that this is indeed so before proceeding. The contents of list2.txt in both localgrocery and localgrocerydup should look like this:
carrots
tomatoes
celery
potatoes
cucumber
lettuce
endives
asparagus
cabbage

Now, in localgrocery, change carrots in list2.txt to CARROTS. Now do svn commit -m “Put emphasis on carrot”

In localgrocerydup, change carrots in list2.txt to Carrots. Now do svn commit -m

“Emphasize importance of carrot” and watch it balk with the following message:

Sending list2.txt
subversion/libsvn_client/commit.c:873: (apr_err=160024)
svn: Commit failed (details follow):
subversion/libsvn_ra_dav/commit.c:570: (apr_err=160024)
svn: Your file or directory ‘list2.txt’ is probably out-of-date
subversion/libsvn_ra_dav/util.c:389: (apr_err=160024)
svn: The version resource does not correspond to the resource within the transaction. Either the requested version resource is out of date (needs
to be updated), or the requested version resource is newer than the transaction root (restart the commit).

Now, if you try doing a svn update in localgrocerydup like we did before, you get:

C list2.txt
Updated to revision xx.

The ʻCʼ means that there is a conflict. Files marked as ʻCʼ cannot be checked in until the conflict has been resolved. Here are the necessary steps to resolve the conflict.
Open up list2.txt in localgrocerydup:
<<<<<<< .mine
Carrots
=======
CARROTS
>>>>>>> .rxx
tomatoes
celery
potatoes
cucumber
lettuce
endives
asparagus
cabbage
The lines with the <<<<<<< and >>>>>>> show where the conflict occurred. Between them we can see both our change and the conflicting change in the repository.
We decide that we like the change to be ʻCarrotʼ instead of ʻCARROTʼ. So we edit the file above to look like this:
Carrot
tomatoes
celery
potatoes
cucumber
lettuce
endives
asparagus
cabbage
Having removed the conflict markers, we can tell Subversion weʼve resolved the conflict and then commit the file: svn resolved list2.txt and then svn commit -m “Emphasize importance of carrot”. You have now successfully committed the file.

Adding files to the repository
It is unlikely that you will only be working with the files that you imported into the repository at
the beginning of the development cycle. You will be constantly adding files as you develop your
application. Subversion has a command for that: svn add.
In our example, we want to add list3.txt to the repository. Create list3.txt with the following
contents:
beef
chicken
pork
lamb
Now you need to tell Subversion that you want it to start keeping track of list3.txt. Type svn add list3.txt. Subversion replies with:
A list3.txt
The ‘A’ stands for added. Now, you need to commit the file into the repository. You do it using the normal command that we have been using: svn commit -m “Added list of meats”. And you get:
Adding list3.txt
Transmitting file data .
Committed revision xx.

You can always add a list of file using the wildcard * operator. For instance, svn add *.cpp will add all the current cpp source code to the list of files that Subversion has to take care of.

Removing files from the repository
Sometimes, we do not want Subversion to keep track of certain files anymore. This could be because we decided to remove that source code from our project or because we realize that we have moved the contents of the file to some other file. For this example, we are going to remove the file we just created. Type svn delete list3. txt. You will get:
D list3.txt
The ‘D’ stands for deleted. However, you have only deleted the file from your working directory.

To make the change to the repository, you need to type svn commit -m “Discovered that I want to be a vegetarian”. And you get:
Deleting list3.txt
Committed revision xx .

At this point, it is useful to clarify what we mean by removing. Say that we have list3.txt in revision 25. Now we remove list3.txt from the repository using svn delete list3.txt. What this does is remove list3.txt from all future revisions. Revisions 25 (and previous revisions up to the time list3.txt was added) will still have list3.txt inside it. So if we do a svn checkout -r25 https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/grocery/ . we will still get that
file back. Subversion never forgets what you put into it. If you really want to delete a file you need to go through an elaborate scheme as described here.

Move or rename something in repository
Sometimes, you need to change the name of your repository. For instance, like in our example, I decided that I really do not like the name grocery for the repository. What I want is to call it shopping instead. Now, a naive way of doing it would just be to checkout everything and recommit as a new repository. This is not a good idea for two reasons:

1. You now lose all the previous history
2. You duplicate information across two repositories

What you want to do is actually copy everything in the grocery repository to the new shopping repository AND delete the old grocery repository. Fortunately, Subversion has one command that does both of that: svn move.

Here is how we use it for our example:
svn move https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/grocery https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/shopping -m

“Moved grocery to shopping for clarity”

This time, Subversion just replies with a simple Committed revision xx.

Ignore certain files in the repository
It is a good practice to not add binary files to the repository. Binary files cannot really be “versioned” since there is nothing to be compared except their time stamps. Also, they just take up space in the repository. But it is not just binary files that should be ignored. Log files and all temp directories should also be ignored since they do not contribute to the development process for other people. In our shopping example, letʼs create a new file called list3.txt with the following line:

This is a lousy list that I do not want anyone to see

Save the file and do svn status. Subversion replies with:
? list3.txt

So far Subversion reports that it is a new file and there are no previous revisions of that file yet. So we can do this to have Subversion ignore it: svn propset svn:ignore list3.txt . Then you can commit your file using svn commit -m “Ignored the list3.txt from all future commits”. You can see the properties that svn propset has set on the current repository by doing svn proplist .. You get this in return:

Properties on ‘.’:
svn:ignore

There can be multiple properties from the above command. To view the files affected by the svn: ignore property, you do: svn propget svn:ignore .. This is what it replies with: list3.txt
What if you want to add list3.txt back to the repository? Meaning that you do not want to ignore it anymore? You can do that with svn propdel like so: svn propdel svn:ignore list3. txt ..

And you see this in the console:

property ‘svn:ignore’ deleted from ‘.’.

Now when you do svn status, you see that Subversion reports that:
? list3.txt
svn propset svn:ignore has some convenient functions such as pattern matching for file names so that you can tell it to just ignore files with extension .bin.
If on the other hand, you accidentally added a file to the repository already, you can do a svn delete first on the file and then do the svn propset command above to ignore it in future revisions. The nice about svn:ignore is that there is less “noise” when you do a svn status on the repository. Subversion does not report the status of the files that you plan on ignoring. svn propset is a pretty useful command for setting other “metadata” on your files as well. This helps you perform nice things when you need to intelligently select files. Some IDEs allow you right-click on a file in the navigator pane to set the svn:ignore property on it. This is pretty convenient as well but at least now you know how to do it from the command line as well.

Export a clean repository
When you turn your work in, you do not want to include all the hidden subversion files. What you want to do is commit your final changes and then do: svn export -rHEAD https://subversion.ews.illinois.edu/svn/fa11-cs242/<netid>/<project> <new directory name>. You can also export an earlier revision by specifying the revision number instead of HEAD.

Useful tips
● You can always find out what a command does by doing svn help <command> in the
command line.
● If you are working on your own repository as a single user, then the best course of action
would be:
1. Add your project to the repository
2. Checkout a copy into your working directory
3. After making changes, commit them
4. Repeat 3
5. Do a svn export before you hand your code to someone else.
● If you are working on a shared repository with someone else, here is the suggested
sequence of steps
1. Check out a copy into your working directory
2. Make changes to your working directory
3. Do a svn status—show-updates to see what has changed
4. Do a svn update or merge by hand
5. Commit your modified files
6. Repeat 2 – 4
● Itʼs a good idea to check in often. Especially if you have gotten some new function to work. Subversion is great but it cannot help you automatically check in. But do not check
in too often either: definitely not every time you make a simple change.
● Also, you will probably be interacting with Subversion using the GUI clients such as TortoiseSVN and svnX. Using those clients are definitely simpler than using the command
line but there are things that can only be done in the command line. If you are using  an IDE, you should also check if your IDE has a plug-in that supports Subversion. Eclipse, the
popular Java IDE has one called Subclipse,
● One major problem that plagues beginners of Subversion is merging code comments and formatted source code. Since Subversionʼs intelligent compare and merge works on a line
by line basis, a major code formatting such as auto formatting can have dire consequences. For instance, imagine that we have Alice and Bob working on the same repository. Alice has revision 22 and Bob has revision 22 as well. Alice makes some quick change and commits it. Bob, on the other hand, decides to apply the auto code tidy/ formatting. Since Alice committed before Bob, Bob has to merge those changes.Subversion will probably fail to automatically merge the file since the entire file could now look different. To avoid this scenario, you should always stick with a coding standard for your entire team of developers.

Document generated by Confluence on Feb 22, 2012 18:09

  1. Hiya. Fantastically polite web site!! Guy .. Charming .. Superb .. I will bookmark your web site and assume the feeds additionally…I am jovial to locate accordingly a lot beneficial in a row here inside the article. Recognition for sharing…

  2. Blueberry, no se si Zaplana es el mejor vestido, pero desde luego mejor que Aznar….sin duda!!!De todos modos, al sastre del Sr. Zaplana hay que añadirle la planta del caballero, que todo influye…

  1. No trackbacks yet.