In part II of this article, we learned more about SVN repositories by creating the basic default structure of an SVN project folder, creating a “tag” or a clearly identifiable snapshot of our project, and learned the why and how to begin committing our projects to our repository.
In part III, we'll use our SVN repository to help recover from disaster; relying on stored copies of our source code in the backup facility.
While there are many articles about how to set up and use a source code control system, I found many were limited, dated, or incomplete; or, they dealt with a much larger team approach to coding. This article attempts to translate my lengthy research among this mire into a helpful article suited for the year 2009.
Apologies for Delaying part III? (My, How Time Flies…)
While the "holidays" soaked up my time and energy since part II, it wouldn't be the complete tale. Primarily I was (am) torn by the endless reasons or techniques with using an SVN repository. Suffice it to say, I finally settled on the premise that these articles are geared toward beginners and not destined to be an SVN cookbook.
Once again, I'll reiterate the purposes of this set of articles:
- We are focusing on the lone (hobby?) programmer using Visual Studio
- We are learning to use SVN as a manageable source code backup facility
- We are bridging the gap to (easily?) move into a team programming model
- We're not concerned about which utility is the best solution
So, let's get back in the game already…
Back to Getting Started - Part III
To get us on the same page, I'd suggest we do the following:
- I've upgraded AnkhSVN to version 2.0.6347.433 (the most recent or third version 2 release), so I'd recommend you also upgrade.
- I'd also recommend updating TortoiseSVN and VisualSVN Server and even a daily build of AnkhSVN to the SVN 1.6.1 versions
- Open your source code project in Visual Studio. I'll assume we have a working source code project set up for source control and it's already imported into the “Main” SVN repository. My examples use the SourceOutliner powertoy source project available at CodePlex.com. I'm also assuming we've completed the steps in Part II to create the other SVN folders. The repository structure should look like:
- Open, or "View" "Pending Changes" so it is readily accessible. Typically "Pending Changes" is docked at the bottom.
- Sync the "Repository Explorer" and "Working Copy Explorer" with our project by right-clicking on the solution in the "Solution Explorer," selecting the two bottom-most commands in the "Subversion" sub-menu (Open Folder in Working Copy Explorer & Open Folder in Repository Explorer). This also opens them for viewing, and they are typically docked on the left side.
Note: The tag "release1.0" folder won't be used for this article, but was created in part II.
SVN Source Control Concepts – Part IV
One of the more confusing aspects of SVN is comprehending the possible disparity (or iterations) with varying revision numbers across the repository and working copy. It's not my intent to confuse an already confusing idea, nor to muddy the differences between SVN and other source control systems such as CVS. Therefore, please bear with me or skip over this section if you are easily confused (though this is the bulk of the article!).
While SVN takes a snapshot of an entire project folder and assigns it a revision number, in actuality it makes a "diff" with the previous snapshot. So only the changed files/folders get the updated revision number. Therefore the revision number of a single file is equivalent to a "timestamp" of when it was last changed.
Imagine this scenario - your project has three files: a static/unchanging file, a seldom changed file, and a continually changed file. Let's say the entire project was committed to the repository for revision #1. After 8 revisions of the continually changing file, the seldom changed file was also changed and committed. Then the continually changing file was committed an additional 8 times taking the project to revision 16. If we pull up the repository browser, we'd see the project was at revision 16, but it would show the static file at revision 1 and the seldom changed file was at revision 8.
Likewise, the local working copy records the revision number with each project file based on commits (save to repository) and updates (load from repository). Furthermore, you can commit a single file or update a single file from any revision snapshot independent of the entire project. However, one difference with the working copy is there are no alternate revisions of files, only the one stored on the disk of the working copy (this is the reason we are using SVN, though some OS'es provide a recovery feature). Another difference with the working copy is you can change and save working copy files locally several times and each still carries the revision number associated with the last commit or update, though they are marked as changed. Here's a key concept of SVN - the revision number is assigned, managed, and stored with the repository (copy), never the working copy.
Perhaps now is a good time to look at some more key SVN terms we'll need to understand:
- “Latest Version” is the term AnkhSVN now uses for "Head" (duh!).
- “Base” is the revision number of an item in the working copy as last committed or updated. If the item has been locally modified (since a commit or update), this refers to the way the item was before those local modifications.
- The “Revert” command is like an "undo" or "revert to last saved" command which takes the working copy file back to the Base revision.
- “Committed” adds a snapshot of our local “working copy” into the repository as the next revision. It’s recommended you enter a “log message” in the “Pending Changes” window before you “commit” to annotate what all the changes are. Again, a revision is an entire snapshot of the project, not just a single changed file. We can always add or edit the log message for a revision later, if needed.
- “Previous” attempts to update our local “working copy” to a revision from the repository. In a programming environment with a single programmer, I can't think of a reason an “update” is needed since no one else is “committing” to the repository.
These terms become important when we retrieve or "update" saved copies of our project files in the SVN repository. While "Update to Latest Version" is the typical way to get our project up to date; in a single programmer scenario (remember the purpose of this article?) we'll probably want to "update" to an earlier revision. However, we may only want to "look" at differences (diff) between our working copy and an earlier revision, which is where the real power of AnkhSVN's integration comes in.
Using the Repository to Recover from Disaster
Next we'll perform some exercises. It would be impossible to cover every reason or technique for "updating" our local working copy from the SVN repository. I'll not even attempt to speculate on reasoning, but stick to performing a few simple tasks in this section, so you'll have to extrapolate from what is covered here.
For the purposes of our exercise, I'll be updating the version number of the sample project "SourceOutliner" to 1.1. Specifically, I'll enter "1.1" in line 16 (
VersionString) of PackageConstants.cs and as the 4th parameter in line 44 (
InstalledProductRegistration) of VsPkg.cs. We'll save both files, then update the repository with a log message of "Updated version number to 1.1"
(View History) Let's take a look at our repository revisions. Right-click on the solution in the solution explorer and select "View Solution History" to bring up the history window.
Within the "History" window, you can right click on any of the items and perform quite a few actions. Likewise, we could similarly pull up a project or file history and see slightly pared down information.
Most likely we'd never blindly "update" to an earlier revision. In fact, we may not want to replace a working copy file with an earlier revision of itself, but bring back only a few of the changes.
(Compare) Let's look at how some of the previous revisions differ from our working copy. Though there seem to be a hundred ways to bring up this information, right-click on the file in the solution explorer and select "Subversion" then "Compare..." We'll want to compare from "Previous" to "Working". You may have to select (check-off) the file in some cases.
Which brings up a standard "Diff" window we can scroll through.
(Unified Diff) Or perhaps you want a (patch) file listing the differences. Right-click on the file in the solution explorer and select "Subversion" then "Unified Diff..." We'll want to compare from "Previous" to "Working", the dialog is similar to the "Compare" command, but creates a patch file and opens it.
(Update to a Previous Version) Perhaps you are brave enough to try and bring an earlier revision back into your working copy. In that case, right-click on the file in the solution explorer right and select "Subversion" then "Update to Specific Version..." which brings up a somewhat familiar dialog.
The older revision is now in the working copy, but NOTICE, it's not marked for commit! If you perform an "Update to Latest Version" it'll be replaced by the latest version. If however, you need to use this older version, you'll need to modify, save, and commit it to the repository.
There are likely other commands that may be useful which are not covered here. In fact, I've not found a "merge file" type feature in AnkhSVN. This may be of use in these scenarios allowing you to pick and choose sections of changes instead of replacing entire files or manually editing changes back in.
We've come to the end of this set of beginner's articles. Though we've only scratched the surface of techniques used with SVN repositories, we have gained a better understanding of their practicality.
In summary, in this article:
- We learned a great deal more about SVN repositories, especially revision numbering.
- We learned to perform a "diff" with a previous revision.
- We learned to restore a file to a previous revision.
This concludes my series of articles about beginning to use SVN.
- Mar 7, 2009 - Began working on this, my third article for CodeProject