While programming a large code (or a set of codes) it’s important to keep track of changes along the way. Subversion (SVN) does precisely that. Its main difference with the popular alternative git, is that SVN keeps a single copy of the “repository” — where all the changes are stored. Here’s a brief outline of the main features and usage of SVN.
I. GETTING THINGS READY
a) Create the directory where the repository will be stored (let’s say ~/svn_repos/big_project)
$ mkdir ~/svn_repos && mkdir ~/svn_repos/big_project
b) “Create” the SVN repository
$ svnadvin create --fs-type fsfs ~/svn_repos/big_project
This will create a few files in the directory ~/svn_repos/big_project. Have a look at this link for an explanation of all the files created.
c) Start a project and put it (or an existing project) under version control
A typical project directory usually contains three subdirectories: (1) trunk, (2) branches ( and (3) tags. The ‘trunk’ contains the main working copy of the project. The ‘branches’ directory as the name suggests contains other ideas related to the project which initially started off of the main branch but now has significant deviation and are worth considering later. The ‘tag’ holds the snapshots (which you think might be considered to be good versions worth comparing with). So, if you are just starting you need to create the file structure first:
$ mkdir ~/project && cd ~/project && mkdir trunk branches tag
and then create a file in the trunk for fun!
$ touch ~/project/trunk/my_program.cpp
It’s recommended that the whole ‘project’ directory be put under version control (but that’s not mandatory!). You can do it as follows (assuming “~/ ” or the user’s “$HOME” variable expands as “/usr/username”, and both “~/svn_repos” and “~/project” directories are on the same machine):
$ svn import ~/project file:///usr/username/svn_repos/big_project -m 'Initial import'
The “-m” flags lets you enter a message along with the import.
If you want to import only ‘trunk’ you can do so by replacing “~/project” by “~/project/trunk”.
However, if the the ~/projects and ~/svn_repos reside on different machines (say, local.com and remote.com, respectively) we need to use svn+ssh instead:
$ svn import ~/project svn+ssh://firstname.lastname@example.org/usr/remote_username/svn_repos/big_project -m 'Initial import'
assuming that we are on the local machine and remote_username, as the name suggests, is the username on remote.com.
The initial import will be labeled as ‘revision 1’.
c) Copying the repository to somewhere else
You may want to copy the repository to a different place or even to a different machine:
$ svnadmin dump /path/to/reponame > /tmp/reponame.dump ; scp -rp /tmp/reponame.dump email@example.com:/tmp/
Have a look at the Arch wiki link for a thorough description.
II. LIFE WITH SVN
a) Check out a copy from the repository
If you want to check out revision N from the repo into the ~/codes directory on the same machine where the repo resides, then
$ svn checkout -r N file:///usr/username/svn_repo/big_project ~/codes/new_project
which will check out the Nth revision of the “trunk”, “branches” and “tags” in the “~/codes/new_project” directory.
However, if the repository is on a different machine (remote.com), then use the following to checkout the Nth revision in “~/codes/new_project”
$ svn checkout -r N svn+ssh://firstname.lastname@example.org/usr/remote_username/svn_repos/big_project ~/codes/new_project
- “co” is synonymous to checkout.
- If you skip “-r N”, then you’ll check out the latest revision.
- If you want to check out only “trunk” as the “new_project”, then replace “big_project” above by “big_project/trunk”.
For the time being we’ll assume that you are the only person who’s working on the project and you’re working solely in the directory “~/new_project/trunk”.
(At this point you can delete the original “~/project” directory — it’s of no use to us any more since all its information is stored in the repo)
b) Get more information about the repo: [svn info]
$ svn info
c) Check the files currently under version control: [svn ls]
$ svn ls
d) Make changes and commit: [svn commit]
Make some changes to “my_program.c”, and if you think it’s worth saving in the repo then do the following
$ svn commit -m 'The first big change is made'
Again the “-m” lets you add an informative comment.
e) Add another file under version control: [svn add]
Create another file in same directory
$ vi dummy.cpp
and add something to it, and then add it to the repository
$ svn add dummy.cpp
f) Remove a file from version control: [svn rm]
$ svn rm dummy.cpp
g) Put a copy of a version-controlled file under version control: [svn cp]
$ svn cp my_program.cpp our_program.cpp
h) Check the current status of the working copy (i.e., how does it differ from the copy in the repo?): [svn status]
$ svn status
Have a look at the list of codes which describes the status of the file(s).
i) Check the SVN log containing information about the revisions: [svn log]
$ svn log
The optional flag “–verbose” will print will print verbose information.
j) Compare the differences: [svn diff]
To find the difference in “my_program.cpp” between revisions M and N
$ svn diff -r M:N my_program.cpp > diff_file
The output is redirected to a file “diff_file” for easy browsing. If you want to know all the differences (in all the files) between these two revisions, then skip the file name.
On the other hand to find the difference between revision N and the working copy of “my_program.cpp”:
$ svn diff -r N my_program.cpp > diff_file-2
k) Revert to a previous revision: [svn revert]
If you want to revert to the last committed version of my_program.cpp
$ svn revert my_program.cpp
You may revert more than one files this way (just type the file names after my_program.cpp). If you want to revert to the last saved copy of the working directory, replace “my_program.cpp” with a “.” (dot).
l) Help is on the way: [svn help]
$ svn help unknown_command
will help you with the use of the command, “unknown_command”.
III. SHARING THE WORKLOAD WITH OTHERS USING SVN
a) Obaining copies and making changes
If you are a collaborator you should first check out a version of the repo in the same way as described in Section II(a) above. Then you can do all the other things described in Section II to the checked out files. For example, you can make changes to the files uncder version control and commit the changes to the repository using the commit command as in II(d).
b) Confilict resolution
There may be a conflict during ‘committing’ a file if some other collaborator has already saved (committed) an updated version of the file to the repo. The command, ‘svn commit’, won’t let you commit if there are conflicting changes between the file in the repo (say, with a revision number 6) and the one that you modified from an older version (e.g., 5). In that case you have to resolve conflict first before you can commit. To avoid such a scenario you should always start your work before you update your copy to the latest version in the repo:
$ svn update
However, in some cases conflict may be unavoidable. You have a few options in such a case:
Option 1: Skip your changes and revert to the updated version in the repo
$ svn revert my_program.cpp
Then make the changes and try to ‘commit’ it.
Option 2: Merge the changes (yours and the one in the repo)
After a failed attempt in commiting (due to conflicts), there will be four ‘special’ files in the working direcotry
1. my_program.cpp (the original with markers showing conflicts)
2. my_program.cpp.mine (your updated version which you’re trying to commit)
3. my_program.cpp.5 (the original that you started to work on)
4. my_program.cpp.6 (the one in the repository)
Labelling the file my_program.cpp ‘resolved’ will merge the changes
$ svn resolved my_program.cpp
Next do an ‘svn update’ to make sure that there isn’t any other conflict, and then you can proceed with the ‘svn commit’.
Option 3: Throw away all the changes made by others’ and save only your changes:
$ cp my_program.cpp.mine my_program.cpp
$ svn resolved my_program.cpp
In the same way as above, the next thing to do is an ‘svn update’ to make sure that there isn’t any other conflict, and then proceed with the ‘svn commit’.
Note: It’s always a good idea to start with ‘svn update’ before you modify a file under version control by SVN!
2. List of useful commands: here.
3. Conflict resolution: here.