Anyone who codes programs without revision control is stupid. Seriously.
The trade-offs are so high that there’s almost no reason not to use a version control systems (VCS) when programming.
“So what is revision control?”, you might ask.
At its very core, revision control deals with tracking down changes to your work. That definition, however, is a bit misleading. For software development, it’s better to think of revision control as similar to the computer gaming concept of multiple saves.
As gamers will know, one save slot is not enough for larger games like epic RPGs or RTS games. It is not uncommon to encounter a scenario where a player realizes that he has made a terrible mistake 3-4 saves ago. If the game has only one save slot, that player is pretty much screwed as the save has already been overwritten. On the other hand, this won’t be a problem if he has saved on different save slots.
A similar problem pops up often when developing programs. A developer might realize that he made a terrible mistake in the code he wrote some time ago. Without a VCS, the developer only has one “save”: the one currently saved on his computer. He will have to search his files manually in order to pinpoint the location of the problematic code and fix or revert it.
With a VCS, however, the developer is given the ability “save” the current state of his code. As long as he commits (“commit” is “save” in revision terms) often, the above scenario is not going to be a big problem. Instead of manually searching each file for the change, he can look at the revision history which will tell him which files were changed. He can then use the various tools in the VCS to inspect and fix the problem. What would have taken the developer minutes or even hours to fix might only require a few seconds if there was a VCS in place.
The other good thing about VCS is that the setup effort is trivial compared to the countless hours they can save. By trivial, I mean you create those coding “save slots” in just a few steps, as you shall see in the next few paragraphs.
Back when I was working, we were using the primitive Concurrent Versions System (CVS) and right now I’m cutting my teeth into the conceptually advanced Git. For this tutorial, however, we’re going to use Subversion (SVN). It’s basically an advanced version of CVS, but not as advanced as Git. It’s also widely supported (unlike Git): Google Code and SourceForge uses it to track code, and there also SVN IDE plugins for the more popular IDEs.
(I’m also assuming that you’re using a Windows machine. If you’re using Linux or Mac, you’re probably better off with Git.)
The first step is to download and install TortoiseSVN. This will add SVN functionality directly to Windows Explorer.
The next step is to create a repository. This is where your “saves” will be stored. To do this, make an empty directory then right-click -> TortoiseSVN -> Create a repository here. TortoiseSVN will create the files needed by SVN to track the revisions in the files.
Congratulations, you have now made your first SVN repository!
The setup isn’t complete yet, though. We’ve only created the repository but we haven’t actually created the workplace which we would dump into the repository. To do that, go to another folder and right-click -> Checkout.
Add the location of the repository in file:///c:/path/to/repo/ format (that’s three forward slashes). After you click Ok, TortoiseSVN will retrieve (checkout) the repository.
It’s empty now, but you’ll notice that there’s a “.svn” hidden folder in the folder. This contains the information regarding the repository, and in effect links your workspace to the repo.
Let’s add some files to the repository. Traditionally, people add three folders in their initial SVN commit: the “trunk”, “tags”, and “branches” (TTB) directories. We don’t care about them in this tutorial so feel free to add folders and files to the workplace.
When you’re finished, right-click -> TortoiseSVN -> Add.. This command lets you choose which files to add to the repository. Note that this only adds the files to the list inside the hidden “.svn” folder, to send them to the repository you will have to perform a commit.
To commit, right-click -> SVN Commit.. The dialog box will prompt you which files you wish to commit and will also ask you for a “message”, a description for the commit.
The message is optional but in practice, you must provide a meaningful message every time you commit. You don’t need to be verbose with the message, a short description of the changes in the files you wish to commit will do.
What we want to avoid is a blank revision history–a list of revisions with details on the files changed but with no messages. Above is an example of a mostly blank revision history (right-click file -> TortoiseSVN -> Show log). As we can see, we don’t have an idea what the user did to dummy.txt in the 2nd, 3rd, and 4th revisions. Faced with the “oh crap I made a mistake a few days ago” scenario, a blank revision history would force the user to manually check every revision instead of just looking at the revision messages.
Speaking of checking revisions, let’s move on to how we can compare revisions via TortoiseSVN.
One way is to right-click a file -> TortoiseSVN -> Diff with previous version. This compares the current version of the file with its previous version, showing what was added, modified, and deleted.
To compare two revisions with other, you can go to the Log Messages window then Ctrl-click two revisions you want to compare then right-click -> Compare revisions. The revisions don’t need to be next to each other to work–you can even compare revision 1000 to revision 1 if you want.
Now that you know what was changed between revisions, you can now revert the changes. The simplest way to revert changes is to roll back all changes up to a certain revision by going to the Log Messages window and right-click revision -> Revert to this revision. Your local copy will be reverted to that revision and you can now commit it. Of course, that approach is overkill most of the time.
An alternative to the previous approach is to right-click revision -> Revert changes from this revision which, as expected, tries to revert the changes done in that revision. If you’re lucky, that revision doesn’t have conflicts and the changes will be reverted. If there’s a conflict, TortoiseSVN will warn you about it.
I’m used to having Eclipse doing all the dirty work for me so I’m not familiar TortoiseSVN’s approach in conflict resolution. Please refer to the TortoiseSVN manual entry on resolving conflicts for more details about this.
That pretty much covers all you need to know about using SVN to maintain your revision history. Just two quick tips before I end this post:
- You can commit binary files (files that show up gibberish on Notepad) to SVN. However, you cannot directly compare the revisions using the built in compare tool (because they’ll show up as gibberish). To compare two binary file revisions, use Update to revision to get one version, copy the file somewhere else, then use Update to revision again to get the other version. You can now compare the two revisions manually.
- SVN, unlike CVS, allows atomic commits i.e. a single commit/revision can contain multiple files. As much as possible commit all related file changes in one single commit instead of committing one file at a time.
Tomorrow we’ll tackle the basics on using revision control for collaboration.