Source code control systems offer more than the possibility of keeping one programmer from stomping on another programmer's changes. The other face of source code control is version management. Version management allows you to keep track of old versions of your source code.
There are many reasons to ask, "How did the system work yesterday?" (or last week, or last month, or last year). At the very least, it pays to maintain every released copy of the system. If a clientcustomer, beta tester, another developer on the teamdiscovers unexpected behavior, it's a lot easier to separate the bugs from the user errors if you can reproduce the client's system. And you probably can't produce a patch unless you have all of the source code that was used to produce that system.
You'll often want to be able to reproduce versions that are more fine-grained than those released to the public. Every check-in represents a different version of the system, with bugs, bug fixes, and features that will be a little different from every other version, released or otherwise. A tester, beta-tester, or other developer who attempts to use that version will require maintainers to be able to reproduce exactly that version of the code to investigate bugs. For example, if a tester finds a bug in a version of the system from 2:00 p.m., it's imperative that the bug be reproduced against the 2:00 p.m. code, even if that bug was fixed at 3:00 p.m. Otherwise, you can't be sure whether the bug was a flaw in the testing. If you can't trust your testing, you can't be sure that the bug is fixed.
Professional source code control systems allow you to reproduce the software at any point. Most even allow branch versions. Branch versions occur when you have to make changes to out-of-date source files. When old versions of the system can't be replaced with new versions, but the bugs need to be fixed anyway, you create a branch version of the system, as shown in Figure 1.
Figure 1 The history of a program.
Sometimes the bugs you need to fix for version 1.2 have already been fixed in version 2.0. Those can be pretty confusing times for software maintainers:
Charlie: We need to fix the problem with bad text wrapping.
Deb: I thought we already fixed the problem with bad text wrapping.
Charlie: Good point. I'll have to get back to you on that.
Even if the bad text wrapping has been fixed in version 2.0, you can't always convince users to upgrade. Major releases (as indicated by a change to the first number) usually cost money, and users may be unwilling to spend that money for a new release that comes with other improvements that they're not willing to pay for. Version 2.0 may require a hardware upgrade (like a controversial upgrade to Windows XP), or version 2.0 may simply have received bad reviews, and users prefer to stick with what they know.
But we often owe users bug fixes anyway, even if only to keep their goodwill until they decide to upgrade to the new version. Thus, you have to dig out an old version of the software and fix the bug. If the old version was very long ago, this can be a challenge of software archaeology.
In some ways, version 1.1.1 and version 2.0 have now become completely different software. Changes to one are not automatically propagated to the other. When you're done, you may have to go back and make the change again to the code in version 2.0. This is very stressful on the development team, so I try to avoid doing it. It's a lot more fun to just encourage users to keep up to date with the latest copy. But you have to be prepared to replicate work between current and old versions of the system. How long you're going to keep maintaining old systems is a management decision, not a maintenance decision. Be prepared for upset users when you tell them that you're not going to fix bugs in an old version without more money.