Using Subversion
Subversion (SVN) is arguably the most popular version control software. Originally created by Tigris, it is now part of the Apache Software Foundation (and thus distributed under the Apache License).
Version control softwares (also known as revision control softwares or source control softwares) are collaborative tools that aim to resolve problems commonly faced by a team of developers working on the same project. How can everyone on the team work in the same file(s) without overwriting each other? How to keep track of changes, while being able to go back to a previous version if needed? How to maintain multiple versions of the same product, while, at the same time, avoiding a painfully maintainable amount of somewhat similar copies?
Probably the best-known revision system to the general public is the one that is integrated in Microsoft Office since Office 2007. It is the mechanism that provides, among other things, the ability to comment a document in Word and then to go from "bubble to bubble" to revise the document.
Version controllers are also useful when a project is the work of a single person. It provides easy (often off-computer) backup capabilities, with added bonus functionalities like progress logs or the possibility to revert to an earlier version.
For those interested in that sort of thing, source controllers are often used to make statistics about a project: number of lines, growth rate, ...
Every field comes with its bunch of words that describe common concepts in that field. There are quite a few, but here are the essential ones.
A (Subversion) server is the (most often network-enabled) computer on which the Subversion server process runs. It keeps a central version of a project called the repository. That repository can be updated by contributors to the project. Contributors are users of the repository.
Users (most often) use a different computer from the server. Their computer are the clients. They run the Subversion client software to talk to the server. Every user is able to get the project (from scratch, the checkout) or to update their working copy. The working copy is the local copy of the project on a user's computer. It reflects a certain version of the project (not necessarily the latest). Files in the working copy can be edited. It is the user's job to periodically update their working copy to the latest available version on the server. When the version on the server matches the version of the user's working copy, the user can commit the changes into the server. A new version will then be available on the server with the latest changes.
The update process is a totally desynchronized one. Users update on their own will. They do not need to update every time there is a new version, but once they update, their working copy will always reflect the latest changes made to the project.
Subversion is primarily targeted at developers. So it mainly deals with text files. That doesn't mean it can't handle binaries (e.g. icons of a program), just that it can't track changes in them. In text files, on the other hand, it is able to detect (and sometimes automatically correct) conflicts. Conflicts occur when multiple users work in the same file at the same time. (Note that, since the update process is desynchronized, "at the same time" really means "between two successive updates of a working copy".)
The model used by Subversion is the server/client one. There is a single server and every user connects to it to make or get changes. Other version controllers (e.g. Mercurial) use a distributed model in which multiple servers are available and punctually synchronize with each other. A user can then select one of these servers (usually the closest to them) to work with. Like always, advantages may come out of that distributed infrastructure: if a server fails, the others will still work; any of the server is able to completely recreate another server's repository; ...
This article will focus on the use of Subversion. I will not talk about branching (the "how to have multiple similar projects" part). Originally, I intended to do a simple aide-mémoire for myself with the common commands that I use. Then I decided to cover the possible authentication methods for Subversion, since I couldn't find anything that suited me when I installed Subversion. So the page gradually grew to become this. Hopefully, it will be useful to someone :)
Installing SVN
Server
Unix / Linux
The subversion server is most likely available in your package repository. In Archlinux, the package name is subversion.
Once installed, you may want to configure your system to run the subversion server as a service by adding svnserve in your rc.conf file (or inetd.conf, or what have you).
Usually, only limited rights are given to svnserve. Hence, it is usually not run as user System. Most often, a specific user (say user svn) will be created to run the daemon.
Systems using rc.d can edit the script located at /etc/rc.d/svnserve and add
Arguments to the daemon can be given by modifying the SVNSERVE_ARGS variable. As such,
sets the repository root path to /home/svn/repositories. Other popular locations are /srv/svn or /var/svn. Don't forget that if you're running the server as user svn, user svn has to have read and write privileges to that base path.
Sysems using inetd.d can edit file /etc/inetd.conf and add the following line to it:
where the first svn is the service name for Subversion, as defined in /etc/services while the second one is the username to run the daemon as. /usr/bin/svnserve is the full path to svnserve. Finally, the -i option tells svnserve that it is being run through inetd.d.
If your distribution uses another initialization program, you probably know better than me how to achieve that configuration on it. If not, consult your distribution's documentation.
To manually launch the SVN server, run svnserve in a terminal.
Windows
A pre-packaged version with a graphical installer is available at CollabNet. (You must be registered with CollabNet to be able to download, but the registration is free.)
Once installed, you may want to configure your system to run the subversion server as a service. In order to do so, you can (graphically) add an entry in services.msc. Alternatively, you can enter the following command in a command prompt:
Obviously, C:\Program Files\CollabNet\Subversion is the path you have decided to install SVN in. C:\svn_repositories is the base path for every repository (i.e. that means every repository is located in C:\svn_repositories). The whole --root C:\svn_repositories is an optional argument to svnserve, but it is good practice to specify it. Please note that if there is any space in the root repository path, the correct way of specifying it would be (for example) --root \"C:\My Documents\svn_repositories\" (i.e. with the escaped quotes \").
If Windows asks you choose an account to run the service as, select the local service account (NT AUTHORITY\LocalService on systems in English). You can also specify it by appending obj="NT AUTHORITY\LocalService" to the previous command.
To manually launch the SVN server, run svnserve in a command prompt.
Change the listening port
The default port for SVN is 3690. If, for some reason, you want to change it to something else (say 3691), you only need to append
to the arguments passed to svnserve.
Authentication methods
Multiple methods for authenticating the client can be used.
The basic authentication is the default mode that "works out of the box". It authenticates a user with a (classical) username/password combination. However, all exchanged data (authentication or not) is not encrypted. It is the most popular method for authenticating users with SVN (probably out of laziness). No further configuration is requested to use the basic authentication. To setup username/password entries associated with a repository, see section Create a repository.
Authentication can also be carried out under SSL. Obviously, the exchanged informations are then protected via SSL. The SSL part is carried out by a third-party software.
The most common third-party is the Apache web server. (Don't forget that the Subversion project is now handled by the Apache Software Foundation.) Apache will then use the HTTP header-based authentication to provide access.
For those who don't have (or don't want to use) Apache, the Cyrus SASL library can be used to provide secured data exchange.
Finally, SVN authentication can be done through SSH. In that case, the client first signs in with SSH (which means every contributor to the repository must also be a system user), and then plain-text SVN informations are exchanged within encrypted SSH packets.
Authentication over SSL with HTTPS (and Apache)
Make sure that modules mod_dav, mod_dav_fs, dav_svn_module, and authz_svn_module are correctly installed, loaded and enabled.
Then, edit file /etc/apache2/mods-enabled/dav_svn.conf and add
DAV svn
SVNParentPath /home/svn/repositories
AuthzSVNAccessFile /home/svn/.svn-policy
AuthName "Subversion Repositories"
AuthType Basic
AuthUserFile home/svn/.svn-auth
Satisfy Any
Require valid-user
</Location>
/home/svn/repositories is, like above, the root path for the repositories. Please note that, now, user svn is not the only one who should be able to access it. User www-data (or whatever Apache runs as on your system) also has to.
Modifying dav_svn.conf results in making each of your virtual hosts svn URLs handled by subversion (i.e. http://virualhost1.tld/svn and http://virualhostN.tld/svn will both be handled by SVN). If you want to restrict SVN handling to a particular domain, instead of adding the previous code to dav_svn.conf, put it directly in /etc/apache2/sites-available/virtualhost under the <VirtualHost> tag. To make it only available under SSL (i.e. only with HTTPS), add it to the virtual host entry that handles HTTPS traffic (usually the <VirtualHost IP:443> one). (Obviously, this authentication method works just as well without SSL, but why would you go through all this trouble if you're not going to gain on privacy? If you don't want to have encrypted data streams, you might just stick to the basic authentication.)
Obviously, the above configuration relies on two other files: /home/svn/.svn-policy and /home/svn/.svn-auth. The first one defines policies by user for a repository. The second one stores the user/password associations.
Please note that because the authentication file is global (i.e. the .svn-auth is unaware of the different repositories), a single user will not be able have different passwords for different repositories.
I cannot stress hard enough that if you're going to use this method of authentication, it is
- ridiculously complicated if you're not going to take advantage of SSL encryption,
- necessary that Apache (i.e. user www-data) can access all the requested locations; that includes the repositories, and the policy and authentication files.
Normally, this whole configuration should work just as well on Windows, provided that you change the paths to the Windows equivalent ones. (I've always found it cumbersome to work with Apache modules on Windows).
Authentication over SSL with Cyrus SASL
The Cyrus Simple Authentication and Security Layer is a software library developed by folks at Carnegie Mellon University. It enables authentication and encryption capabilities for any network protocol. Since version 1.5, Subversion has been able to use that library.
Once SASL is installed, you have to create a configuration file for svnserve, let's call it svn.conf. Windows users will find it convenient to put it in the installation directory of the svnserve executable. For Unix / Linux users, that executable is most likely located in /usr/bin and you will certainly not want a configuration file there. Put it wherever you like (hint: /home/svn/svn.conf), and append
when you call svnserve.
Fill that file with the following informations:
auxprop_plugin: sasldb
mech_list: DIGEST-MD5
sasldb_path: /home/svn/.sasldb
The sasldb database contains username/password associations. Please note that the service has to be able to access that file. So, if you specify the --root argument when you run svnserve (if not, you really should!), the database has to be somewhere in there. So it will certainly be located in a common parent directory to all the repositories.
Finally, the SVN server has to be aware of the location of the SASL library. In Unix / Linux, that means svnserve must be compiled with SASL support enabled. In Windows, if you've installed the CollabNet version, everything has already been taken care of. If not, you should add two string keys in HKEY_LOCAL_MACHINE\SOFTWARE\Carnegie Mellon\Project Cyrus\SASL Library:
- SearchPath with the directory containing the sasl*.dll files,
- ConfFile with the directory containing the svn.conf file.
I cannot seem to understand how to provide read-only access to authenticated users with this method so maybe it is not (currently) possible. If read-only encrypted access is important to you, you may want to check another authentication method.
Authentication with SSH
When tunneling SVN into SSH, it is unnecessary to run the Subversion server as a daemon. Indeed, whenever a user logs in svnserve can be run (with that user's rights), and terminated when the user logs out.
File rights management is trickier when using this method, since it is the real end-user that accesses the repository (not some fictional user svn). Some administrators like to create a group per project and assign the rights to the repositories by groups. Others just manage each repository directly with usernames. It is your task to decide whether you prefer having a lot of groups (if so, please, use some sort of prefix to the group names to know what is SVN and what is not), or if you'd rather manage everything user by user, and eventually have an "imperfect" user management). Just remember that each user is granted the rights they have on a repository's directory.
It may seem that this is the "shortest way to privacy". However, beware that a bad management of SSH access to your server may have catastrophic consequences. Common sense applies: if you don't know what you're doing, don't do it... (or rather learn how to do it :).
Client
Unix / Linux
The subversion server is most likely available in your package repository. In Archlinux, the package name is subversion.
Windows
A pre-packaged version with a graphical installer is available at CollabNet. (You must be registered with CollabNet to be able to download, but the registration is free.)
Server-side commands
Create a repository
To create a new repository, open a console/command prompt and go to the root directory for your repositories. Then type
where myRepository is the name of the repository to create. Alternatively, you can use the full path to the repository:
Once the command is executed, a new directory should be located in the root repository folder. It should contain (at least) a conf directory.
Add users to the repository
The method to add users to a repository depends on the authentication method you have selected. (Please note that it is possible to select different authentication methods for different repositories. You can also imagine authenticating some users via SSH, while others use an SSL-based authentication, etc.)
Basic authentication
To add a user to the basic authentication, first edit the file myRepository/conf/svnserve.conf. In the [general] section of the file, you can find
auth-access = write
Quite self-explanatory, but in case you didn't get it, anonymous access is granted a read-only right, while authenticated users have read-write capabilities. The values can be any of the three following values : none, read, write. Edit the entries to match your goal.
A bit further down, still in the [general] section, make sure that the line
is not commented (i.e. it doesn't start with a sharp character (#)).
You can also specify the realm by editing the line
(and make sure it is uncommented). The realm is a sort of "authentication domain" for SVN. Beware that two realms mustn't be identical on a server.
Save that file, close it, and open passwd located in the same folder.
In the section [users] of passwd, you can add users with the following format (one entry per line):
Yes, the password is stored in plain-text.
Once you're done, save the file and restart svnserve (I'm not sure it is necessary on every system).
The repository is now available at
Authentication over SSL with Cyrus SASL
Just like in Basic authentication, start by editing myRepository/conf/svnserve.conf. You can comment (i.e. add sharp characters (#)) the whole [general] section, since it will be disregarded when using SASL, except for the realm line
Make sure it is uncommented, as you will need the realm value further down. The realm is a sort of "authentication domain" for SVN. Beware that two realm mustn't be identical on a server.
In the [sasl] section uncomment the lines (i.e. remove the sharp character (#))
min-encryption = 0
max-encryption = 256
Obviously, you can set whichever value you fancy for the minimal/maximal encryption value. I recommend you leave the maximum set to 256 (bits), but increase the minimum to 128 (bits).
When you're done, save the file and close it.
In a console/command prompt type
saslpasswd2 is an utility from the SASL library that sets a password for a user. -c indicates that it will create an entry if it doesn't already exist. -f is the (full) path to the sasldb (see subsection Authentication over SSL with Cyrus SASL in the Installing SVN section). -u is the domain. In our case, it is the realm of the repository. Finally username is the username of the user you want to add to the repository. saslpasswd2 will then prompt you to enter the user's password.
Please note that if you have any space in any of the arguments of the previous command (and that include the full sasldb file path), you should use quotes (") around them (just like in the example with My repository.
If you want to remove a user from a domain, you can call saslpasswd2 with the -d argument (which deletes a user) in the following fashion:
Once you're done, save the file and restart svnserve (I'm not sure it is necessary on every system).
The repository is now available at
Authentication over SSL with HTTPS (and Apache)
Let's now define the policy (/home/svn/.svn-policy) and user/password association (/home/svn/.svn-auth) files we talked about earlier.
The policy file should look something like this:
*=r
[myRepository:/]
user=rw
The asterisk (*) is the anonymous access. user is a user for repository myRepository. Obviously, anonymous users have a read-only right, while user user has read-write rights over the myRepository repository. Please note that rights for myRepository are inherited from global rights (in section [/]) so that myRepository also allows read-only access for anonymous users. If you don't want to have anonymous reading rights, you can always overwrite the access with *= in the [myRepository:/] section which grants no right for anonymous users.
The user/password file is something similar to the usual .htpasswd mechanics used in Apache. To add a user, type, in a console,
You will then be prompted to enter the password. The -s option enables the use of the SHA-1 hash algorithm (instead of the default MD5). The first time you add a user, you may also want to use the -c option which creates the file.
The repository is now available at
Alternatively, if you decided not to use SSL (and HTTPS), the address becomes
Authentication with SSH
Make sure the user already has an SSH access to your server.
Create the script /usr/local/bin/svn containing
umask 002
/usr/local/subversion/bin/svn "$@"
which is a wrapper for svnserve. The umask value 002 is a umask that prevents access by other users.
Then, give read-write permissions for the group (or for the user) to the repository directory.
The repository is now available at
Please note that, in this case, both, the repository name (myRepository) and the full path to the repository directory (/home/svn/repositories) are part of the address. The repository path is needed for SSH.
Backup a repository
A backup file of a repository can easily be created. It can be used as a real backup or as means to transfer a repository to another SVN server.
The dump command creates a dump of the repository. Generally speaking, a dump is a raw copy of an object. In this case, the object is the repository. So, you are making a raw copy (i.e. in exactly the same format) of a repository.
To create a dump file of the repository, type the following command (as usual, in a console/command prompt):
/home/svn/repositories/myRepository is the full path to repository myRepository. ~/myRepository.svndump is the full path to the repository dump file (which will be created).
The file myRepository.svndmp contains the whole repository (that includes the different files in the repository, the commits history and logs, ...).
You can store that file or move it as any other file on your system. To add it to another SVN server, use the load command.
Please note that if you're not using the basic authentication, you will have to reconfigure users' accesses if you lose your SVN server. If you use Apache's BasicAuth to authenticate users, backup the .svn-policy and .svn-auth files. If you're using Cyrus SASL, backup the sasldb. Although all of these files contain more than user configurations for myRepository, they certainly do contain it too. You can always manually merge (or recreate) the files on your new server. For the SSH authentication, well... it's all tied to your system: backup your system! (But then why wouldn't you backup the whole /home/svn/repositories/ with it?)
Reload a backup
The load command loads an SVN dump file into an existing repository.
The first thing you have to do is to create a new repository. You do not, however, need to worry about user configuration now.
To load an SVN dump into that new repository (which we'll call newRepo), use the following command :
Obviously, you don't need to give the full path to newRepo if you execute the command from the /home/svn/repositories/ location. ~/myRepository.svndmp is the full path to the repository dump file.
If your original repository was configured to use basic authentication, you're all set.
If you use any of the other authentication methods, you will need to properly reconfigure users' accesses, as indicated in the Create a repository section.
If you're wondering why you have to reconfigure users, just remember that, when using another authentication than the basic one, it is a third-party software (i.e. an entity outside of svnserve's control) that manages accesses to your repository. So, the SVN server can't be aware of those settings since it doesn't "contain" them.
Client-side commands
Checkout
A checkout is the initial import of the project on your computer: it creates the working copy. You only need to do it the first time you connect to the SVN server.
To checkout a repository, use the following command :
where svn://domain.tld/myRepository is the address of the repository and project is the local location to put the files in. (Obviously, if you want to put it in the current location, just use a point (.) as the location.) If you do not specify the location to checkout in, the SVN client will create a folder named like the repository in the current location. user represents the username to log in as. (You will be prompted for your password afterwards.)
After you've been prompted for your password, SVN will ask you if you want your password to be memorized. You have to know that the Subversion client stores passwords locally as plain-text. If it is important to you that your password is not stored in that way, just answer no. You will then be prompted for your password on every svn command you call.
A shortcut for checkout is co so that the shortened command becomes
Checkout can be a long process. It all depends on the size of the project and the speed of your network connection.
Once the working copy is created, you can modify any of the files in it; add (and remove) files to (from) it. However, don't edit (or remove) any of the .svn directories (or whatever is in it). They are part of the SVN mechanism. Should you delete/edit them, you will end up compromising your working copy and you won't be able to do anything with it (except delete it and perform a new checkout).
Update the working copy
The update command updates your working copy by reflecting the changes that have been made in the repository into your local files.
An update is significantly shorter (in time) than a checkout. Performing one regularly ensures that your working copy is up to date (which, in turn, might save you from having to deal with conflicting versions).
To perform an update, type the command
A shortcut to update is up so that the shortened command is
update produces an output very similar to status. Don't forget to check the file states to check it for possible version conflicts.
If you want to "go back in time" and update your working copy to an older version of the project, you can specify the revision number with the -r option. The following version upgrades (although it should really be "downgrades") to version 4:
(you never really lose anything with SVN).
Add (and remove) files to (from) revision control
When you create a new file (or directory) in your working directory, that file isn't automatically added to version control (i.e. Subversion doesn't "take care" of it until you've told it to).
To add your file to revision control, execute the following command in a location that's already version controlled:
filename is the name of the file (or directory) to add to control version. If filename is a directory, it will be processed recursively. If you don't want it that way, you can specify the argument --non-recursive, and the command becomes
A shortcut for --non-recursive is -N, so that the shortened version is
To remove a file from revision control, you can just delete it from the working copy. Alternatively, you can use the command
where filename is the name of the file to remove from version control. filename can also be a directory. In that case, the directory (and therefore everything that's inside it) will be removed from version control.
Shortcuts for delete exist. They include
just line Unix's rm command. One other alternative is
just like the del DOS command.
If you want to remove control version from a file that's been locally modified, you will have to force the removal. Hence, the command becomes
These commands all remove the file both from the local copy and from the repository. In order to remove a file from revision control, but still keep it locally (e.g. a file that was committed, but that should have been ignored), you can use the --keep-local argument, as follows:
Ignore files
You may have files in your working copy that you never want to be "managed" by SVN. You shouldn't normally have build files in your SVN, so that's a good examples of files to be ignored.
Subversion has a bunch of properties. One of them is svn:ignore. It is the property that is going to be modified to ignore certain files.
Let's imagine you have a build directory in your repository. Everything under it should be ignored by version control. (Arguably, you could also ignore the directory itself, but if you want it to appear in the structure of the project, only its contents will have to be ignored.) In order to do so, from inside build, type
The final point (.) indicates that we want to edit the properties (hence the name propedit) for the current location (i.e. location .).
A text editor should open (e.g. nano, vim, notepad, ...). Add masks for files to ignore (one mask per line). In this case, you want to ignore everything, so we will just add an asterisk (*) in the file. (If you only wanted to ignore HTML files, the mask would be *.html (and maybe *.htm).) Save the file in your editor, and close the editor. Filenames that match your mask(s) will then be ignored by SVN.
To change the editor in which the svn:ignore properties are opened, change the SVN_EDITOR environment variable (this is out of the scope of this article, but it is a widely available information).
To make sure everything went according to plan, you can type
(the syntax is similar to propedit), and you will have the list of everything that's ignored in the target location.
Status
You can view the current status of your working copy at any time. Status includes informations about which file was modified, which file was added, which file was modified, ...
To view the status, type
in a location that is under revision control. By default, status doesn't display the ignored files. To display them, use the option --no-ignore:
The shortcut command for status is st:
Here's a typical status answer:
D README
I doc/report/tex/CuteSNMP.dvi
I doc/report/tex/CuteSNMP.ps
I doc/report/tex/CuteSNMP.pdf
M doc/report/tex/CuteSNMP.tex
A doc/report/tex/new
Statuses are indicated in the left column. ? means that the file is not currently under revision control. I means that the file is ignored. M means that the file has been modified since the last commit or update (i.e. the file has local changes). A means that the file is new and has been added to revision control (it is not considered as a "regular" file until it has been committed). Finally, D means that the file has been removed from revision control.
If you type status at the root of your working copy, every directory will be recursively processed (like in the example above). To "filter", just change the location in which you type the command. For example, if I had typed the above command in doc/report/tex, only the files in that location would have been displayed, leaving the files located at the root (i.e. temp and README) out of the result.
Three more statuses exist. They represent file conflicts. They are status U (update), G (merGe), and C (conflict). For more details about these status, refer to section Conflicting versions.
Commit changes
Committing your working copy pushes the changes you've made to the project onto the Subversion server. It is the "inverse" operation of update.
To commit your changes, type the following command:
The commit message is used as a log entry in the commit logs. It is mandatory to put one, although it can be an empty string (i.e. "").
Alternatively, you can use a file as the commit message, with the following command:
where commit_message_file is the file in which the commit message is. It can be advantageous to use a file instead of an in-line message since it is easier to fill-in (in terms of formatting, etc) and can be written while the changes are made to the project (so that the log is completely accurate).
As usual, there are shortcuts for this command too. commit can be replaced by ci (not co which is the shortcut for checkout). The short for --message is -m and the one for --file is -F. The shortcut commands for the previous ones are
svn ci -F commit_message_file
Please note that if Subversion tells you that you can't commit because your working copy is not up to date, you have to do an update first. At this point, you should be very careful for version conflicts. If you have unresolved conflicts you will not be able to commit.
Conflicting versions
Typically, there are multiple contributors to a single project. These contributors may even work in the same file (at the same time). The initial goal of revision control is to avoid problems when that happens. There is no use in updating your work on the server if, when you're doing it, someone else's work is deleted.
The previous scenario leads to conflicting versions: while you were working on a file, someone else was working on it too, and the working copy you have done your work in is not up to date anymore. You can't just send it to the server, you have to merge the two different versions of the file. In other words, you have to resolve the conflict.
As noted in the status section, there are three types of conflicts:
- The version of the file in the repository has been updated to a new version and your local copy has not changed. (Status U)
- The version of the file in the repository has been updated, and so has your local copy. The changes, however, do not overlap. (Status G)
- The version of the file in the repository has been updated, and so has your local copy. In this case, the changes do overlap. (Status C)
In the first two cases, Subversion handles the conflicts all by itself:
- Replace local copy with repository version.
- Merge the two version in a single file (easily done algorithmically since changes don't overlap), and mark that file as changed and ready for the next commit.
Unfortunately, the last case can't be handled automatically. SVN will mark the file as conflicting (meaning that you can't commit it until you've marked the conflict as resolved). To help you do the merge manually Subversion creates three new files:
- conflictingFile.mine: the file as you were going to send it to the server. In other words, the file that you've been working in.
- conflictingFile.rOLD (where OLD is the revision number of your working copy before you've updated it): it is the version of the file before you started working in it.
- conflictingFile.rNEW (where NEW is the revision number of your working copy after you've updated it): it is the version of the currently in the repository.
Please note that conflictingFile is a representation of the filename, not its actual name. If the conflicting file is foo.cpp, the old revision number is 31, and the new one is 36, the you will have the four following files in your directory: foo.cpp, foo.cpp.mine, foo.cpp.r31, and foo.cpp.r36.
To understand how they work, here's a little example (taken from the SVN book). Open conflictingFile (i.e. the (new) content of the file that is in conflict). It will look something like this (the example is a grocery list):
Lettuce
Tomato
Provolone
<<<<<<< .mine
Salami
Mortadella
Prosciutto
=======
Sauerkraut
Grilled Chicken
>>>>>>> .r2
Creole Mustard
The lines filed with <<<<<<< .mine, =======, and >>>>>>> .r2 are conflict markers. They are not part of the original data in any way. Whatever you do, make sure you don't leave them in the final (resolved) file. (Also, please note that none of the three files conflictingFile.mine, conflictingFile.rOLD, and conflictingFile.rNEW have any sort of marker in them.)
The part between <<<<<<< .mine and the equal signs (=======) are the changes you made to the file. The changes made by the other contributor are between those equal signs and the >>>>>>> .r2 separator.
Your job is to make that section of the file (i.e. the one between <<<<<<< .mine and >>>>>>> .r2) coherent (and to remove the conflict markers).
Once you're done, the conflict can be marked as resolved. In order to do so, type
You can also delete the three conflict files conflictingFile.mine, conflictingFile.rOLD, and conflictingFile.rNEW.
Please note that there can be more than one conflict in a single file (and more than one conflicting file). Make sure you sort them all out!
You can resolve the conflict in other ways if you like. If you just want to replace the file with the latest version, delete conflictingFile and rename conflictingFile.rNEW in conflictingFile, then mark the conflict as resolved. In the same fashion, you can put your file as the new version. You can also revert to an older file version. (If you choose to revert, Subversion will automatically mark the conflict as resolved, so you won't need to do it.)
You are now ready to commit.
Revert to an older version
If for some reason you are not satisfied with the changes you've made to the project, you always have the option to revert to the previous version. In other words, you will erase any local change you made and get the files you had the last time you performed an update.
To revert the changes made to myFile, just type
You can also revert the changes made to a directory (say myDir):
If you want SVN to recursively process the subdirectories of myDir, you can specify the --recursive option:
A shortcut for --recursive is -R, so that the last command becomes
Please note that specifying no target location for the revert will have no effect (to prevent you from losing every changes you made by accident).
If you want to go further down than the latest update revision number, you can make use of the update command. Although not specified in the corresponding section, you can specify a target file for update (so that it only updates that single file). To revert back file myFile back in time to revision 82, you can use the following command:
View commit logs
The messages you entered while committing can be viewed with the log command.
Calling
from inside a working copy displays the whole commit log. Here's a typical output of that command
r83 | q | 2010-05-22 18:29:30 +0200 (sam., 22 mai 2010) | 4 lines
Corrected bugs:
- Program assertion failing when changing current user name
- Removed displayed MIB when failing to process a walk on a new agent
------------------------------------------------------------------------
r82 | q | 2010-05-22 07:58:40 +0200 (sam., 22 mai 2010) | 1 line
Bug correction
------------------------------------------------------------------------
r81 | murmex | 2010-05-22 06:05:05 +0200 (sam., 22 mai 2010) | 1 line
correct debug messages
------------------------------------------------------------------------
r80 | murmex | 2010-05-22 05:58:34 +0200 (sam., 22 mai 2010) | 1 line
removing unused files
Let's see in details what the header means. The number number following r (e.g. r83) is the revision number (e.g. it was the 83rd commit). The second column is the user that committed (here: q). It is followed by the commit date and by the number of lines in the commit message (here: 4). The header is followed by an empty line which, in turn, is followed by the whole commit message.
You can search for the commit logs that modified a file. The command is then
and the result will be the commit logs of the commits that modified filename.
You can also restrict the commit logs to certain revision numbers. For example, to get the commit log of revision number 6, type
To get the commit lots of every revision between revision 23 and 32, use the following command:
Notice now the colon (:) separates the bounds of the revision numbers to show.
Please note that you need to be able to access your SVN server to use the log command, as the logs are not stored locally on the client side.
A few more tips
It can be overwhelming to have all those log outputs in your console/command prompt. Here are a few basic tips (this is more dedicated to Windows users, since it is pretty common knowledge in the *nix world):
which will "send" the output in the utility more that will display the text on a single screen height. You can then press the enter key to "scroll" down. (Yes, I know, it is more convenient to use less but more works on Windows too!). You can also redirect the output to a file:
and the file svn_log.txt will be created in the current directory with the contents of svn log. If svn_log.txt already existed before, the new content will be appended to the file.
These stream redirection mechanism not only work with svn log commands, or svn commands: any console/command prompt application that outputs on the standard stream (it is most often the case if there is no user interface) can have its (standard stream) redirected that way.
Relocate
Sometimes, funny business happens: a server changes its hostname, the repository is moved to another server, ... As checking out a project can be quite costly, it would be interesting to only locally change the address of the repository so that the local working copy keeps on going.
The switch command allows you to do that. Here's how to use it:
where svn://old-address.tld/oldRepository is the old address of the repository and svn://new-address.tld/repository is the new address of the repository.
Please note that it will only work if the repositories on both addresses have the same UUID. In other words, it will only work if the SVN server administrator correctly did its work of moving the repository around with the dump command.
To check if relocating succeeded, you can use
and check if the value given in URL is the new one.
Further reading...
For more in-depth informations about Subversion (including functionalities not discussed in this article), consult Version Control with Subversion by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.
Revisions
- September 30, 2010: Initial version.
- October 10, 2012: Added svn rm --keep-local paragraph.