Every article and book I have seen on using version control has discussed it from the standpoint of team — which makes sense, since it is certainly essential in that environment. But often I work at home, either for a client or on my own shareware, and I wondered if the benefits of version control could be realized in such a standalone environment, without imposing too much of a burden in terms of installation or administration.
Version Control Alternatives
Whenever you bring up subject of which version control system to use, there is always short list (see, for example, this Lounge thread) that people recommend:
I am probably most familiar with Visual SourceSafe, since a lot of the work I do involves Windows, and companies use SourceSafe simply because there is no extra expense — it comes free with DevStudio and MSDN. Having survived several near-disasters with SourceSafe database corruption, I wanted to try other solutions. I have heard many good things about Vault, but wondered about heavy database requirement. I was finally left with Subversion, which I have used before on Linux. So then I turned to TortoiseSVN, a Windows GUI for Subversion.
First, some nomenclature: when I refer to "Windows Explorer" or just "Explorer", I am talking about Windows file manager/shell, not about Internet Explorer.
I started by installing Subversion after downloading it (3.3 MB) from Subversion web site, since I thought it would be good to have Subversion to fall back on, in case there was something I couldn't figure out with TortoiseSVN.
For the rest of this article, the only user interface I will be discussing is one available via TortoiseSVN GUI. Please refer to the Subversion documentation if you want to experiment with Subversion command-line interface.
Next I installed TortoiseSVN after downloading it (7.6 MB) from the TortoiseSVN web site. The TortoiseSVN web site has a lot of information, including screenshots, about TortoiseSVN. It turns out that entire TortoiseSVN GUI is implemented as Windows Explorer add-in (right-click context menu).
The TortoiseSVN download includes a chm help file, but I also downloaded a single-page HTML file from SourceForge because I don't like searching in HTML help. (The Subversion manual is available here in a single-page HTML file).
OK, with TortoiseSVN installed and documentation handy, I was ready to try it out.
One thing I have been meaning to do is update my XWinVer article for Vista. It seemed like the perfect choice — first, there was pre-existing code, which I wanted to put under source control; then, I wanted to generate a new version from this initial base.
Repository Directory Structure
In the Subversion manual and other articles, you will see directory trees that look like this:
When I saw this structure so frequently referenced, I thought at first that this was some kind of mandatory hierarchy that Subversion expected; but after some experimentation, I realized that this was not the case, and in fact you are free to set up whatever hierarchy makes sense for your project. In the case of XWinVer, I unfortunately did not have original 1.0 sources — the version currently on CodeProject is actually 1.1. This meant that new version that I wanted to create would be 1.2. So I envisioned structure like this:
OK, so how does Subversion know about 1.1 and 1.2? This leads to next topic.
Subversion Revision Numbers, Tags, and Branches
When you see the term "revision number" or just "revision" in dialog or documentation, it refers to the integer value that increases by one each time you check in file or directory. From TortoiseSVN documentation:
"Each time the repository accepts a commit, this creates a new state of the filesystem tree, called a revision. Each revision is assigned a unique natural number, one greater than the number of the previous revision. The initial revision of a freshly created repository is numbered zero...
Unlike those of many other version control systems, Subversion's revision numbers apply to entire trees (HD: emphasis mine), not individual files. Each revision number selects an entire tree, a particular state of the repository after some committed change. Another way to think about it is that revision N represents the state of the repository filesystem after the Nth commit. When a Subversion user talks about "revision 5 of foo.c", they really mean "foo.c as it appears in revision 5." Notice that in general, revisions N and M of a file do not necessarily differ!"
You can find out what the revision number is by looking at the log, and you might have to do that if you want to retrieve a specific set of source code. In general, however, you can pretty much ignore revision numbers, since Subversion offers a much handier way to name and manage coherent set of source code: tags. In the way I set up the XWinVer repository, each version (1.1, 1.2) is tagged. If I ever wanted to come back to a previous version, I could simply get source code that I tagged, rather than figure out a revision number that was applied on some date and time. You can read detailed descriptions of tags and branches in TortoiseSVN and Subversion documentation.
One Project, One Repository
There is another choice you must make before planning your directory layout. You can choose to have all your projects reside in a single repository, or you can set up each project (like XWinVer) in its own repository. This really depends on nature of your projects — whether or not they are closely tied together. Practically speaking, the only real difference is that repository-per-project makes it simpler to move projects around, and the repository log file won't be so big (in case you have to browse through it at some future time). These considerations might not be as important in the long run, but since I'm approaching this on a step-by-step basis, I decided to use repository-per-project.
FSFS vs. Berkeley DB
Subversion supports two types of repository storage systems: FSFS and Berkeley DB. FSFS seems to be leading choice currently, because of its insensitivity to interruptions, platform independent storage, and smaller size; you can read more about both these types in Subversion manual, Chapter 5.
There is no need to install Apache, or set up Subversion server, or IIS, or run any kind of NT service. Basically, if you are reading along in the TortoiseSVN manual, you can just skip all of Chapter 3, since repository will be stored locally.
Repository vs. Working Directory
Previously I talked about creating 1.1 and 1.2 subdirectories under XWinVer repository. This was not entirely precise. In fact, after you create a repository directory hierarchy — up to and including the repository directory itself (in this case, \XWinVer) — you should not modify or add anything to the repository directories or files that will be created in them. Instead, you should add additional directories (like 1.1 and 1.2) underneath working directory hierarchy, which is created when you do initial checkout, and that holds a working copy of source. This will become clear in steps below.
Naturally, with its Unix heritage, there is possibility to endlessly tweak Subversion config files. I tried many different tweaks, and at end of this article I will discuss tweaks I actually kept. Chapters 5 - 7 of Subversion manual has detailed information on what you can tweak and what the effect will be.
Step By Step
Some of the images below have been edited to reduce size.
1. Create Repository Directory
You can create a repository directory anyplace you like. Since I want to group together my CP articles, using Windows Explorer I created CP_SVN_Repositories directory, and underneath that I created XWinVer directory, which will be a repository directory for XWinVer project:
2. Create Repository
With the repository directory created, I can now create a repository using TortoiseSVN. I right-click XWinVer, and see Explorer context menu:
I click on Create repository here... and this dialog is displayed:
I click OK and see this:
TortoiseSVN has now created some subdirectories and files in XWinVer:
I have now created XWinVer repository; from this point on, all file and directory operations will be performed on a working directory, which is created in the next step.
3. Create Working Directory
I right-click the XWinVer repository directory, and choose SVN Checkout....
This is not what I want, because I want to keep a working copy of the source ("checkout directory") separate from the repository directory tree. So I change D:\CP_SVN_Repositories\XWinVer to D:\CP_SVN_WorkingCopies\XWinVer and click OK. Then TortoiseSVN asks permission to create a working directory for XWinVer:
When I click Yes, TortoiseSVN displays:
The working directory structure looks like:
Notice that TortoiseSVN has created .svn subdirectory; this is referred to in Subversion documentation as working copy administrative directory, and should be left alone.
Notice also that folder icon of D:\CP_SVN_WorkingCopies\XWinVer has been decorated with an icon overlay. This is one of several overlays that TortoiseSVN uses to signal state of files and directories. The overlays you will see most often are:
|indicates "normal" state, for file or directory that is in sync with what is stored in repository.
|indicates "changed" state, for file or directory that has been modified but not yet committed.
|indicates file or directory that has been added but not yet committed.
|indicates that file or directory has been scheduled to be deleted from version control, or file under version control is missing.
Other icon overlays are described in Chapter 5 of TortoiseSVN
4. Create Initial Project Directory
I create directory 1.1 under D:\CP_SVN_WorkingCopies\XWinVer using Windows Explorer, right-click on D:\CP_SVN_WorkingCopies\XWinVer\1.1, and choose Add from TortoiseSVN menu:
TortoiseSVN pops up this dialog:
I click OK and TortoiseSVN displays:
I click OK and when I look at working copy directories, I see:
Notice that XWinVer is decorated with "out of sync" icon overlay, and that 1.1 is decorated with overlay for "just added but not committed". And again TortoiseSVN has created .svn subdirectory under 1.1.
5. Add Project Files
Now I can add current source files for XWinVer to the working directory. I do this with a standard Explorer drag and drop from the old source directory.
It is possible to use Import on TortoiseSVN menu to add files, but I am deliberately trying to use only smallest set of TortoiseSVN commands, to minimize learning curve and unintended side effects (i.e., the command does something that I don't want and may not even be aware of).
Then I right-click on D:\CP_SVN_WorkingCopies\XWinVer\1.1, and choose Add from TortoiseSVN menu, just like I did above. TortoiseSVN displays this dialog:
This dialog is one of the things that makes TortoiseSVN so easy to use in Windows environment. By unchecking any of the files that TortoiseSVN has found, you can prevent it from being added to repository. But what if there are some files — say, with .bak extension — that you never want to add? Do you have to keep unchecking these files? As I discuss below in TortoiseSVN Settings section, there is very simple way to make TortoiseSVN always ignore these files.
I click OK
I click OK, and working copy directory now shows this:
Notice how all newly added files are decorated with overlay for "just added but not committed".
Committing these files is next thing to do (this is also known as "checking in"). I right-click on D:\CP_SVN_WorkingCopies\XWinVer and choose SVN Commit..., and TortoiseSVN displays:
In above dialog I have entered message that will be logged for this revision (TortoiseSVN questions my use of word "checkin" by underlining it in red — you can right-click any underlined word to access TortoiseSVN's spell checker.)
When I click OK, TortoiseSVN displays:
I click OK, and the working copy directory now shows this:
All the green icon overlays indicate that everything is now in sync with repository, and I am finally ready to create a new 1.2 working directory.
6. Create New Project Directory
To start I right-click D:\CP_SVN_WorkingCopies\XWinVer\1.1, and choose Branch/tag... from TortoiseSVN menu:
Notice that — even though I clicked on working copy directory — dialog is displayed with path pointing to repository. This is normal behavior, since what I want to do is tell the repository about my new project directory; later, when I update project, TortoiseSVN will create new working directory (1.2) for me.
I need to make some changes. First, I change To URL path to point to 1.2 — it will be automatically created. Next, I enter message for log. Finally, I select the checkbox at bottom, so working copy will be switched to new 1.2 directory:
I click OK and this is displayed:
However, as I mentioned above, all I have been doing with these last few operations is telling repository how I want to set up project structure. To actually realize this new structure in my on-disk working directory, I need to do an update. I right-click on D:\CP_SVN_WorkingCopies\XWinVer (the project directory, NOT the 1.1 working directory!) and choose SVN Update. This dialog is displayed:
The above dialog tells me that repository is now at revision 2 for this project.
If you see no changes in the Explorer window, don't panic! Just hit F5 in Explorer and you will see new 1.2 directory, fully populated with all files from 1.1:
Notice that repository directory structure shows no indication of two working directories 1.1 and 1.2:
Subversion has a tweak for just about anything you can think of. I initially started browsing through these — in Chapters 5 - 7 of Subversion manual — but there are only so many hours in the day, and I didn't find any that were really compelling.
TortoiseSVN itself offers an interface to some tweaks; right-click on your project directory (in my case, D:\CP_SVN_WorkingCopies\XWinVer), and choose Settings from TortoiseSVN menu. This brings up Netscape-like settings dialog, which has many options for look and feel, external tools, etc.
On General page, there is Subversion section that allows you to specify Global ignore pattern. This is where you can tell TortoiseSVN to ignore files that have particular extension, and even entire directories. Here is how I set it up:
I specified 5 file extensions and 2 directories to ignore — so these files and directories will never be automatically selected to be added to the repository.
Many readers have emailed me about various plugins available for developer IDEs. I have not tried these myself so I cannot recommend them, but they may be useful for you. As always, you need to decide if plugin behavior (how it might destabilize IDE) is acceptable, for the value it adds. Here are the ones most often mentioned:
- AnkhSVN - free Subversion plugin for VS.Net 2002-2005. You cannot create a repository with Ankh, so you must have Subversion or TortoiseSVN installed as well.
- Subclipse - free Subversion plugin for Eclipse. This article explains how to install Subclipse.
- Pushok SVN - shareware plugin for Visual Studio (MSVC 5.0 - 7.0, according to web site).
In this article I have discussed how to set up TortoiseSVN, using one of my CodeProject articles (XWinVer) as an example. With this preparation, in Part 2 I will discuss how to use TortoiseSVN as I create new version of XWinVer.
- Version control basics
- Subversion web site
- Subversion manual
- TortoiseSVN web site
- TortoiseSVN manual
Version 1.1 - 2006 July 28
- Added section on IDE plugins.
- Minor formatting changes.
Version 1.0 - 2006 July 17