Fra tid til anden får vi spørgsmål omkring, hvordan vi synes man skal
indrette sin mappe på svn-serveren. Det helt korte svar er, at det må
man selv om ;-)
Der er dog flere best practices, som jeg gerne vil anbefale. De er
taget fra Apache foundations artikel "Subversion
Best Practices", som også indsættes i sin helhed, nederst i
denne artikel.
To practices vil jeg dog fremhæve:
- Mappestruktur
I din rodmappe opret mapperne /trunk, /tags og
/branches. Trunk er det primære kodetræ, som gerne skulle kunne
compiles til hver en tid. /tags er en mappe til (stabile) statiske
versioner og branches er hvor man kan "lege" med ny
funktionalitet, lukke nye udviklere ind og lign., da koden der ikke
påvirker /trunk. Som branching-strategi, vil jeg anbefale "The
Branch-When-Needed system" nævnt nedenfor.
- Dokumentation
Tilføj sigende kommentarer til dine commits.
Det hjælper dine kolleger og alle andre i communitiet med at følge
med i hvad der sker med koden. Tilføj gerne referencer til
fejlhåndteringssystemet, hvis I bruger sådan et.
Som reference til artiklen er yderligere et link til en kapitel i SVN-Bogen som
omhandler, hvordan man opretter
en branch.
Hele best practice artiklen fra Apache foundation:
Subversion Best Practices
This is a quick set of guidelines for making the best use of
Subversion in your day-to-day software development work.
Use a sane repository layout
There are many ways to lay out your repository. Because branches and
tags are ordinary directories, you'll need to account for them in your
repository structure.
The Subversion project officially recommends the idea of a
"project root", which represents an anchoring point for a
project. A "project root" contains exactly three
subdirectories:/trunk,/branches, and/tags. A repository may contain
only one project root, or it may contain a number of them.
Book reference:
Choosing
a Repository Layout.
Commit logical changesets
When you commit a change to the repository, make sure your change
reflects a single purpose: the fixing of a specific bug, the addition
of a new feature, or some particular task. Your commit will create a
new revision number which can forever be used as a "name"
for the change. You can mention this revision number in bug databases,
or use it as an argument tosvn mergeshould you want to undo the change
or port it to another branch.
Book reference: "Subversion and Changesets"
sidebar, within chapter 4.
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, or
to close the issue) name the revision number(s) responsible for the change.
Track merges manually
When committing the result of a merge, be sure to write a descriptive
log message that explains what was merged, something like:
Merged revisions 3490:4120 of /branches/foobranch to /trunk.
Book reference:
Tracking
merges manually, and Merging
a whole branch to another.
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 and match older versions of things with newer ones.
But there are few facts you must be aware of:
- After everysvn commit, your working copy has mixed revisions. The
things you just committed are now at the HEAD revision, and
everything else is at an older revision.
- Certain commits are disallowed:
- You cannot commit the deletion of a file or directory which
doesn't have a working revision of HEAD.
- You cannot commit a property change to a directory which doesn't
have a working revision of HEAD.
- svn updatewill bring your entire working copy to one working
revision, and is the typical solution to the problems mentioned in
point #2.
Book reference:
The
limitation of mixed revisions.
Be patient with large files
A nice feature of Subversion is that by design, there is no limit to
the size of files it can handle. Files are sent "streamily"
in both directions 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. While
there's no need to worry about files in the kilobyte-sized range (e.g.
typical source-code files), committing larger files can take a
tremendous amount of both time and space (e.g. files that are dozens
or hundreds of megabytes large.)
To begin with, remember that your Subversion working copy stores
pristine copies of all version-controlled files in
the.svn/text-base/area. This means that your working copy takes up at
least twice as much disk space as the original dataset. Beyond that,
the Subversion client follows a (currently unadjustable) algorithm for
committing files:
- Copies the file to .svn/tmp/(can take a while, and temporarily
uses extra disk space))
- Performs a binary diff between the tmpfile and the pristine copy,
or between the tmpfile and an empty-file if newly added. (can
take a very long time to compute, even though only a small amount
of data might ultimately be sent over the network)
- 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,
you'll need to be aware that very large files may require quite a bit
of patient waiting while your client chugs away. You can rest assured,
however, that unlike CVS, your large files won't incapacitate the
server or affect other users.
Work around commands that don't understand copies/renames
When a file or directory is copied or renamed, the Subversion
repository tracks that history. Unfortunately in Subversion 1.0, the
only client subcommand which actually takes advantage of this feature
issvn log. A number of other commands (such assvn diffandsvn cat)
ought to be automatically following rename-history, but aren't doing
so yet.
In all of these cases, a basic workaround is to use'svn log -v'to
discover the proper path within the older revision.
For example, suppose you copied/trunkto/branches/mybranchin revision
200, and then committed some changes to/branches/mybranch/foo.cin
subsequent revisions. Now you'd like to compare revisions 80 and 250
of the file.
If you have a working copy of the branch and runsvn diff -r80:250
foo.c, you'll see an error about/branches/mybranch/foo.cnot existing
in revision 80. To remedy, you would runsvn log -von your branch or
file to discover that it was named/trunk/foo.cprior to revision 200,
and then compare 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 it really depends on the
culture of your software project. Rather than prescribe a universal
policy, we'll describe three common ones here.
The Never-Branch system
(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
functional tests) 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 side note: this sort of development is a bit less risky in
Subversion than in CVS. Because Subversion commits are atomic, it's
not possible for a checkout or update to receive a "partial"
commit while somebody else is in the process of committing.
The Always-Branch system
(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, or
manager) 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,
possibly creating more merge conflicts than necessary. Requires users
to do lots of extra merging.
The Branch-When-Needed system
(This is the system used by the Subversion project.)
- Users commit their day-to-day work on/trunk.
- Rule #1:/trunkmust compile and pass regression tests at all times.
Committers who violate this rule are publically humiliated.
- Rule #2: a single commit (changeset) must not be so large so as to
discourage peer-review.
- Rule #3: if rules #1 and #2 come into conflict (i.e. it's
impossible to make a series of small commits without disrupting the
trunk), then the user should create a branch and commit a series of
smaller changesets there. This allows peer-review without disrupting
the 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.
Filer og referencer