    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: A Subversion Primer</title>
        <link>https://members.accu.org/index.php/articles/792</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Project Management + CVu Journal Vol 17, #2 - Apr 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c66/">Management</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c97/">172</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c66-97/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c66+97/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;A Subversion Primer</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 April 2005 13:16:11 +01:00 or Sun, 03 April 2005 13:16:11 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>This article provides an introduction to Subversion. It lists Subversion's key features and best working practices, provides cookbook recipes for all the common activities in your day-to-day development work, and points the reader to further reading.</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>This article provides an introduction to Subversion. It lists
Subversion's key features and best working practices, provides
cookbook recipes for all the common activities in your day-to-day
development work, and points the reader to further reading.</p>
<p>It is intended for software developers and doesn't matter which
operating system you use (although it would help to not be scared
of the command line). It's useful to have an understanding of CVS,
or some other version control system.</p>
<p>Disclaimer: If the information in here diverges from Subversion
documentation, clearly I'm wrong and they're right. Terms and
conditions apply. Your hair may be at risk if you do not keep up a
loan secured on it.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e28" id="d0e28"></a>Terms and
Definitions</h2>
</div>
<div class="variablelist">
<dl>
<dt><span class="term">SCMS</span></dt>
<dd>
<p>Source Code Management System (e.g. CVS, ClearCase, or
Subversion)</p>
</dd>
<dt><span class="term">CM</span></dt>
<dd>
<p>Configuration Management (development practices using SCMS)</p>
</dd>
<dt><span class="term">CVS</span></dt>
<dd>
<p>Concurrent Versions System, the <span class="emphasis"><em>de
facto</em></span> open source SCMS</p>
</dd>
</dl>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e53" id="d0e53"></a>What is
Subversion?</h2>
</div>
<p>Subversion was designed from the ground up as a modern,
high-performance version control system. It is intended to be
compelling SCMS replacement for the (now ageing) CVS<sup>[<a name=
"d0e58" href="#ftn.d0e58" id="d0e58">1</a>]</sup>. It is freely
available under an open source licence.</p>
<p>It is gaining popularity, a stable, production-quality system.
It's now used in anger by public projects including Mono, Xiph,
Apache, Samba, PuTTY, Debian, and Ethereal. I have used it for
personal work, and deployed it in commercial development teams.
I've found it to be an excellent, streamlined SCMS that is very
usable.</p>
<p>Of the new breed of open SCMS tools around, this is really the
only mature production worthy system.</p>
<p>Subversion follows the same <span class=
"emphasis"><em>modify-merge-commit</em></span> model of CVS, so it
should be familiar to most developers.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e71" id="d0e71"></a>Key Features</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>CVS-like interface</p>
</li>
<li>
<p>Directories, renames, and file metadata are versioned</p>
</li>
<li>
<p>Commits are truly atomic, they either totally succeed or totally
fail</p>
</li>
<li>
<p>Commits are recorded as a <i class="firstterm">changeset</i> (a
revision number applies to the whole file tree, not individual
files)</p>
</li>
<li>
<p>Branching and tagging are cheap (constant time) operations</p>
</li>
<li>
<p>Efficient network usage</p>
</li>
<li>
<p>Cross platform: Windows, Linux, MacOS X, with several GUI
front-ends</p>
</li>
<li>
<p>Good for offsite work (supports offline diff and revert)</p>
</li>
<li>
<p>Scales far better than CVS</p>
</li>
<li>
<p>Efficient binary file handling</p>
</li>
<li>
<p>Supports Apache and the WebDAV protocol (also has own protocol,
which can be tunnelled over ssh)</p>
</li>
<li>
<p>MS Visual Studio integration</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e114" id="d0e114"></a>What It Doesn't
Do</h3>
</div>
<p>The feature sets of different SCMSs vary, although the core
concepts (i.e. versioning a set of files) don't tend to differ
significantly. There are a number of key facilities that Subversion
does not provide that you may be used to:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Merge support is not so rich as some tools (it is as good as
CVS, though)</p>
</li>
<li>
<p>There are no dynamic views (a ClearCase magic versioned file
system)</p>
</li>
<li>
<p>There are no locking checkouts (strangely, they're working on
this)</p>
</li>
</ul>
</div>
<p>Depending on your SCMS religion, the last two points are
actually huge benefits.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e131" id="d0e131"></a>Overview of
Operation</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e134" id="d0e134"></a>Versioning</h3>
</div>
<p>Subversion versioning is different from the CVS model. Unlike
CVS, changes are atomic. When you check in multiple files you
submit an atomic changeset. These file commits will either all
succeed or all fail.</p>
<div class="sidebar">
<p class="title c2">Revision Names</p>
<p>When you invoke Subversion commands, there are a number of
special revision names that you can use:</p>
<div class="variablelist">
<dl>
<dt><span class="term"><tt class="literal">HEAD</tt></span></dt>
<dd>
<p>the latest revision in the repository.</p>
</dd>
<dt><span class="term"><tt class="literal">BASE</tt></span></dt>
<dd>
<p>a pristine copy of the file currently checked out in your
working copy.</p>
</dd>
<dt><span class="term"><tt class=
"literal">COMMITTED</tt></span></dt>
<dd>
<p>the last revision in which a file changed, before (or at)
<tt class="literal">BASE</tt>.</p>
</dd>
<dt><span class="term"><tt class="literal">PREV</tt></span></dt>
<dd>
<p>the file that is identified as (<tt class=
"literal">COMMITTED</tt>-1).</p>
</dd>
</dl>
</div>
</div>
<p>All the modifications made in one changeset are held together as
a single revision, with a single checkin message.</p>
<p><span class="bold"><b>Important difference:</b></span> a
revision number applies to the <span class="emphasis"><em>whole
tree</em></span>, unlike CVS where version numbers apply to each
individual file. When you check in a single file, the whole file
tree gets up-versioned (the files in your working copy <span class=
"emphasis"><em>do not</em></span> all automatically get
up-versioned, though). A revision number identifies how a file tree
looked at a position in time.</p>
<p>For example: you check out <tt class="filename">foo.c</tt> from
<tt class="literal">HEAD</tt>, and the repository is currently at
version 5. You have 'version 5' of the file in your working copy.
What you really have is <tt class="filename">foo.c</tt>
<span class="emphasis"><em>as it appeared</em></span> in version 5
<span class="emphasis"><em>of the repository</em></span>. The file
may not have changed since version 3. So consecutive version
numbers of a single file may be identical.</p>
<p>The changeset idea is very powerful. Using it there is no need
for a manually maintained changelog (updates) file, and it's easy
to merge specific changesets from one branch to another.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e210" id="d0e210"></a>Branches and
Tags</h3>
</div>
<p>Committing a single file effectively creates a new copy of the
entire file tree in the repository (remember: the whole source tree
goes up a version number). To do this Subversion provides very
cheap copy operations. Subversion branches and tags (labels)
exploit this fact, and so are also very cheap and quick operations.
Their implementation is surprising to CVS developers.</p>
<p>Both branches and tags are stored in the repository as copies of
a file set. Therefore, they exist at a physical point in the file
structure. This is very different from the CVS branching/tagging
model. A Subversion tag <span class="emphasis"><em>is
not</em></span> a property applied to a particular revision of a
file, although it does still uniquely identify a set of files.</p>
<p>Both tags and branches are created in the same way, and the
difference between the two is only what you do with them
afterwards. A branch is a copy created with the express purpose of
performing additional development work, work that should be kept
separate from the trunk. A tag is a copy that will not be worked on
(you can still merge changesets into a tag copy, in order to 'move'
the tag).</p>
<p>Branches and tags can have finite lifetimes - as versioned
objects in the repository you can delete them like any other
object. This will not lose the history of their existence, and is a
powerful tool that helps to keep your repository neat.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e224" id="d0e224"></a>Repository
Directory Layout</h3>
</div>
<p>There is no fixed directory structure in a repository, although
there are conventions that Subversion users generally follow. A
repository may contain a number of projects, each in their own
top-level directory. A project directory has three
subdirectories:</p>
<div class="variablelist">
<dl>
<dt><span class="term"><tt class="literal">trunk</tt></span></dt>
<dd>
<p>contains the main line of code development</p>
</dd>
<dt><span class="term"><tt class=
"literal">branches</tt></span></dt>
<dd>
<p>contains all branch copies of code development</p>
</dd>
<dt><span class="term"><tt class="literal">tags</tt></span></dt>
<dd>
<p>contains all tag copies of code development</p>
</dd>
</dl>
</div>
<p>The <tt class="literal">branches</tt> and <tt class=
"literal">tags</tt> directories both hold Subversion copies of a
version of the <tt class="literal">trunk</tt> file set.</p>
<div class="sidebar">
<p class="title c2">Terms</p>
<div class="variablelist">
<dl>
<dt><span class="term">Repository</span></dt>
<dd>
<p>the central store of files under revision control.</p>
</dd>
<dt><span class="term">Working copy</span></dt>
<dd>
<p>a set of files checked out of the repository, stored on your
local hard disk.</p>
</dd>
<dt><span class="term">Revision</span></dt>
<dd>
<p>a set of changes to the repository (file edits, directory
changes, metadata changes). A revision number applies to the whole
repository file tree, not to individual files.</p>
</dd>
<dt><span class="term">Tag</span></dt>
<dd>
<p>a read-only copy of a revision of the file tree.</p>
</dd>
<dt><span class="term">Property</span></dt>
<dd>
<p>arbitrary (possibly binary) metadata associated with a revision
of a file in the repository.</p>
</dd>
<dt><span class="term">Trunk</span></dt>
<dd>
<p>the repository directory containing the main line of code
development.</p>
</dd>
<dt><span class="term">Branch</span></dt>
<dd>
<p>a repository copy of a version of the trunk. New commits in this
directory only affect the branch, not the trunk.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e308" id=
"d0e308"></a>Miscellaneous</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>When you check out a working copy of the repository, Subversion
makes a physical copy of the files on your hard disk. Each
directory contains a .svn directory (akin to the CVS directory in
CVS) where admin files are held. You must <span class=
"emphasis"><em>not poke</em></span> around in here.</p>
<p>In that directory is held a pristine copy of the files you have
checked out, so network utilisation is very efficient - file diffs
are done at the client end, not on the server.</p>
</li>
<li>
<p>Subversion uses URIs to define a location in the repository.
There are several different repository access methods, identified
by the URI's transport (e.g. <tt class="literal">file:</tt>
<tt class="literal">svn:</tt> <tt class="literal">http:</tt> and
<tt class="literal">https:</tt>, you only use one of these at
once!)</p>
<p>On Windows, URIs still use the Unix-like forward slash.</p>
</li>
<li>
<p>Most operations are applied to the working copy's file tree, in
which case the modification is made locally, but no change occurs
in repository until you perform a commit. Some operations also
accept repository URIs; these work directly on the repository files
(the <tt class="literal">copy</tt> command is an example of this).
In this case you do not even need to check out a working copy.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e343" id="d0e343"></a>Subversion
Cookbook</h2>
</div>
<p><img src="/var/uploads/journals/resources/goodliffe%20subversion%20cookbook.png"
align="right">Here are some simple Subversion recipes to get you
started. This should cover most of your day-to-day work. If you
want to step beyond these examples, you can always type <tt class=
"literal">svn help</tt> for more information, or look at the
<span class="emphasis"><em>Further Reading</em></span> section,
below.</p>
<p>These recipes show how to perform each operation using the
Subversion command line client (<tt class="literal">svn</tt>). The
exercise is similar using one of the available GUI front ends (for
example the MS Visual Studio <span class=
"emphasis"><em>Ankh</em></span> plug-in); naturally you don't type
a command, you click on helpful buttons instead. But despite all
the GUI goodness you still have to understand what's going on
behind the scenes - these recipes will make this clear. The
<span class="emphasis"><em>Other Tools</em></span> section towards
the end of this article describes the various Subversion GUI front
ends available.</p>
<p>In the following command line examples, the text you type is
emboldened, the svn response is plain text. The repository URI
location is represented as <tt class="literal">REPOSITORY</tt>, and
I assume that the URI's transport is method <tt class=
"literal">svn:</tt>. Change this as appropriate.</p>
<p>Subversion commands have both a long form (e.g. <tt class=
"literal">checkout</tt>) and a shortened form (<tt class=
"literal">co</tt>). I use the long form for clarity. The shortened
versions are listed at the end of the document (see <span class=
"emphasis"><em>Shortened Commands</em></span>).</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e385" id="d0e385"></a>Import a
Project</h3>
</div>
<p>Admittedly you don't do this very often, but it's a quick way to
get a baselined project into a Subversion repository<sup>[<a name=
"d0e390" href="#ftn.d0e390" id="d0e390">2</a>]</sup>.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You want to import the <span class=
"emphasis"><em>widgetizer</em></span> project into the
repository.</p>
</li>
<li>
<p>You have made a top-level widgetizer directory structure in the
repository (see below for that recipe).</p>
<pre class="screen">
svn import /path/to/widgetizer  svn://REPOSITORY/widgetizer/trunk
Adding      widgetizer/main.c
Adding      widgetizer/other.c
Committed revision 1
</pre></li>
</ul>
</div>
<p>These changes are made to the repository immediately. Don't
worry if you import to the wrong place, in Subversion it's easy to
move things around afterwards (that's a later recipe).</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e408" id="d0e408"></a>View the
Repository</h3>
</div>
<p>Before you 'check out' files from the repository you can browse
to see what you want to play with. (CVS doesn't provide this
facility.)</p>
<pre class="screen">
svn list svn://REPOSITORY/widgetizer
branches/
tags/
trunk/
</pre>
<p>Clearly, if there is a ViewCVS system (a web-based repository
browse application) set up, you would use that in preference.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e417" id="d0e417"></a>Check Out Part
of a Repository</h3>
</div>
<div class="sidebar">
<p class="title c2">Selecting Revisions</p>
<p>Many commands can be directed to work with a specific revision
of a file (remember, though, that revision numbers actually apply
to the <span class="emphasis"><em>repository</em></span>, and not
to <span class="emphasis"><em>individual files</em></span>). In
this case they take a <tt class="literal">-revision</tt>
(<tt class="literal">-r</tt> for short) argument.</p>
<p>This can take two forms:</p>
<div class="variablelist">
<dl>
<dt><span class="term">-r 5</span></dt>
<dd>
<p>Specifies files from revision 5 of the repository.</p>
</dd>
<dt><span class="term">-r 3:5</span></dt>
<dd>
<p>Specifies a range of files from version 3 to version 5 of the
repository</p>
</dd>
</dl>
</div>
<p>The version specified can be a revision number, a keyword, or a
date. Dates are enclosed in braces, and can take many forms, for
example: <tt class="literal">{2002-02-17}, {15:30}, {&quot;2002-02-17
15:30&quot;}</tt> and more. (If the date contains a space, wrap it in
quotes.)</p>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You've identified the project subdirectory you want to check
out, and know whether you want the trunk or a branch.</p>
<pre class="screen">
cd ~/Work
svn checkout svn://REPOSITORY/widgetizer/trunk
A  widgetizer/trunk/main.c
A  widgetizer/trunk/other.c
Checked out revision 1
</pre></li>
</ul>
</div>
<p>The A above stands for 'Added'. We'll see more output like this
later. You have now created a <span class="emphasis"><em>working
copy</em></span> of the repository.</p>
<p>You can choose to check out a whole project or just a specific
file or directory.</p>
<p>You can edit the files immediately; there is no need to issue a
Subversion command to 'open' them for editing. Of course, this
means that someone else could be editing the same file as you at
the same time. More on that later&hellip;</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e472" id="d0e472"></a>Inspect Which
Files You've Modified</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You've modified some of the files in your working copy.</p>
</li>
<li>
<p>Before you commit the changes to the repository, you want to see
what you've changed.</p>
<pre class="screen">
cd widgetizer/trunk
svn status
M  main.c
M  other.c
</pre></li>
</ul>
</div>
<p>The M above stands for 'Modified'. Files with no difference from
the repository<sup>[<a name="d0e486" href="#ftn.d0e486" id=
"d0e486">3</a>]</sup> are not listed. The most common status codes
are:</p>
<div class="variablelist">
<dl>
<dt><span class="term">M</span></dt>
<dd>
<p>The contents of this file have been changed</p>
</dd>
<dt><span class="term">?</span></dt>
<dd>
<p>This file is not in the repository (you may want to svn add
it)</p>
</dd>
<dt><span class="term">A</span></dt>
<dd>
<p>File is scheduled for addition</p>
</dd>
<dt><span class="term">D</span></dt>
<dd>
<p>File is scheduled for deletion</p>
</dd>
<dt><span class="term">C</span></dt>
<dd>
<p>File has conflicts which need resolving (see below)</p>
</dd>
<dt><span class="term">S</span></dt>
<dd>
<p>File has been switched to a branch (see below)</p>
</dd>
<dt><span class="term">!</span></dt>
<dd>
<p>File is managed by Subversion, but it's missing in your working
copy</p>
</dd>
</dl>
</div>
<p>CVS users, note: Subversion doesn't need you to subvert the
update command to do this kind of inspection. (CVS users routinely
type <tt class="literal">cvs -nq update</tt> to list modifications
because the output of cvs status is not at all helpful.)</p>
<p>You can give a specific filename as an argument to <tt class=
"literal">svn status</tt> to get information on it alone.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e543" id="d0e543"></a>Inspect the
Changes You've Made</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You know that you've changed a file.</p>
</li>
<li>
<p>You want to look at the complete set of changes to compose a
suitable checkin message.</p>
<pre class="screen">
svn diff other.c
Index: other.c
=======================================
-- other.c       (revision 2)
+++ other.c       (working copy)
@@ -1,4 +1,5 @@
 int m;
 int n;
-int p;
+int o;
$
</pre></li>
</ul>
</div>
<p>You can compare your working copy to a specific repository
revision using the <tt class="literal">-r</tt> switch, and can
compare two repository versions by specifying a range. For example,
to see the last change made to <tt class=
"filename">main.c</tt>:</p>
<pre class="screen">
svn diff -r PREV:COMMITTED main.c
Index: main.c
   ...
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e565" id="d0e565"></a>Check In Your
Changes</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You've edited a file (or files), and want to check it in to the
repository.</p>
<pre class="screen">
svn commit --message &quot;Changed the default \
   banana count&quot; other.c
</pre>
<p>... or ...</p>
<pre class="screen">
svn commit --file log-message-file other.c
Sending    other.txt
Transmitting file data .
Committed version 3.
</pre></li>
</ul>
</div>
<p>If you don't specify a message on the command line, Subversion
opens your default editor (as specified by the <tt class=
"literal">EDITOR</tt> environment variable) to prompt you for
it.</p>
<p><span class="bold"><b>Note:</b></span> You can't perform a
checkin if someone else has modified the files and checked them in
before you. In this case, Subversion will moan at you:</p>
<pre class="screen">
svn commit -m &quot;Changed the default banana \
   count&quot; other.c
Sending    other.txt
svn: Commit failed (details follow):
svn: Out of date: 'other.c' in transaction 'k'
</pre>
<p>You must first update to the <tt class="literal">HEAD</tt>
version (recipe below) and then try to check in.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e594" id="d0e594"></a>Add Directories
and Files</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You want to add a new file to the widgetizer project.</p>
</li>
<li>
<p>You have created it in your working copy.</p>
<pre class="screen">
svn add new.c
A  new.c
svn commit -m &quot;Added&quot; new.c
</pre></li>
</ul>
</div>
<p>Note that the file doesn't get put into the repository until you
issue a <tt class="literal">commit</tt> command.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e611" id="d0e611"></a>Move and Copy
Files</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You want to modify the layout of files within a directory.</p>
<pre class="screen">
svn move new.c old.c
A      old.c
D      new.c
svn copy old.c copy.c
A      copy.c
svn commit -m &quot;Changed file structure&quot;
   ...
</pre></li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e620" id="d0e620"></a>Undo a
Modification</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You made a mistake when altering <tt class=
"filename">main.c</tt>, and want to back out your changes,
restoring the previous revision that you checked out.</p>
<pre class="screen">
svn revert main.c
Reverted 'main.c'
</pre></li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e632" id="d0e632"></a>Update to Latest
Version of a File</h3>
</div>
<p>Files change in the repository whilst you are working; your
working copy will become outdated. Periodically (and usually before
you check in) you must update your working copy to the latest
repository state-of-the-art.</p>
<p>If a file that you are modifying has been changed by someone
else then Subversion, like CVS, will attempt to merge the changes
automatically into your working copy. Usually this works fine.
Occasionally a <span class="emphasis"><em>conflict</em></span>
occurs, when Subversion doesn't know how to perform a merge because
the changes interfere with each other. This is dealt with in the
next recipe.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You want to see what files have changed in the repository since
you last updated</p>
<pre class="screen">
svn status --show-updates
</pre>
<p>... or ...</p>
<pre class="screen">
svn status -u
M      *    main.c
       *    other.c
</pre>
<p>The * shows that an update must be taken from the repository.
The M shows that you have modified a file locally: Subversion will
merge the repository change into your modified copy.</p>
</li>
<li>
<p>You want to bring in the latest version of other.c, but leave
main.c in the current working copy</p>
<pre class="screen">
svn update other.c
U  other.c
Updated to revision 4.
</pre></li>
</ul>
</div>
<p>Notes:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Working copies are not dynamic, so you are in control of when
you pull in other people's changes. This is especially useful
during builds - no files will change during your build process, so
you can be assured of the build's integrity.</p>
</li>
<li>
<p>Your working copy can contain a random collection of file
version numbers (you can <tt class="literal">commit</tt> and
<tt class="literal">update</tt> files independently).</p>
</li>
<li>
<p>You can use the -r argument to shift to a particular file
revision.</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e677" id="d0e677"></a>Resolving
Conflicts</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You performed a svn update, and a file had conflicts (the
<tt class="literal">update</tt> output message showed a file with C
status).</p>
</li>
<li>
<p>You can't check your version of the file in until you have
resolved the conflict.</p>
</li>
<li>
<p>Open the conflicted file in your editor. You will see the
conflicts flagged between <span class="emphasis"><em>conflict
markers</em></span> that highlight the problem changes.</p>
</li>
<li>
<p>Subversion has created three extra files in your working copy
directory:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p><tt class="filename">filename.mime</tt> - the copy of <tt class=
"filename">filename</tt> that was in your working copy directory
before you ran <tt class="literal">svn update</tt>.</p>
</li>
<li>
<p><tt class="filename">filename.rOLDREV</tt> - The file that was
the <tt class="literal">BASE</tt> revision before you ran
<tt class="literal">svn update</tt>.</p>
</li>
<li>
<p><tt class="filename">filename.rNEWREV</tt> - The new version
that came from the repository.</p>
</li>
</ol>
</div>
</li>
<li>
<p>Merge the changes manually.</p>
</li>
<li>
<p>Then type the following command to tell Subversion that you have
resolved the conflict (note: this is an extra step over CVS
operation):</p>
<pre class="screen">
svn resolved other.c
Resolved conflicted state of 'other.c'
</pre></li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e735" id="d0e735"></a>Inspect File
History</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You want to see how the file <tt class="filename">other.c</tt>
changed over time.</p>
<pre class="screen">
svn log other.c
---------------------------------
r3 | pete | Tue, 16 Dec 2004 12:23:12 +0000
                                    | 1 line
Changed the default banana count
---------------------------------
r2 | pete | Tue, 16 Dec 2004 12:16:43 +0000
                                    | 1 line
Added
---------------------------------
</pre></li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e747" id="d0e747"></a>Creating a
Branch</h3>
</div>
<p>You want to branch the <tt class="literal">HEAD</tt> of your
project's <tt class="literal">trunk</tt> into a branch called
<tt class="literal">trout</tt>, to perform some parallel
development work .</p>
<pre class="screen">
svn copy \
  svn://REPOSITORY/widgetizer/trunk \
  svn://REPOSITORY/widgetizer/branches/trout \
  -m &quot;Created trout branch&quot;
Committed revision 128.
</pre>
<p>Note: we didn't need to have a working copy checked out to
perform this operation, since we used URIs into the repository.
(You can also do this locally in a working copy, but there's not
much point.)</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e765" id="d0e765"></a>Working on a
Branch</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Having created a branch, you want to check it out and start
working on it.</p>
<pre class="screen">
svn checkout \
   svn://REPOSITORY/widgetizer/branches/trout
A  trout/main.c
A  trout/other.c
Checked out revision 128.
</pre></li>
</ul>
</div>
<p>This new branch is a separate physical directory from the trunk.
However, it retains all the file revision history (try a <tt class=
"literal">svn log</tt> on a file).</p>
<p>Alternatively, if you already have a working copy checked out,
and you want to switch it to view the branch, use <tt class=
"literal">svn switch</tt>:</p>
<pre class="screen">
svn info | grep URL
URL: svn://REPOSITORY/widgetizer/trunk
svn switch svn://REPOSITORY/widgetizer/branches/trout
U  main.c
U  other.c
Updated to revision 128.
svn info | grep URL
URL: svn://REPOSITORY/widgetizer/branches/trout
</pre>
<p>This is more efficient than checking out a whole new tree, and
also allows you to switch just a single directory, or even a single
file.</p>
<p>You can now use your branch version of the working directory as
if it was the <tt class="literal">trunk</tt>. All checkins you make
appear only on the branch, without affecting <tt class=
"literal">trunk</tt> at all.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e796" id="d0e796"></a>Merge Changes
Between Branches</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Your work on the <tt class="literal">trout</tt> branch is
sufficiently advanced that it should be merged back onto the
mainline of development, into <tt class="literal">trunk</tt>.</p>
</li>
<li>
<p>Create a working copy of the trunk, then identify the range of
changes that you want, merge them into the trunk, and check in:</p>
<pre class="screen">
cd ~/Work/trout
svn update
At revision 132.
svn log --verbose --stop-on-copy
   The final revision number listed is the
   start of the branch, let's say it's 2
cd ~/Work/trunk
svn merge -r 2:132 svn://REPOSITORY/widgetizer/branches/trout
M   main.c
M   other.c
svn commit -m &quot;Merged trout changes r2:r132 \
  into the trunk&quot;
   ...
</pre></li>
</ul>
</div>
<p>Like CVS, Subversion doesn't record a merge history, so you have
to be careful when you merge a branch into trunk multiple times.
Always specify revision numbers in great detail when you write the
log message, next time you merge you will want to merge the range
<tt class="literal">133:HEAD</tt>, not <tt class=
"literal">2:HEAD</tt>.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e822" id="d0e822"></a>Create a
Tag</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You release the first version of your software and want to tag
the source code that built it.</p>
<pre class="screen">
svn copy \
  svn://REPOSITORY/widgetizer/trunk \
  svn://REPOSITORY/widgetizer/tags/Release1 \
  -m &quot;Created release 1 tag&quot;
Committed revision 326.
</pre></li>
</ul>
</div>
<p>This is a very simple tag operation (but probably the most
common). You can tag more eclectic collections of files. Update
your working copy to the set of file versions that you want to tag
(using <tt class="literal">svn update -r</tt>). Then:</p>
<pre class="screen">
svn copy \
  my-working-copy \
  svn://REPOSITORY/widgetizer/tags/TagName \
  -m &quot;Created release 1 tag&quot;
Committed revision 327.
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e838" id="d0e838"></a>Undo a Change in
the Repository</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Some idiot (you, probably) checked a blatantly wrong revision
into the repository.</p>
</li>
<li>
<p>You want to revert the change.</p>
<pre class="screen">
svn merge -r 10:9 svn://REPOSITORY/widgetizer/trunk/main.c
U  main.c
svn commit -m &quot;Undoing change committed in r10&quot;
   ...
</pre></li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e850" id="d0e850"></a>Create a Change
Log</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You want to maintain a file containing all commit messages over
the project's history.</p>
</li>
<li>
<p>You don't want to do it by hand.</p>
</li>
<li>
<p>At each release point in your project, do this:</p>
<pre class="screen">
svn log -r 42:HEAD &gt;&gt; ChangeLog
svn commit ChangeLog -m 'Update ChangeLog'
</pre></li>
</ul>
</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e865" id="d0e865"></a>Shortened
Commands</h2>
</div>
<p>Subversion commands can be abbreviated to save you some typing.
The following table shows the abbreviations for the common
commands:</p>
<div class="table"><a name="d0e870" id="d0e870"></a>
<table summary="Shortened forms of Subversion commands" border="1"
cellspacing="0">
&lt;colgroup&gt;
&lt;col width=&quot;50%&quot;&gt;
&lt;col width=&quot;50%&quot;&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th>Long form</th>
<th>Short (alternate) form</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td>checkout</td>
<td>co</td>
</tr>
<tr>
<td>checkin</td>
<td>ci</td>
</tr>
<tr>
<td>copy</td>
<td>cp</td>
</tr>
<tr>
<td>delete</td>
<td>rm, del, remove</td>
</tr>
<tr>
<td>help</td>
<td>?, h</td>
</tr>
<tr>
<td>list</td>
<td>ls</td>
</tr>
<tr>
<td>move</td>
<td>mv</td>
</tr>
<tr>
<td>status</td>
<td>stat, st</td>
</tr>
<tr>
<td>switch</td>
<td>sw</td>
</tr>
<tr>
<td>update</td>
<td>up</td>
</tr>
<tr>
<td>-revision</td>
<td>-r</td>
</tr>
<tr>
<td>-show-updates</td>
<td>-u</td>
</tr>
&lt;/tbody&gt;
</table>
<p class="title c2">Table 1. Shortened forms of Subversion
commands</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e941" id="d0e941"></a>CVS
Conversion in 2 Minutes</h2>
</div>
<p>Subversion has been designed to work as much like CVS as is
practical. Most of your CVS knowledge translates directly into
Subversion. The following table shows the Subversion equivalents of
common CVS commands:</p>
<div class="table"><a name="d0e946" id="d0e946"></a>
<table summary="CVS and Subversion commands compared" border="1"
cellspacing="0">
&lt;colgroup&gt;
&lt;col width=&quot;50%&quot;&gt;
&lt;col width=&quot;50%&quot;&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th>CVS command</th>
<th>Subversion command</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td>cvs co</td>
<td>svn co</td>
</tr>
<tr>
<td>cvs ci</td>
<td>svn ci</td>
</tr>
<tr>
<td>cvs tag</td>
<td>svn copy</td>
</tr>
<tr>
<td>cvs -ng update</td>
<td>svn status</td>
</tr>
<tr>
<td>cvs diff</td>
<td>svn diff</td>
</tr>
<tr>
<td>cvs tag -j</td>
<td>svn copy</td>
</tr>
<tr>
<td>cvs add</td>
<td>svn add</td>
</tr>
<tr>
<td>cvs update</td>
<td>svn update</td>
</tr>
<tr>
<td>cvs merge</td>
<td>svn merge</td>
</tr>
&lt;/tbody&gt;
</table>
<p class="title c2">Table 2. CVS and Subversion commands
compared</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e1002" id="d0e1002"></a>Other
Tools</h2>
</div>
<p>There are other tools that sit on top of Subversion. You may
find them useful:</p>
<div class="variablelist">
<dl>
<dt><span class="term">TortoiseSVN</span></dt>
<dd>
<p>a Windows explorer plug-in providing a Subversion RMB submenu.
This is an absolutely excellent Subversion front end, and I highly
recommend it. It has an excellent history viewer, merge tool,
repository browser, and much more. If you use Subversion under
Windows you really want to get a hold of this. You can download it
from <a href="http://tortoisesvn.tigris.org/" target=
"_top">http://tortoisesvn.tigris.org/</a></p>
</dd>
<dt><span class="term">RapidSVN</span></dt>
<dd>
<p>a cross-platform GUI front end for Subversion. In my experience
this is an odd beast, and best avoided - the Tortoise front end is
far superior.</p>
</dd>
<dt><span class="term">Ankh</span></dt>
<dd>
<p>a MS Visual Studio plug-in for the Subversion client. It works
quite nicely, and I recommend it. Some Subversion operations are
easier to perform through TortoiseSVN, so I tend to use both
clients together. Ankh is not quite as polished as TortoiseSVN, but
it is an excellent tool for VS developers.</p>
<p>You can download it from <a href="http://ankhsvn.tigris.org/"
target="_top">http://ankhsvn.tigris.org/</a></p>
</dd>
<dt><span class="term">ViewCVS</span></dt>
<dd>
<p>a web based repository viewer, originally for CVS, but now with
Subversion support (at the moment there is no CVSGraph-like
facility, sadly).</p>
</dd>
</dl>
</div>
<p>Subversion's <tt class="literal">svnadmin</tt> and <tt class=
"literal">svnlook</tt> tools. Mere mortals needn't ever use these;
they are administration tools.</p>
<p>There are many other useful Subversion tools - I have seen very
pretty Mac OS X clients (<tt class="literal">SvnX</tt> is a neat
GUI front end and <tt class="literal">SCPlugin</tt> is a helpful
Finder plug-in). <tt class="literal">Subclipse</tt> and <tt class=
"literal">Svn4Eclipse</tt> are Eclipse plug-ins. Look around for
other useful Subversion plug-ins.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e1062" id="d0e1062"></a>Further
Reading</h2>
</div>
<p>Subversion's homepage is <a href="http://www.subversion.org/"
target="_top">http://www.subversion.org/</a></p>
<p>The free Subversion book is an excellent, thorough overview of
the system. It is available from <a href="http://svnbook.org/"
target="_top">http://svnbook.org/</a> You can buy a dead tree
version of this from O'Reilly, which is recommended. It's called
<i class="citetitle">Version Control with Subversion</i>, ISBN:
0596004486.</p>
<p>Another recommended book is <i class="citetitle">Pragmatic
Version Control Using Subversion</i> by The Pragmatic Programmers.
ISBN: 0974514063.</p>
<p>There is a Latex Subversion quick reference card in the source
distribution.</p>
</div>
<div class="footnotes"><br>
<hr class="c3" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e58" href="#d0e58" id=
"ftn.d0e58">1</a>]</sup> For this reason I often compare a
Subversion operation to the CVS counterpart in this document.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e390" href="#d0e390" id=
"ftn.d0e390">2</a>]</sup> Tools exist to help you import CVS
projects and retain the version/branch history. See the Subversion
website for details.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e486" href="#d0e486" id=
"ftn.d0e486">3</a>]</sup> Or, more accurately: no difference from
the repository version that the working copy was checked out
from.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
