What would you say if I told you that I've found a terrific programmers' editor on the Internet free for the downloading. It has all the great features you find in other editors, except one-there's no "undo." I'm afraid you'd dismiss such an editor without even trying it. And for a good reason! We, programmers, are fallible-we write something, try it, then change our minds, rewrite it, go back to the previous version, and so on. Sometimes we implement a whole elaborate idea only to find out that it won't work. We have to go back to square one-and that's when we desperately need the undo button.
The simplest, most elementary application of a version control system (VCS) is to act as a big undo button. An editor might keep a stack of recent editing commands, but this stack has limited capability and in most cases disappears at the end of your editing session. A version control system has a much bigger stack that is stored persistently between sessions. Obviously, storing the history of all your keystrokes would not only overwhelm your computer, but it would also be very unwieldy. So a version control system stores larger granularity snapshots of your work. And it lets you decide when to take such a snapshot.
Here's how it works in practice. (Each VCS has its own protocol, so I will describe the most generic interface.) Before you start working with a VCS, you have to create a project and add all existing files to it. This will constitute your baseline. During a typical editing session, you will work with a subset of project files. You have to tell the systems to check these files out, using the checkout command-before you start changing them. Quite often your editor or your IDE can collaborate with the VCS. In that case it will ask you whether you want to check the file out, as soon as you start editing it. Once a file is checked out, all your editing is done on a scratch copy of this file.
The first level of VCS "undo" works by undoing your checkout. The "undo checkout," or uncheckout command, returns the file to its pre-checkout state. Whenever you change your mind about modifying a certain file, you can always use uncheckout to clean the slate.
If, however, you are satisfied with your changes, you tell the system that you are ready to take a snapshot: You check the file(s) back in, using the checkin command-this time with your changes. The version control system does not however discard the previous state of the files. In fact, it is supposed to keep all versions of your files in its database, so that you can retrieve them at your convenience. This gives you the option of "deep undo." You can retrieve a snapshot of your files from a day ago, a week ago, or a year ago with the same ease. In practice, no VCS actually stores full versions of each file-that would take too much storage. It is enough to store the differences (called diffs) between consecutive versions. This way, if you modify a single line in a thousand-line file, only this line will be stored in a diff.
A version control system is of great help in independent development-it is, however, absolutely indispensable when a team of developers is involved. Even if you're planning on collaborating with just one other person, a VCS is the second application you should buy (right after a compiler or an HTML editor, depending on your line of work).
When a VCS is used for collaboration, you still have a private copy of the whole project, and you work with the same protocol of checking files out and in. But in order to see the changes made by your coworkers, you have to periodically synchronize you project using the synch command. Synchronization applies the changes made by other developers to your own copy of the project. Only those changes that have been checked in are propagated by synch. This way, team members can test and perfect their changes until they are happy with them-or at least satisfied enough to make their new versions available to others-at which point they check them in.
A typical development cycle might look like this: You decide to implement a new feature, fix a bug, or modify a set of web pages. You checkout the relevant files as the need arises-maybe with the help of your development environment. You make some changes, test them, and make some more changes.
In the meanwhile, your coworkers might be making their own changes. When they check them in, you perform synchronization so that you can test your modifications against their updates. Some systems will notify you about the availability of new versions-others will let you inquire. Occasionally, other members of your team modify the same files you are working on. A VCS will attempt to merge these changes during synchronization. You should review the results of such a merge to make sure that the system correctly guessed your intentions. In most cases your changes and your coworkers' changes will not overlap and the merge will do the right thing.
Finally, when your task is done, you checkin the files you've been working on and thus create a new version of the project. Of course, the VCS makes all these versions of the project available to you. You can restore old versions of any file. You can also look through its history in order to, for instance, find out who introduced the bug you've been chasing for the last couple of days.
A good version control system not only smoothes out collaboration, it can also help establish better programming practices. For instance, it's a good idea to review your changes before checking them in. A VCS should help you in this task by listing the modified files and showing you the diffs on demand. A differ/editor can greatly simplify this task. Similarly, a VCS should be able to help you review the changes made by others, either during synchronization or at a later time, by comparing historical versions. After going through multiple reviews, your code is bound to be more robust and reliable. You'll spend less time debugging and more time creating new exciting stuff.
To summarize, whether you're working alone or in a team, you should look at a version control system as one of the fundamental tools facilitating the development process. A VCS gives you access to previous versions of your project and can coordinates the work of multiple developers. Its use not only enhances productivity, but it can also help improve the quality of your work.