Source Control
This page is dedicated to being a tutorial and methods reference for source control, specifically treating the subversion source control system. You will find here:
- Tutorials for beginners' use of source control.
- Examples of less-common source control operations.
- Details on policy and etiquette for the repository.
The page is under constant contruction at this point; you will probably see relevant material appear very shortly.
Good Practice for Version Control
The following are the golden rules:
- No autogenerated files in the repository. Check in the scripts and a makefile to run them.
- Do not do a regular filesystem copy (cp in linux) in the repository; use svn copy as detailed below.
- Develop new features in branches. Fix bugs in the trunk.
- Merge branches with the trunk at stopping points.
Structure of the Repository
The repository is broken up into three primary root directories: trunk, branches, and tags. Each of these directories has a unique purpose, and the entire project benefits from our correct use of them, as described below. Don't be intimidated by this; it's just there to help us, and nothing can be done that can't also be undone.
trunk is the most important of these directories; it represents the main course of development. Most bug fixes and general improvements are made in the trunk. If you're working on a small feature or an easy fix, you should develop with a copy of the trunk.
branches is used to develop dangerous, experimental, or highly disruptive features separately from the rest of the code. The general process for creating a branch (described in detail below: Branching and Soft Copies) is to create a soft copy of the trunk directory and put it in the branches folder. This soft copy includes all of the files and revision history of the trunk at the time it was made. Once it is copied, however, the branch does not change with the trunk, and neither does the trunk change as you make new changes to the branch. You develop a feature in a branch (checking in regularly, just like you would in the trunk) until the branch code is stable by whatever measure. At this point, you merge the branch back into the trunk, so everybody else is up-to-date with what you have done. You can also merge recent changes to the trunk into your branch, so you stay current with the rest of the project.
tags is used for taking snapshots of the code at different points in time. You might, for instance, create a first_working_application tag or a version_1_0 tag. Creating a tag is exactly like creating a branch; the only difference is that, by convention, tags are never modified like branches are.
Common Commands in Subversion
Checking Out the Code
svn checkout \ svn+ssh://username@yt.acm.uiuc.edu/afs/acm.uiuc.edu/sig/soft/tdb/trunk
If you know what you want, replace trunk with branches/myBranch, or anything else in the repository. Yes, you must have an acm user account in order to check out code.
Branching and Soft Copies
To create a new branch "mySpecialFeature" from the trunk, use the following command (substitute your login for 'username'). You don't have to check out or change into any particular directory, since it uses URLs (a server-side copy). Pick a descriptive name for your branch.
svn copy \ svn+ssh://username@example.com/var/svn/example/trunk \ svn+ssh://username@example.com/var/svn/example/branches/mySpecialFeature
With this command, subversion will make soft, "link"-like copies instead of actually duplicating the content of the files to a new place. This takes up much less space. You can make copies anywhere, not just to branches, as long as it's all in the examplerepository.
If you use the file:///... url form, this line is shorter; you need to do that on example.com, though.
Merging a Branch
Merging is the process of applying differences between one file and another file in the repository. Usually, you will be merging a branch (wherein you developed a feature) into another branch, or more frequently into the main development trunk. This how-to assumes you are merging a branch into the trunk. The process is:
- Check out the trunk (where you are merging into)
- Determine the range of changesets you want to merge.
This is the critical step, I have realized. Suppose I branched my feature at revision 753, and now at revision 790 I want to merge that branch back into the trunk. I don't want to merge based on the differences between the two branches; that would mean "pick one of these and apply it". What I want to do is merge everything I changed between version 753 and 790 in my branch as a single change to the trunk.
- Run the merge command against your working copy of the trunk.
The two URLs you merge should read, left-to-right, the range of changesets you want to apply. In the example we began above, the following would be our merge command.
svn merge \ svn+ssh://username@example.com/var/svn/example/branches/mySpecialFeature@753 \ svn+ssh://username@example.com/var/svn/example/branches/mySpecialFeature@790 \ ./trunk
- Test and refine the results of the merge.
- Commit the trunk just like you would any old change.
It is good practice to periodically merge the trunk into your branch, so that surprise changes are kept to a minimum. Also, this ensures that you are acting with full knowledge of the behavior of the trunk.
