diff options
Diffstat (limited to 'doc/user/svn-best-practices.html')
-rw-r--r-- | doc/user/svn-best-practices.html | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/doc/user/svn-best-practices.html b/doc/user/svn-best-practices.html new file mode 100644 index 0000000..61ba1c6 --- /dev/null +++ b/doc/user/svn-best-practices.html @@ -0,0 +1,350 @@ +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> + +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> +<title>Subversion Best Practices</title> +<style type="text/css"> +h1 { + text-align: center; +} +</style> +</head> + +<body> + +<h1>Subversion Best Practices</h1> + +<p>This is a quick set of guidelines for making the best use of +Subversion in your day-to-day software development work.</p> + + +<h2>Use a sane repository layout</h2> + +<p>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.</p> + +<p>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: <tt>/trunk</tt>, +<tt>/branches</tt>, and <tt>/tags</tt>. A repository may contain +only one project root, or it may contain a number of them.</p> + +<p><em>Book reference:</em> <a + href="http://svnbook.red-bean.com/svnbook/ch05s04.html#svn-ch-5-sect-6.1">Choosing + a Repository Layout</a>.</p> + + + +<!-- =================================================== --> + +<h2>Commit logical changesets</h2> + +<p>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 to <tt>svn merge</tt> should you want to undo the +change or port it to another branch.</p> + +<p><em>Book reference:</em> "Subversion and Changesets" sidebar, + within <a + href="http://svnbook.red-bean.com/svnbook/ch04s03.html">chapter + 4</a>.</p> + +<!-- =================================================== --> + +<h2>Use the issue-tracker wisely</h2> + +<p>Try to create as many two-way links between Subversion changesets +and your issue-tracking database as possible:</p> + +<ul> +<li>If possible, refer to a specific issue ID in every commit log message.</li> +<li>When appending information to an issue (to describe progress, or + to close the issue) name the revision number(s) responsible + for the change.</li> +</ul> + +<!-- =================================================== --> + +<h2>Track merges manually</h2> + +<p>When committing the result of a merge, be sure to write a +descriptive log message that explains what was merged, something +like:</p> + + <pre>Merged revisions 3490:4120 of /branches/foobranch to /trunk.</pre> + +<p><em>Book reference:</em> <a + href="http://svnbook.red-bean.com/svnbook/ch04s03.html#svn-ch-4-sect-3.2">Tracking + merges manually</a>, and <a + href="http://svnbook.red-bean.com/svnbook/ch04s04.html#svn-ch-4-sect-4.1">Merging a whole branch to another</a>.</p> + +<!-- =================================================== --> + +<h2>Understand mixed-revision working copies</h2> + +<p>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:</p> + +<ol> + +<li>After every <tt>svn commit</tt>, 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.</li> + +<li>Certain commits are disallowed: + <ul> + <li>You cannot commit the deletion of a file or directory which + doesn't have a working revision of HEAD.</li> + <li>You cannot commit a property change to a directory which + doesn't have a working revision of HEAD.</li> + </ul> +</li> + +<li><tt>svn update</tt> will bring your entire working copy to one + working revision, and is the typical solution to the + problems mentioned in point #2.</li> +</ol> + +<p><em>Book reference:</em> <a +href="http://svnbook.red-bean.com/svnbook/ch02s03.html#svn-ch-2-sect-3.4">The + limitation of mixed revisions</a>.</p> + + +<!-- =================================================== --> + +<h2>Be patient with large files</h2> + +<p>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.</p> + +<p>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.)</p> + +<p>To begin with, remember that your Subversion working copy stores +pristine copies of all version-controlled files in the +<tt>.svn/text-base/</tt> 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:</p> + + <ul> + <li>Copies the file to <tt>.svn/tmp/</tt> <em>(can take a while, + and temporarily uses extra disk space)</em>)</li> + + <li>Performs a binary diff between the tmpfile and the pristine + copy, or between the tmpfile and an empty-file if newly + added. <em>(can take a very long time to compute, even + though only a small amount of data might ultimately be sent + over the network)</em></li> + + <li>Sends the diff to the server, then moves the tmpfile into + <tt>.svn/text-base/</tt></li> + </ul> + +<p>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.</p> + +<!-- =================================================== --> + +<h2>Work around commands that don't understand copies/renames</h2> + +<p>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 is <tt>svn +log</tt>. A number of other commands (such as <tt>svn diff</tt> and +<tt>svn cat</tt>) ought to be automatically following rename-history, +but aren't doing so yet.</p> + +<p>In all of these cases, a basic workaround is to use <tt>'svn log +-v'</tt> to discover the proper path within the older revision.</p> + +<p>For example, suppose you copied <tt>/trunk</tt> to +<tt>/branches/mybranch</tt> in revision 200, and then committed some +changes to <tt>/branches/mybranch/foo.c</tt> in subsequent revisions. +Now you'd like to compare revisions 80 and 250 of the file.</p> + +<p>If you have a working copy of the branch and run <tt>svn diff +-r80:250 foo.c</tt>, you'll see an error about +<tt>/branches/mybranch/foo.c</tt> not existing in revision 80. To +remedy, you would run <tt>svn log -v</tt> on your branch or file to +discover that it was named <tt>/trunk/foo.c</tt> prior to revision 200, +and then compare the two URLs directly:</p> + +<pre> + $ svn diff http://.../trunk/foo.c@80 \ + http://.../branches/mybranch/foo.c@200 +</pre> + + + +<!-- =================================================== --> + +<h2>Know when to create branches</h2> + +<p>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.</p> + +<h3>The Never-Branch system</h3> + +<p>(Often used by nascent projects that don't yet have runnable code.)</p> + +<ul> +<li>Users commit their day-to-day work on <tt>/trunk</tt>.</li> +<li>Occasionally <tt>/trunk</tt> "breaks" (doesn't compile, or fails +functional tests) when a user begins to commit a series of complicated +changes.</li> +</ul> + +<p><em>Pros:</em> Very easy policy to follow. New developers have low + barrier to entry. Nobody needs to learn how to branch or merge.</p> + +<p><em>Cons:</em> Chaotic development, code could be unstable at any + time.</p> + +<p>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.</p> + + +<h3>The Always-Branch system</h3> + +<p>(Often used by projects that favor heavy management and supervision.)</p> + +<ul> +<li>Each user creates/works on a private branch for <em>every</em> coding task. + </li> +<li>When coding is complete, someone (original coder, peer, or + manager) reviews all private branch changes and merges them to + <tt>/trunk</tt>.</li> +</ul> + +<p><em>Pros:</em> <tt>/trunk</tt> is guaranteed to be + <em>extremely</em> stable at all times. </p> + +<p><em>Cons:</em> Coders are artificially isolated from each other, + possibly creating more merge conflicts than necessary. + Requires users to do lots of extra merging.</p> + + +<h3>The Branch-When-Needed system</h3> + +<p>(This is the system used by the Subversion project.) + +<ul> +<li>Users commit their day-to-day work on <tt>/trunk</tt>.</li> + +<li>Rule #1: <tt>/trunk</tt> must compile and pass regression tests at +all times. Committers who violate this rule are publically +humiliated.</li> + +<li>Rule #2: a single commit (changeset) must not be so large +so as to discourage peer-review.</li> + +<li>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 <tt>/trunk</tt>.</li> + +</ul> + +<p><em>Pros:</em> <tt>/trunk</tt> is guaranteed to be stable at all + times. The hassle of branching/merging is somewhat rare.</p> + +<p><em>Cons:</em> Adds a bit of burden to users' daily work: + they must compile and test before every commit.</p> + + +<!-- + + +Mapping CVS tasks to SVN tasks +============================== + +This section is just a re-indexing of topics covered in the book, +for people who prefer to learn from the "bottom up" rather than "top down". +It shows some common CVS operations, and then the equivalent SVN operation, +followed by a link to the book which explains more. + + +* Importing data. + +* Checking out a working copy. + +* Seeing your changes. + +* Undoing your changes. + +* Resolving a conflict. + +* Adding binary files. + +* Activating keyword expansion and/or EOL translation. + + +TAGS: + +* Creating a tag from a working copy + +* Creating a remote tag + +* Seeing all of a project's tags + +* Comparing two tags + +* Seeing the logs between two tags + +* Tweaking a tag + + +BRANCHES: + +* Creating a branch and switching to it + +* Finding the beginning of a branch + +* Merging a branch to trunk, or vice versa + +--> + + +</body> +</html> |