Subversion
From DGC Wiki
Subversion is the version control system that we use to manage files. Specifically we store our source code and related files in our main subversion repository, dgc.
In order to use subversion, you must have an account on grandchallenge. Send e-mail to help@grandchallenge to request an account. Make sure to send your desired username.
Much of the information in this document is taken from Version Control with Subversion, a book from O'Reilly that is available free online. If something isn’t here, that would be the first place to look.
Also the Subversion Administration wiki page for information on administering the repository.
Contents
|
What is Subversion?
Subversion stores files and their locations in a database called a repository or "repo". Every time a file is changed and then checked back into the repository, subversion notes the change and stores the difference between the two along with the notes given when the file was checked in. It remembers each change made, so you can go back and look at any previous version and undo changes. Because of this, it is to your advantage to check in as often as possible.
The subversion repository can be used by everyone over the network, so as soon as you make changes and commit them, the can be accessed by others. Because you are checking in fairly often as you develop, some of your changes may break other people's code. To prevent this from adversely affecting others, subversion has a structure called branches that let each developer or group work on their component separately and merge the changes as they see fit.
Complete documentation is available here: SVN book
Basic Terminology
| svn | The program used to access and use a subversion repository |
| repository | The database that stores all files and changes |
| check out | Set up a local copy of a portion of a repository |
| update | Download any changes from the repository to the local copy |
| check in/commit | Upload local changes to the repository along with an explanatory message |
| revision | A single change to the repository, given a revision number |
| branch | A copy of a portion of the repository with a common history used for parallel development |
Revision Numbers
Every time a change is committed to the repository, it is given a revision number. The revision number represents the state of the repository at that time. It does not matter how many files are added or changed.
Common Commands and Usage
Initial Checkout
svn co svn+ssh://gc.caltech.edu/dgc/subversion/dgc/trunk dgc
This command gets the trunk folder from the dgc repository on gc.caltech.edu in the folder /dgc/subversion and places it in the dgc folder in the current directory.
If the username in your Terminal shell is different from your username with access to gc.caltech.edu, just change that to:
svn co svn+ssh://username@gc.caltech.edu/dgc/subversion/dgc/trunk dgc
NOTE: If you want to compile our code on the new gclab cluster, there are some changes that you must make in order for it to run under gcc4 (which the new cluster uses). see the Gclab page for more info.
update
It is a good idea to update as often as possible, usually every time you sit down to work. This gets all the new changes and merges them with your local copy.
svn update svn up
Subversion will then list all the files that changed along with one of the following codes:
- U foo
- File foo was Updated (received changes from the server).
- A foo
- File or directory foo was Added to your working copy.
- D foo
- File or directory foo was Deleted from your working copy.
- R foo
- File or directory foo was Replaced in your working copy; that is, foo was deleted, and a new item with the same name was added. While they may have the same name, the repository considers them to be distinct objects with distinct histories.
- G foo
- File foo received new changes from the repository, but your local copy of the file had your modifications. Either the changes did not intersect, or the changes were exactly the same as your local modifications, so Subversion has successfully merGed the repository's changes into the file without a problem.
- C foo
- File foo received Conflicting changes from the server. The changes from the server directly overlap your own changes to the file. No need to panic, though. This overlap needs to be resolved by a human (you); we discuss this situation later
Make Changes to Your Local Copy
If you are just changing existing files, you don’t need to do anything special, subversion will know that you made the change.
If you want to add, delete, or move a file, you will need one of the following commands:
add
svn add foo
Schedule file, directory, or symbolic link foo to be added to the repository. When you next commit, foo will become a child of its parent directory.
delete
svn delete foo
Schedule file, directory, or symbolic link foo to be deleted from the repository. If foo is a file or link, it is immediately deleted from your working copy. If foo is a directory, it is not deleted, but Subversion schedules it for deletion. When you commit your changes, foo will be removed from your working copy and the repository.
copy
svn copy foo bar
Create a new item bar as a duplicate of foo. bar is automatically scheduled for addition. When bar is added to the repository on the next commit, its copy history is recorded (as having originally come from foo). svn copy does not create intermediate directories.
move
svn move foo bar
This command is exactly the same as running svn copy foo bar; svn delete foo. That is, bar is scheduled for addition as a copy of foo, and foo is scheduled for removal. svn move does not create intermediate directories.
Examine Your Local Changes
Before you check in, it is a good idea to look at your changes and make sure you didn’t forget anything, especially if you are adding or removing files.
status
svn status
This lists the status of all files changed in the local copy. The following codes are used in the first column:
- A item
- The file, directory, or symbolic link item has been scheduled for addition into the repository.
- C item
- The file item is in a state of conflict. That is, changes received from the server during an update overlap with local changes that you have in your working copy. You must resolve this conflict before committing your changes to the repository.
- D item
- The file, directory, or symbolic link item has been scheduled for deletion from the repository.
- M item
- The contents of the file item have been modified.
- ? item
- The file, directory, or symbolic link item is not under version control. You can silence the question marks by either passing the --quiet (-q) switch to svn status.
- ! item
- The file, directory, or symbolic link item is under version control but is missing or somehow incomplete. The item can be missing if it's removed using a non-Subversion command. In the case of a directory, it can be incomplete if you happened to interrupt a checkout or update. A quick svn update will refetch the file or directory from the repository, or svn revert file will restore a missing file.
- ~ item
- The file, directory, or symbolic link item is in the repository as one kind of object, but what's actually in your working copy is some other kind. For example, Subversion might have a file in the repository, but you removed the file and created a directory in its place, without using the svn delete or svn add command.
- I item
- The file, directory, or symbolic link item is not under version control, and Subversion is configured to ignore it.
- X item
- The directory item is unversioned, but is related to a Subversion externals definition.
An M in the second column indicates that the file or directory’s properties were changed.
An L in the third column indicates that the file or directory is locked.
A + in the fourth column indicates that the file or directory has additional history information.
An S in the fifth column indicates the file is being switched from a branch using svn switch.
svn stat -u
This can be used to get information on what has been changed server-side to see if any files are out of date before you update.
diff
svn diff
This shows exactly what changes you made to files using the standard line-by-line diff format.
revert
svn revert foo
undoes any changes in the local copy of foo. This does not have any affect on the repository.
Resolve Conflicts
When you do a svn update and someone else has checked in a change to a file you modified, you will often need to resolve the changes. Subversion will attempt to look at the file and automatically merge the changes, but if they are in the same part of the file, this is not safe and subversion will leave it to you to make the changes.
To tell if you need to resolve a conflict you can look at the output of svn update. The code of G indicates that subversion successfully merged the changes for you, but a code of C means you have some work in front of you.
If you miss the C when doing an update, subversion will not let you check in the conflicting file and will display the C code when you do a svn stat.
Subversion creates three temporary files in the repository:
- filename.mine
- The file in your working copy before the update
- filename.rOLDREV#
- The file as it was before you made changes
- filename.rNEWREV#
- The file as it is currently in the repository with someone’s changes
In addition, it places revision markers in filename showing what is different in each copy.
You now have three possible courses of action:
- Manual merge by hand
- Copy one of the temporary files on top of the working file
- Revert your changes to the version in the repository
(The following were taken directly from the Subversion book)
Merging by Hand
Here's an example. Due to a miscommunication, you and Sally, your collaborator, both edit the file sandwich.txt at the same time. Sally commits her changes, and when you go to update your working copy, you get a conflict and we're going to have to edit sandwich.txt to resolve the conflicts. First, let's take a look at the file:
$ cat sandwich.txt Top piece of bread Mayonnaise Lettuce Tomato Provolone <<<<<<< .mine Salami Mortadella Prosciutto ======= Sauerkraut Grilled Chicken >>>>>>> .r2 Creole Mustard Bottom piece of bread
The strings of less-than signs, equal signs, and greater-than signs are conflict markers, and are not part of the actual data in conflict. You generally want to ensure that those are removed from the file before your next commit. The text between the first two sets of markers is composed of the changes you made in the conflicting area:
<<<<<<< .mine Salami Mortadella Prosciutto =======
The text between the second and third sets of conflict markers is the text from Sally's commit:
======= Sauerkraut Grilled Chicken >>>>>>> .r2
Usually you won't want to just delete the conflict markers and Sally's changes—she's going to be awfully surprised when the sandwich arrives and it's not what she wanted. So this is where you pick up the phone or walk across the office and explain to Sally that you can't get sauerkraut from an Italian deli.[5] Once you've agreed on the changes you will check in, edit your file and remove the conflict markers.
Top piece of bread Mayonnaise Lettuce Tomato Provolone Salami Mortadella Prosciutto Creole Mustard Bottom piece of bread
Now run svn resolved, and you're ready to commit your changes:
$ svn resolved sandwich.txt $ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."
Remember, if you ever get confused while editing the conflicted file, you can always consult the three files that Subversion creates for you in your working copy—including your file as it was before you updated. You can even use a third-party interactive merging tool to examine those three files.
Copying a File Onto Your Working File
If you get a conflict and decide that you want to throw out your changes, you can merely copy one of the temporary files created by Subversion over the file in your working copy:
$ svn update C sandwich.txt Updated to revision 2. $ ls sandwich.* sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1 $ cp sandwich.txt.r2 sandwich.txt $ svn resolved sandwich.txt
Punting: Using svn revert
If you get a conflict, and upon examination decide that you want to throw out your changes and start your edits again, just revert your changes:
$ svn revert sandwich.txt Reverted 'sandwich.txt' $ ls sandwich.* sandwich.txt
Note that when you revert a conflicted file, you don't have to run svn resolved. Note also that this command does not revert revisions of the repository.
Rolling back changes in the repository
How do I revert code that has already been committed? A: You can do this with svn merge. This is described in detail at http://svnbook.red-bean.com/svnbook/book.html#svn-ch-4-sect-4.2 .
Commit Changes
svn commit svn ci
This will send all changes in the current and child directories to the server. It will open your editor and ask you to leave an explanation of the changes you made. Please make this descriptive so others don’t have to look at the code to see what your change did.
svn commit foo
Commits file or directory foo
svn commit -m “Message explaining the changes made”
Allows you to specify a message without having to open an editor
Examine History
log
svn log -r 2462:2400
Shows the log entries (commit messages) in reverse order from revision 2362 to 2400. Add -v for verbose log entries with a list of all files changed.
A useful option is --stop-on-copy will print out all changes in a branch an stop at when it was committed.
svn log --stop-on-copy
diff
svn diff
Shows line-by-line differences between the working copy and the repo.
svn diff -r 3503 foo
Compares the local copy of foo with version 3503 in the repo.
svn diff -r 3503:3504 foo
Compares two revisions in the repository.
cat
svn cat -r 5 foo
Displays version 5 of foo.
svn cat -r 5 foo > foo.r5
Copies version 5 of foo to the local file foo.r5
list
svn ls
Displays a list of files in the repository, as ls does on the local filesystem.
Branching and Merging
It is highly recommended to read Subversion Book chapter on branching and merging.
Creating branches is very cheap. It takes up almost no space in the repository and can make everyone’s work a lot easier. Do it whenever you feel like it. If you want to try something out or make changes that might break something, make a branch. ‘’You should treat trunk like a stable branch.’’
Creating a branch
Say that now you want to create a whole new sandwich and experiment with different recipies. To do this without bothering Sally you should create a branch. TO do this
svn copy svn+ssh://gc.caltech.edu/dgc/subversion/dgc/trunk svn+ssh://gc.caltech.edu/dgc/subversion/dgc/branches/new_recipe
Make a note somewhere to yourself about the revision immediately after you create the branch. You will need this later. It also wouldn't hurt to put the name of the branch and that revision number in the log message, so you can do the following (in any branch or trunk) to find that number later:
svn log | grep "branch_name"
Another option for creating a branch with a full checkout of the whole repository
This is not recommended because it will take a very long time and a lot of disk space to check out the whole repository (including full copies of all current tags and branches!). Just use the full URL as shown below.
svn checkout svn+ssh://gc.caltech.edu/dgc/subversion/dgc
in the checkout directory
svn copy trunk branches/new_recipe
Checking out a branch
Now that you have your new branch you will need to check it out to use it. Do so like this.
svn checkout svn+ssh://gc.caltech.edu/dgc/subversion/dgc/branches/new_recipe my_new_recipe_branch
Merging changes back into trunk
So now you've made changes to the new_recipe and feel that the original version shoudl be upgraded. However Sally may have still been working on her sandwich as well and you do not want to throw away all her work that happened while you had your branch.
Obtain a clean copy of trunk
Now checkout the trunk.
svn checkout svn+ssh://gc.caltech.edu/dgc/subversion/dgc/trunk dgc
Or if you already have a checkout of trunk, in that checkout do:
svn update
merge
Recall that the branch was created with commit 23 and now we are probably at 31 unless someone else has commited else where in the system so it might be higher. Be careful, do it until current. A useful command is
svn log --stop-on-copy
this will give you all the log messages back until the branch was created which is an easy way to find out what revision you created the branch.
So now we want your changes of the recipie in the branch to be intergrated into the trunk. So in the checkout of the trunk
svn merge -r 23:31 svn+ssh://gc.caltech.edu/dgc/subversion/dgc/branches/new_recipe
However if you changed some of the same lines as Sally when working on your new recipe there will be conflicts that subversion cannot update. Therefore, check that the merge went sucessfully with
svn status
After doing this if there are conflicts you will need to resolve them just like if there are conflicts from doing an svn update. (See above)
When you commit your changes in your message, make absolutely sure to list the revision numbers that you used in the merge (and it wouldn't hurt to include the name of the branch for easy grepping, too). It will be very helpful later if you or someone else wants to merge in more changes.
This may somehow produce conflicts that need to be resolved so check. Then test it and if it works commmit. Again, try to include both revision numbers, as well as the name of the branch in your log message.
Once you have merged your changes back into trunk, DELETE YOUR BRANCH. Don't bother trying to make more changes to your branch, and go through the whole merge process again - it's much quicker to delete your branch and create a new one.
Deleting the branch
Now that we're done with the branch we should get rid of it.
svn rm svn+ssh://gc.caltech.edu/dgc/subversion/dgc/branches/new_recipe
Committing changes in the working copy to a branch
If you have a checkout of trunk and you edit files and later decide that you want to save these changes to a branch instead of messing up the stable trunk, there is a solution: svn switch. However be careful and do svn info a lot to make sure you're doing what you think you are. For it gets tricky very quickly.
First, create your branch as normal, using the svn copy command.
svn switch
- svn switch changes what branch of a repository the working directory is comparing against.
- This can be done for any tree of folders.
- so if you switch dgc everything will change to the new branch
- If you switch in the directory $(DGC)/modules that directory and everything under it will change, but not anything else in $(DGC)
- it is very useful when working with multiple branches.
- This can be done for any tree of folders.
Then use svn switch to change to the branch of the repository. Execute this from the top of the directory tree you wish to switch:
svn switch svn+ssh://gc.caltech.edu/dgc/subversion/branches/new_recipe
This keeps all your local changes, but moves you to your branch. Since you just made the branch, there won't be any changes to merge from the svn switch.
You can now use svn ci to commit your changes to your branch as you would at any other time.
Q & A from the old page
Feel free to add more questions and we'll try to answer them for you.
- How do I install a subversion client on Mac OS X?
A: You can use Fink to do this, but there are dependencies. See this thread for details. <li>Is there a Subversion Quick Reference card available that I can print?
A: Here's one! <li>Can subversion send e-mail to me when files change
A: Yes! Edit the file /subversion/dgc/hooks/post-commit and add your e-mail address to the line that sends e-mail out. <li>I get an error message saying that I need to run database recovery, what do I do?
A: From grandchallenge, execute the following commands (as root):svnadmin recover /dgc/subversion/dgc chmod g+w /dgc/subversion/dgc/db/*
<li>How do I create a private branch without having to checkout the whole root tree?
A: You can do it with this command:svn copy svn+ssh://login@grandchallenge.caltech.edu/dgc/subversion/dgc/trunk \ svn+ssh://login@grandchallenge.caltech.edu/dgc/subversion/dgc/branches/my-private-branch \ -m "Creating private branch my-private-branch for isolated development"After that you can checkout your own private tree (that will not be affected by changes of other people unless you merge) with:
$ mkdir my-branch $ svn checkout svn+ssh://login@grandchallenge.caltech.edu/dgc/subversion/dgc/branches/my-private-branch my-branch
A good thing to do when you make a branch is to store the revision number at the moment you create the branch. This will be useful to have when you're going to merge changes into/from your branch. Do it like this directly after you've checked out your branch to store the number as a propset for your branch-directory:
$ cd my-branch $ svn up At revision XXX $ svn propset branch-point XXX .
If you want to get your number at a later moment you just do this:
$ cd my-branch $ svn propget branch-point . XXX
<li>How do I merge changes from trunk into my branch?
A: This is a bit confusing in the manual, so here's working instructions:
You have to know which revision you checked out at (I assume you want to merge all changes since then) and also the current revision (easily achieved with svn up. If you saved your branch number with svn propset (as described above) just get it with svn propget (see above). Otherwise you'll probably have to read svn log or something like that to find out.
- OK, now that you got your old and new revision numbers. Follow these instructions (replace login with your login, XXX with the old revision number and YYY with the current revision number):
$ cd my-branch-root $ svn merge \ svn+ssh://login@grandchallenge.caltech.edu/dgc/subversion/dgc/trunk@XXX \ svn+ssh://login@grandchallenge.caltech.edu/dgc/subversion/dgc/trunk@YYY \ .- now check the merged files so there's no conclicts (C letters in the merging log). You can also do svn status in a directory to see changes in that dir (and subdirs).
- if there's conflicts, solve them or do svn revert (details on syntax @ http://svnbook.red-bean.com/en/1.0/re25.html ) on the files to change them back. If you want to keep old versions instead of the merged ones, revert those files.
- commit the merge changes.
<li> How do I revert code that has already been committed? A: You can do this with svn merge. This is described in detail at http://svnbook.red-bean.com/svnbook/book.html#svn-ch-4-sect-4.2 .
<li> How do I switch from subversion on grandchallenge to subversion on lawrencium, and vice versa? A: To switch from repository to another, use the svn 'switch' command:
svn switch --relocate <from> <to> [path]
For example, to switch you code to look at lawrencium instead of grandchallenge, use
cd dgc svn switch --relocate svn+ssh://gc.caltech.edu/dgc/subversion/dgc \ svn+ssh://192.168.0.235/dgc/subversion/dgc .
To switch from lawrencium to grandchallenge, do
cd dgc svn switch --relocate svn+ssh://192.168.0.235/dgc/subversion/dgc \ svn+ssh://gc.caltech.edu/dgc/subversion/dgc .
If you experience problems, try checking your current URL with
svn info
The format of the URL must match your <from> string!
<li> How do I use the $Id$ string in a svn'd file?
A: You need to set the svn:keywords property on the file so that $Id$ will be interpreted and replaced with the identification string:svn propset svn:keywords Id file.c
<li> How to checkout SVN if your username is not the same as your grandchallenge login?
A: If you encounter trouble with your username not matching the username on the Subversion server, it is supposed to be enough to add your username to the access URL but since that didn't work for me, there is an alternative way: to add the following to the ssh configuration file ~/.ssh/config on the computer you are trying to checkout from (change myusername to the username you have on grandchallenge):Host grandchallenge.caltech.edu User myusername Host gc.caltech.edu User myusername<li>Where should I add new code into the repository?
A: See the guidelines at Project Subversion Structure.<li> Eeek! So I/someone changed something in my local copy/the latest revision and now things don't work, how do I svn up to a previous version while simultaneously over-writing anything on my local machine? (and I don't want those >>>>mine, >>>>>r5060 comments to appear in my code)
A: Although it's debatable whether this is the cleanest solution, the easiest is probably to remove the offending folder/file (rm *filename* or rm -r *directory name* (note that *directory name* should be replaced by the name of the directory) when in the directory in which the offending item is stored) and then svn up to a previous version that you liked/know worked (svn up -rXXXX (replace XXXX with desired revision number)IF you want to do this with dgc/ then you may have to reinstall doxygen after you have removed and checked-out a new copy of the code - to do this use the following commands (sequentially - i.e. press return after each line) when you are in your home directory (the one in which dgc is stored)
- su root
- root password - you will obviously have to put in the real one here...
- cd ~/dgc/local/scripts
- svn up
- ./install_packages.sh
You will be asked something relating to fonts by Debian Configuration in the middle (the screen goes blue) - accept the default answers
<li> How do I move/copy something from obsolete back into trunk?
A: You want to do something like this:
svn move svn+ssh://user@gc.caltech.edu/dgc/subversion/dgc/Obsolete/path_to_what_you_want_moved svn+ssh://user@gc.caltech.edu/dgc/subversion/dgc/trunk/path_to_where_you_want_it -m "Descriptive checkin message"
Yes, that is all one line. In particular, this one worked for klk on 2005-03-20:
svn move svn+ssh://klk@gc.caltech.edu/dgc/subversion/dgc/Obsolete/bob.0/Ladar/laserreader.cc svn+ssh://klk@gc.caltech.edu/dgc/subversion/dgc/trunk/drivers/sicklms221/laserreader.cc -m "Moving simple ladar test out of obsolete" </ol>[edit]Additional Information
![[Main Page]](../../../../upload/alice.jpg)