Subversion Best Practices
Subversion Best Practices©2008 CollabNet Corporation
This is a quick set of guidelines for making the best use of Subversionin your day-to-day software development work. These best practices aretaken from the book Version Control with Subversion.
Use a Sane Repository Layout
There are many ways to lay out your repository. Because branches andtags are ordinary directories, you need to account for them in yourrepository structure. The Subversion project officially recommends theidea of a project root, which represents an anchoring point for aproject. A project root contains exactly three subdirectories:
* /trunk
* /branches
* /tags
A repository may contain only one project root, or it may contain a number of them.
Commit Logical Changesets
When you commit a change to the repository, make sure your changereflects a single purpose: fixing a specific bug, adding a new feature,or some particular task. Your commit creates a new revision numberwhich can forever be used as a "name" for the change. You can mentionthis revision number in your bug database, or use it as an argument tosvn merge if you want to undo the change or port it to another branch.
Use the Issue Tracker Wisely
Try to create as many two-way links between Subversion changesets and your issue-tracking database as possible:
* If possible, refer to a specific issue ID in every commit log message.
* When appending information to an issue (to describe progress orto close the issue), name the revision number(s) responsible for thechange.
Understand Mixed-Revision Working Copies
Your working copy's directories and files can be at different "working"revisions: this is a deliberate feature which allows you to mix andmatch older versions of things with newer ones. But there are few factsyou must know:
1. After every svn commit, your working copy has mixed revisions.The things you just committed are now at the HEAD revision, andeverything else is at an older revision.
2. Certain commits are disallowed:
1. You can not commit the deletion of a file or directory which doesn't have a working revision of HEAD.
2. You can not commit a property change to a directory which doesn't have a working revision of HEAD.
3. svn update brings your entire working copy to one workingrevision, and is the typical solution to the problems mentioned inpoint #2.
Be Patient with Large Files
A nice feature of Subversion is that by design, there is no limit tothe size of files it can handle. Files are sent "streamily" in bothdirections between Subversion client and server,using a small, constant amount of memory on each side of the network.Of course, there are a number of practical issues to consider. Whilethere's no need to worry about files in the kilobyte-sized range (forexample, typical source-code files), committing larger files can take atremendous amount of both time and space (for example, files that aredozens or hundreds of megabytes large.)
To begin with, remember that your Subversion working copy storespristine copies of all version-controlled files in the .svn/text-base/area. This means that your working copy takes up at least twice as muchdisk space as the original dataset. Beyond that, the Subversion clientfollows a (currently unadjustable) algorithm for committing files:
1. Copies the file to .svn/tmp/
This can take a while, and temporarily uses extra disk space.
2. Performs a binary diff between the tmpfile and the pristine copy, or between the tmpfile and an empty-file if newly added.
This can take a very long time to compute, even though only asmall amount of data might ultimately be sent over the network.
3. Sends the diff to the server, then moves the tmpfile into .svn/text-base/
So while there's no theoretical limit to the size of your files,understand that very large files may require quite a bit of patientwaiting while your client chugs away. You can rest assured, however,that unlike CVS, your large files won't incapacitate the server oraffect other users.
Work Around Commands that Don't Understand Copies/Renames
When a file or directory is copied or renamed, the Subversionrepository tracks that history. Unfortunately, in Subversion the onlyclient subcommand which actually takes advantage of this feature is svnlog. A number of other commands (such as svn diff and svn cat) ought toautomatically follow rename-history, but aren't doing so yet.
In all of these cases, a basic work around is to use 'svn log -v' todiscover the proper path within the older revision. For example:
1. Suppose you copied /trunk to /branches/mybranch in revision 200,and then committed some changes to /branches/mybranch/foo.c insubsequent revisions.
2. Now you want to compare revisions 80 and 250 of the file.
3. If you have a working copy of the branch and run svn diff-r80:250 foo.c, you see an error about /branches/mybranch/foo.c notexisting in revision 80.
4. To remedy this, you run svn log -v on your branch or file todiscover that it was named /trunk/foo.c prior to revision 200, and thencompare the two URLs
directly: $ svn diff http://.../trunk/foo.c@80 \
http://.../branches/mybranch/foo.c@200
Know When to Create Branches
This is a hotly debated question, and when you create branches reallydepends on the culture of your software project. Rather than prescribea universal policy, here are three common suggestions:
The Never-Branch System
This is often used by nascent projects that don't yet have runnable code.
* Users commit their day-to-day work on /trunk .
* Occasionally /trunk "breaks" (doesn't compile or fails functionaltests) when a user begins to commit a series of complicated changes.
Pros: Very easy policy to follow. New developers have low barrier to entry. Nobody needs to learn how to branch or merge.
Cons: Chaotic development, code could be unstable at any time. A sidenote: this sort of development is a bit less risky in Subversion thanin CVS. Because Subversion commits are atomic, it's not possible for acheckout or update to receive a "partial" commit while someone else isin the process of committing.
The Always-Branch System
This is often used by projects that favor heavy management and supervision.
* Each user creates/works on a private branch for every coding task.
* When coding is complete, someone (original coder, peer, ormanager) reviews all private branch changes and merges them to /trunk .
Pros: /trunk is guaranteed to be extremely stable at all times.
Cons: Coders are artificially isolated from each other, possiblycreating more merge conflicts than necessary. Requires users to do lotsof extra merging.
The Branch-When-Needed System
This is the system used by the Subversion project itself.
* Users commit their day-to-day work on /trunk .
* Rule #1: /trunk must compile and pass regression tests at alltimes. Committers who violate this rule are publicly humiliated.
* Rule #2: a single commit (changeset) must not be so large as to discourage peer-review.
* Rule #3: if rules #1 and #2 come into conflict (for example, ifit's impossible to make a series of small commits without disruptingthe trunk), then the user creates a branch and commits a series ofsmaller changesets there. This allows peer-review without disruptingthe stability of /trunk .
Pros: /trunk is guaranteed to be stable at all times. The hassle of branching/merging is somewhat rare.
Cons: Adds a bit of burden to users' daily work: they must compile and test before every commit.
页:
[1]