778 lines
41 KiB
HTML
778 lines
41 KiB
HTML
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
<title>Version Control the Subversion Way</title>
|
||
<link rel="stylesheet" href="styles.css" type="text/css" />
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2" />
|
||
<style type="text/css">
|
||
body { background-image: url('images/draft.png');
|
||
background-repeat: no-repeat;
|
||
background-position: top left;
|
||
/* The following properties make the watermark "fixed" on the page. */
|
||
/* I think that's just a bit too distracting for the reader... */
|
||
/* background-attachment: fixed; */
|
||
/* background-position: center center; */
|
||
}</style>
|
||
<link rel="home" href="index.html" title="Version Control with Subversion [DRAFT]" />
|
||
<link rel="up" href="svn.basic.html" title="Chapter 1. Fundamental Concepts" />
|
||
<link rel="prev" href="svn.basic.version-control-basics.html" title="Version Control Basics" />
|
||
<link rel="next" href="svn.basic.summary.html" title="Summary" />
|
||
</head>
|
||
<body>
|
||
<div class="navheader">
|
||
<table width="100%" summary="Navigation header">
|
||
<tr>
|
||
<th colspan="3" align="center">Version Control the Subversion Way</th>
|
||
</tr>
|
||
<tr>
|
||
<td width="20%" align="left"><a accesskey="p" href="svn.basic.version-control-basics.html">Prev</a> </td>
|
||
<th width="60%" align="center">Chapter 1. Fundamental Concepts</th>
|
||
<td width="20%" align="right"> <a accesskey="n" href="svn.basic.summary.html">Next</a></td>
|
||
</tr>
|
||
</table>
|
||
<hr />
|
||
</div>
|
||
<div class="sect1" title="Version Control the Subversion Way">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title" style="clear: both"><a id="svn.basic.in-action"></a>Version Control the Subversion Way</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We've mentioned already that Subversion is a modern,
|
||
network-aware version control system. As we described in
|
||
<a class="xref" href="svn.basic.version-control-basics.html" title="Version Control Basics">the section called “Version Control Basics”</a> (our
|
||
high-level version control overview), a repository serves as the
|
||
core storage mechanism for Subversion's versioned data, and it's
|
||
via working copies that users and their software programs
|
||
interact with that data. In this section, we'll begin to
|
||
introduce the specific ways in which Subversion implements
|
||
version control.</p>
|
||
<div class="sect2" title="Subversion Repositories">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h3 class="title"><a id="svn.basic.svn-repositories"></a>Subversion Repositories</h3>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Subversion implements the concept of a version control
|
||
repository much as any other modern version control system
|
||
would. Unlike a working copy, a Subversion repository is an
|
||
abstract entity, able to be operated upon almost exclusively
|
||
by Subversion's own libraries and tools. As most of a user's
|
||
Subversion interactions involve the use of the Subversion
|
||
client and occur in the context of a working copy, we spend
|
||
the majority of this book discussing the Subversion working
|
||
copy and how to manipulate it. For the finer details of the
|
||
repository, though, check out
|
||
<a class="xref" href="svn.reposadmin.html" title="Chapter 5. Repository Administration">Chapter 5, <i>Repository Administration</i></a>.</p>
|
||
</div>
|
||
<div class="sect2" title="Revisions">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h3 class="title"><a id="svn.basic.in-action.revs"></a>Revisions</h3>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a id="idp32239216" class="indexterm"></a>
|
||
<p>A Subversion client commits (that is, communicates the
|
||
changes made to) any number of files and directories as a
|
||
single atomic transaction. By atomic transaction, we mean
|
||
simply this: either all of the changes are accepted into the
|
||
repository, or none of them is. Subversion tries to retain
|
||
this atomicity in the face of program crashes, system crashes,
|
||
network problems, and other users' actions.</p>
|
||
<p>Each time the repository accepts a commit, this creates a
|
||
new state of the filesystem tree, called a
|
||
<em class="firstterm">revision</em>. Each revision is assigned a
|
||
unique natural number, one greater than the number assigned to
|
||
the previous revision. The initial revision of a freshly
|
||
created repository is numbered 0 and consists of nothing but
|
||
an empty root directory.</p>
|
||
<p><a class="xref" href="svn.basic.in-action.html#svn.basic.in-action.revs.dia-1" title="Figure 1.6. Tree changes over time">Figure 1.6, “Tree changes over time”</a>
|
||
illustrates a nice way to visualize the repository. Imagine
|
||
an array of revision numbers, starting at 0, stretching from
|
||
left to right. Each revision number has a filesystem tree
|
||
hanging below it, and each tree is a <span class="quote">“<span class="quote">snapshot</span>”</span>
|
||
of the way the repository looked after a commit.</p>
|
||
<div class="figure">
|
||
<a id="svn.basic.in-action.revs.dia-1"></a>
|
||
<p class="title">
|
||
<b>Figure 1.6. Tree changes over time</b>
|
||
</p>
|
||
<div class="figure-contents">
|
||
<div>
|
||
<img src="images/ch02dia7.png" alt="Tree changes over time" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<br class="figure-break" />
|
||
<div class="sidebar" title="Global Revision Numbers">
|
||
<p class="title">
|
||
<b>Global Revision Numbers</b>
|
||
</p>
|
||
<a id="idp32246432" class="indexterm"></a>
|
||
<p>Unlike most version control systems, Subversion's
|
||
revision numbers apply to <span class="emphasis"><em>entire trees</em></span>,
|
||
not individual files. Each revision number selects an
|
||
entire tree, a particular state of the repository after some
|
||
committed change. Another way to think about it is that
|
||
revision N represents the state of the repository filesystem
|
||
after the Nth commit. When Subversion users talk
|
||
about <span class="quote">“<span class="quote">revision 5 of
|
||
<code class="filename">foo.c</code>,</span>”</span> they really mean
|
||
<span class="quote">“<span class="quote"><code class="filename">foo.c</code> as it appears in revision
|
||
5.</span>”</span> Notice that in general, revisions N and M of a
|
||
file do <span class="emphasis"><em>not</em></span> necessarily differ! Many
|
||
other version control systems use per-file revision numbers,
|
||
so this concept may seem unusual at first. (Former CVS users
|
||
might want to see <a class="xref" href="svn.forcvs.html" title="Appendix B. Subversion for CVS Users">Appendix B, <i>Subversion for CVS Users</i></a> for more
|
||
details.)</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2" title="Addressing the Repository">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h3 class="title"><a id="svn.advanced.reposurls"></a>Addressing the Repository</h3>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a id="idp32253664" class="indexterm"></a>
|
||
<a id="idp32255440" class="indexterm"></a>
|
||
<p>Subversion client programs use URLs to identify versioned
|
||
files and directories in Subversion repositories. For the
|
||
most part, these URLs use the standard syntax, allowing for
|
||
server names and port numbers to be specified as part of the
|
||
URL.</p>
|
||
<div class="informalexample">
|
||
<div class="itemizedlist">
|
||
<ul class="itemizedlist" type="disc" compact="compact">
|
||
<li class="listitem">http://svn.example.com/svn/project</li>
|
||
<li class="listitem">http://svn.example.com:9834/repos</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<p>Subversion repository URLs aren't limited to only
|
||
the <code class="literal">http://</code> variety. Because Subversion
|
||
offers several different ways for its clients to communicate
|
||
with its servers, the URLs used to address the repository
|
||
change subtly depending on which repository access mechanism
|
||
is employed. <a class="xref" href="svn.basic.in-action.html#svn.basic.in-action.wc.tbl-1" title="Table 1.1. Repository access URLs">Table 1.1, “Repository access URLs”</a>
|
||
describes how different URL schemes map to the available
|
||
repository access methods. For more details about
|
||
Subversion's server options, see
|
||
<a class="xref" href="svn.serverconfig.html" title="Chapter 6. Server Configuration">Chapter 6, <i>Server Configuration</i></a>.</p>
|
||
<div class="table">
|
||
<a id="svn.basic.in-action.wc.tbl-1"></a>
|
||
<p class="title">
|
||
<b>Table 1.1. Repository access URLs</b>
|
||
</p>
|
||
<div class="table-contents">
|
||
<table summary="Repository access URLs" border="1">
|
||
<colgroup>
|
||
<col />
|
||
<col />
|
||
</colgroup>
|
||
<thead>
|
||
<tr>
|
||
<th>Schema</th>
|
||
<th>Access method</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<code class="literal">file:///</code>
|
||
</td>
|
||
<td>Direct repository access (on local disk)</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="literal">http://</code>
|
||
</td>
|
||
<td>Access via WebDAV protocol to Subversion-aware
|
||
Apache server</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="literal">https://</code>
|
||
</td>
|
||
<td>Same as <code class="literal">http://</code>, but with
|
||
SSL encryption.</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="literal">svn://</code>
|
||
</td>
|
||
<td>Access via custom protocol to an
|
||
<code class="literal">svnserve</code> server</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="literal">svn+ssh://</code>
|
||
</td>
|
||
<td>Same as <code class="literal">svn://</code>, but through
|
||
an SSH tunnel.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<br class="table-break" />
|
||
<p>Subversion's handling of URLs has some notable nuances.
|
||
For example, URLs containing the <code class="literal">file://</code>
|
||
access method (used for local repositories) must, in
|
||
accordance with convention, have either a server name
|
||
of <code class="literal">localhost</code> or no server name at
|
||
all:</p>
|
||
<div class="informalexample">
|
||
<div class="itemizedlist">
|
||
<ul class="itemizedlist" type="disc" compact="compact">
|
||
<li class="listitem">file:///var/svn/repos</li>
|
||
<li class="listitem">file://localhost/var/svn/repos</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<p>Also, users of the <code class="literal">file://</code> scheme on
|
||
Windows platforms will need to use an unofficially
|
||
<span class="quote">“<span class="quote">standard</span>”</span> syntax for accessing repositories
|
||
that are on the same machine, but on a different drive than
|
||
the client's current working drive. Either of the two
|
||
following URL path syntaxes will work, where
|
||
<code class="literal">X</code> is the drive on which the repository
|
||
resides:</p>
|
||
<div class="informalexample">
|
||
<div class="itemizedlist">
|
||
<ul class="itemizedlist" type="disc" compact="compact">
|
||
<li class="listitem">file:///X:/var/svn/repos</li>
|
||
<li class="listitem">file:///X|/var/svn/repos</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<p>Note that a URL uses forward slashes even though the
|
||
native (non-URL) form of a path on Windows uses backslashes.
|
||
Also note that when using
|
||
the <code class="literal">file:///<em class="replaceable"><code>X</code></em>|/</code>
|
||
form at the command line, you need to quote the URL (wrap it
|
||
in quotation marks) so that the vertical bar character is not
|
||
interpreted as a pipe.</p>
|
||
<div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;">
|
||
<table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25">
|
||
<img alt="[Note]" src="images/note.png" />
|
||
</td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr>
|
||
<td align="left" valign="top">
|
||
<p>You cannot use Subversion's <code class="literal">file://</code> URLs
|
||
in a regular web browser the way typical
|
||
<code class="literal">file://</code> URLs can. When you attempt to view
|
||
a <code class="literal">file://</code> URL in a regular web browser, it
|
||
reads and displays the contents of the file at that location
|
||
by examining the filesystem directly. However, Subversion's
|
||
resources exist in a virtual filesystem (see <a class="xref" href="svn.developer.layerlib.html#svn.developer.layerlib.repos" title="Repository Layer">the section called “Repository Layer”</a>), and your browser
|
||
will not understand how to interact with that
|
||
filesystem.</p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<p>The Subversion client will automatically encode URLs as
|
||
necessary, just like a web browser does. For example, the URL
|
||
<code class="literal">http://host/path with space/project/españa</code>
|
||
— which contains both spaces and upper-ASCII characters
|
||
— will be automatically interpreted by Subversion as if
|
||
you'd provided
|
||
<code class="literal">http://host/path%20with%20space/project/espa%C3%B1a</code>.
|
||
If the URL contains spaces, be sure to place it within
|
||
quotation marks at the command line so that your shell treats
|
||
the whole thing as a single argument to the program.</p>
|
||
<p>There is one notable exception to Subversion's handling of
|
||
URLs which also applies to its handling of local paths in many
|
||
contexts, too. If the final path component of your URL or
|
||
local path contains an at sign (<code class="literal">@</code>), you need
|
||
to use a special syntax—described in
|
||
<a class="xref" href="svn.advanced.pegrevs.html" title="Peg and Operative Revisions">the section called “Peg and Operative Revisions”</a>—in order to make
|
||
Subversion properly address that resource.</p>
|
||
<p>In Subversion 1.6, a new caret (<code class="literal">^</code>)
|
||
notation was introduced as a shorthand for <span class="quote">“<span class="quote">the URL of
|
||
the repository's root directory</span>”</span>. For example, you can
|
||
use the <code class="literal">^/tags/bigsandwich/</code> to refer to the
|
||
URL of the <code class="filename">/tags/bigsandwich</code> directory in
|
||
the root of the repository. Note that this URL syntax works
|
||
only when your current working directory is a working
|
||
copy—the command-line client knows the repository's root
|
||
URL by looking at the working copy's metadata. Also note that
|
||
when you wish to refer precisely to the root directory of the
|
||
repository, you must do so using <code class="literal">^/</code> (with
|
||
the trailing slash character), not merely
|
||
<code class="literal">^</code>.</p>
|
||
</div>
|
||
<div class="sect2" title="Subversion Working Copies">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h3 class="title"><a id="svn.basic.in-action.wc"></a>Subversion Working Copies</h3>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a id="idp32300736" class="indexterm"></a>
|
||
<p>A Subversion working copy is an ordinary directory tree on
|
||
your local system, containing a collection of files. You can
|
||
edit these files however you wish, and if they're source code
|
||
files, you can compile your program from them in the usual
|
||
way. Your working copy is your own private work area:
|
||
Subversion will never incorporate other people's changes, nor
|
||
make your own changes available to others, until you
|
||
explicitly tell it to do so. You can even have multiple
|
||
working copies of the same project.</p>
|
||
<p>After you've made some changes to the files in your
|
||
working copy and verified that they work properly, Subversion
|
||
provides you with commands to <span class="quote">“<span class="quote">publish</span>”</span> your
|
||
changes to the other people working with you on your project
|
||
(by writing to the repository). If other people publish their
|
||
own changes, Subversion provides you with commands to merge
|
||
those changes into your working copy (by reading from the
|
||
repository).</p>
|
||
<p>A working copy also contains some extra files, created and
|
||
maintained by Subversion, to help it carry out these commands.
|
||
In particular, each directory in your working copy contains a
|
||
subdirectory named <code class="filename">.svn</code>, also known as
|
||
the working copy's <em class="firstterm">administrative
|
||
directory</em>. The files in each administrative
|
||
directory help Subversion recognize which files contain
|
||
unpublished changes, and which files are out of date with
|
||
respect to others' work.</p>
|
||
<div class="sect3" title="How the working copy works">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h4 class="title"><a id="svn.basic.in-action.track-repos"></a>How the working copy works</h4>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>For each file in a working directory, Subversion records
|
||
(among other things) two essential pieces of
|
||
information:</p>
|
||
<div class="itemizedlist">
|
||
<ul class="itemizedlist" type="disc">
|
||
<li class="listitem">
|
||
<p>What revision your working file is based on (this is
|
||
called the file's <em class="firstterm">working
|
||
revision</em>)</p>
|
||
</li>
|
||
<li class="listitem">
|
||
<p>A timestamp recording when the local copy was last
|
||
updated by the repository</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<p>Given this information, by talking to the repository,
|
||
Subversion can tell which of the following four states a
|
||
working file is in:</p>
|
||
<div class="variablelist">
|
||
<dl>
|
||
<dt>
|
||
<span class="term">Unchanged, and current</span>
|
||
</dt>
|
||
<dd>
|
||
<p>The file is unchanged in the working directory, and
|
||
no changes to that file have been committed to the
|
||
repository since its working revision. An <span class="command"><strong>svn
|
||
commit</strong></span> of the file will do nothing, and an
|
||
<span class="command"><strong>svn update</strong></span> of the file will do
|
||
nothing.</p>
|
||
</dd>
|
||
<dt>
|
||
<span class="term">Locally changed, and current</span>
|
||
</dt>
|
||
<dd>
|
||
<p>The file has been changed in the working directory,
|
||
and no changes to that file have been committed to the
|
||
repository since you last updated. There are local
|
||
changes that have not been committed to the repository;
|
||
thus an <span class="command"><strong>svn commit</strong></span> of the file will
|
||
succeed in publishing your changes, and an <span class="command"><strong>svn
|
||
update</strong></span> of the file will do nothing.</p>
|
||
</dd>
|
||
<dt>
|
||
<span class="term">Unchanged, and out of date</span>
|
||
</dt>
|
||
<dd>
|
||
<p>The file has not been changed in the working
|
||
directory, but it has been changed in the repository.
|
||
The file should eventually be updated in order to make
|
||
it current with the latest public revision.
|
||
An <span class="command"><strong>svn commit</strong></span> of the file will do
|
||
nothing, and an
|
||
<span class="command"><strong>svn update</strong></span> of the file will fold the
|
||
latest changes into your working copy.</p>
|
||
</dd>
|
||
<dt>
|
||
<span class="term">Locally changed, and out of date</span>
|
||
</dt>
|
||
<dd>
|
||
<p>The file has been changed both in the working
|
||
directory and in the repository. An <span class="command"><strong>svn
|
||
commit</strong></span> of the file will fail with an
|
||
<span class="quote">“<span class="quote">out-of-date</span>”</span> error. The file should be
|
||
updated first; an <span class="command"><strong>svn update</strong></span> command
|
||
will attempt to merge the public changes with the local
|
||
changes. If Subversion can't complete the merge in a
|
||
plausible way automatically, it leaves it to the user to
|
||
resolve the conflict.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
<div class="sect3" title="Fundamental working copy interactions">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h4 class="title"><a id="svn.basic.in-action.wc-funcdamentals"></a>Fundamental working copy interactions</h4>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>A typical Subversion repository often holds the files (or
|
||
source code) for several projects; usually, each project is a
|
||
subdirectory in the repository's filesystem tree. In this
|
||
arrangement, a user's working copy will usually correspond to
|
||
a particular subtree of the repository.</p>
|
||
<p>For example, suppose you have a repository that contains
|
||
two software projects, <code class="literal">paint</code> and
|
||
<code class="literal">calc</code>. Each project lives in its own
|
||
top-level subdirectory, as shown in <a class="xref" href="svn.basic.in-action.html#svn.basic.in-action.wc.dia-1" title="Figure 1.7. The repository's filesystem">Figure 1.7, “The repository's filesystem”</a>.</p>
|
||
<div class="figure">
|
||
<a id="svn.basic.in-action.wc.dia-1"></a>
|
||
<p class="title">
|
||
<b>Figure 1.7. The repository's filesystem</b>
|
||
</p>
|
||
<div class="figure-contents">
|
||
<div>
|
||
<img src="images/ch02dia6.png" alt="The repository's filesystem" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<br class="figure-break" />
|
||
<a id="idp32331056" class="indexterm"></a>
|
||
<a id="idp32332832" class="indexterm"></a>
|
||
<a id="idp32334224" class="indexterm"></a>
|
||
<p>To get a working copy, you must <em class="firstterm">check
|
||
out</em> some subtree of the repository. (The term
|
||
<span class="emphasis"><em>check out</em></span> may sound like it has something to do
|
||
with locking or reserving resources, but it doesn't; it simply
|
||
creates a working copy of the project for you.) For example,
|
||
if you check out <code class="filename">/calc</code>, you will get a
|
||
working copy like this:</p>
|
||
<div class="informalexample">
|
||
<pre class="screen">
|
||
$ svn checkout http://svn.example.com/repos/calc
|
||
A calc/Makefile
|
||
A calc/integer.c
|
||
A calc/button.c
|
||
Checked out revision 56.
|
||
$ ls -A calc
|
||
Makefile button.c integer.c .svn/
|
||
$
|
||
</pre>
|
||
</div>
|
||
<p>The list of letter <code class="literal">A</code>s in the left
|
||
margin indicates that Subversion is adding a number of items
|
||
to your working copy. You now have a personal copy of the
|
||
repository's <code class="filename">/calc</code> directory, with one
|
||
additional entry—<code class="filename">.svn</code>—which
|
||
holds the extra information needed by Subversion, as mentioned
|
||
earlier.</p>
|
||
<p>Suppose you make changes to <code class="filename">button.c</code>.
|
||
Since the <code class="filename">.svn</code> directory remembers the
|
||
file's original modification date and contents, Subversion can
|
||
tell that you've changed the file. However, Subversion does
|
||
not make your changes public until you explicitly tell it to.
|
||
The act of publishing your changes is more commonly known as
|
||
<em class="firstterm">committing</em> (or <em class="firstterm">checking
|
||
in</em>) changes to the repository.</p>
|
||
<a id="idp32344112" class="indexterm"></a>
|
||
<a id="idp32345888" class="indexterm"></a>
|
||
<a id="idp32347280" class="indexterm"></a>
|
||
<p>To publish your changes to others, you can use
|
||
Subversion's <span class="command"><strong>svn commit</strong></span> command:</p>
|
||
<div class="informalexample">
|
||
<pre class="screen">
|
||
$ svn commit button.c -m "Fixed a typo in button.c."
|
||
Sending button.c
|
||
Transmitting file data .
|
||
Committed revision 57.
|
||
$
|
||
</pre>
|
||
</div>
|
||
<p>Now your changes to <code class="filename">button.c</code> have
|
||
been committed to the repository, with a note describing your
|
||
change (namely, that you fixed a typo). If another user
|
||
checks out a working copy of <code class="filename">/calc</code>, she
|
||
will see your changes in the latest version of the
|
||
file.</p>
|
||
<p>Suppose you have a collaborator, Sally, who checked out a
|
||
working copy of <code class="filename">/calc</code> at the same time
|
||
you did. When you commit your change to
|
||
<code class="filename">button.c</code>, Sally's working copy is left
|
||
unchanged; Subversion modifies working copies only at the
|
||
user's request.</p>
|
||
<a id="idp32354816" class="indexterm"></a>
|
||
<a id="idp32356592" class="indexterm"></a>
|
||
<a id="idp32357984" class="indexterm"></a>
|
||
<p>To bring her project up to date, Sally can ask Subversion
|
||
to <em class="firstterm">update</em> her working copy, by using
|
||
the <span class="command"><strong>svn update</strong></span> command. This will incorporate
|
||
your changes into her working copy, as well as any others that
|
||
have been committed since she checked it out.</p>
|
||
<div class="informalexample">
|
||
<pre class="screen">
|
||
$ pwd
|
||
/home/sally/calc
|
||
$ ls -A
|
||
Makefile button.c integer.c .svn/
|
||
$ svn update
|
||
Updating '.':
|
||
U button.c
|
||
Updated to revision 57.
|
||
$
|
||
</pre>
|
||
</div>
|
||
<p>The output from the <span class="command"><strong>svn update</strong></span> command
|
||
indicates that Subversion updated the contents of
|
||
<code class="filename">button.c</code>. Note that Sally didn't need to
|
||
specify which files to update; Subversion uses the information
|
||
in the <code class="filename">.svn</code> directory as well as further
|
||
information in the repository, to decide which files need to
|
||
be brought up to date.</p>
|
||
</div>
|
||
<div class="sect3" title="Mixed-revision working copies">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h4 class="title"><a id="svn.basic.in-action.mixedrevs"></a>Mixed-revision working copies</h4>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a id="idp32366160" class="indexterm"></a>
|
||
<p>As a general principle, Subversion tries to be as flexible
|
||
as possible. One special kind of flexibility is the ability
|
||
to have a working copy containing files and directories with a
|
||
mix of different working revision numbers. Subversion working
|
||
copies do not always correspond to any single revision in the
|
||
repository; they may contain files from several different
|
||
revisions. For example, suppose you check out a working copy
|
||
from a repository whose most recent revision is 4:</p>
|
||
<div class="informalexample">
|
||
<div class="literallayout">
|
||
<p><br />
|
||
calc/<br />
|
||
Makefile:4<br />
|
||
integer.c:4<br />
|
||
button.c:4<br />
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<p>At the moment, this working directory corresponds exactly
|
||
to revision 4 in the repository. However, suppose you make a
|
||
change to <code class="filename">button.c</code>, and commit that
|
||
change. Assuming no other commits have taken place, your
|
||
commit will create revision 5 of the repository, and your
|
||
working copy will now look like this:</p>
|
||
<div class="informalexample">
|
||
<div class="literallayout">
|
||
<p><br />
|
||
calc/<br />
|
||
Makefile:4<br />
|
||
integer.c:4<br />
|
||
button.c:5<br />
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<p>Suppose that, at this point, Sally commits a change to
|
||
<code class="filename">integer.c</code>, creating revision 6. If you
|
||
use <span class="command"><strong>svn update</strong></span> to bring your working copy
|
||
up to date, it will look like this:</p>
|
||
<div class="informalexample">
|
||
<div class="literallayout">
|
||
<p><br />
|
||
calc/<br />
|
||
Makefile:6<br />
|
||
integer.c:6<br />
|
||
button.c:6<br />
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<p>Sally's change to <code class="filename">integer.c</code> will
|
||
appear in your working copy, and your change will still be
|
||
present in <code class="filename">button.c</code>. In this example,
|
||
the text of <code class="filename">Makefile</code> is identical in
|
||
revisions 4, 5, and 6, but Subversion will mark your working
|
||
copy of <code class="filename">Makefile</code> with revision 6 to
|
||
indicate that it is still current. So, after you do a clean
|
||
update at the top of your working copy, it will generally
|
||
correspond to exactly one revision in the repository.</p>
|
||
<div class="sect4" title="Updates and commits are separate">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h5 class="title"><a id="svn.basic.in-action.mixedrevs.update-commit"></a>Updates and commits are separate</h5>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>One of the fundamental rules of Subversion is that
|
||
a <span class="quote">“<span class="quote">push</span>”</span> action does not cause
|
||
a <span class="quote">“<span class="quote">pull,</span>”</span> nor vice versa. Just
|
||
because you're ready to submit new changes to the repository
|
||
doesn't mean you're ready to receive changes from other
|
||
people. And if you have new changes still in progress,
|
||
<span class="command"><strong>svn update</strong></span> should gracefully merge
|
||
repository changes into your own, rather than forcing you to
|
||
publish them.</p>
|
||
<p>The main side effect of this rule is that it means a
|
||
working copy has to do extra bookkeeping to track mixed
|
||
revisions as well as be tolerant of the mixture. It's made
|
||
more complicated by the fact that directories themselves are
|
||
versioned.</p>
|
||
<p>For example, suppose you have a working copy entirely at
|
||
revision 10. You edit the
|
||
file <code class="filename">foo.html</code> and then perform
|
||
an <span class="command"><strong>svn commit</strong></span>, which creates revision 15
|
||
in the repository. After the commit succeeds, many new
|
||
users would expect the working copy to be entirely at
|
||
revision 15, but that's not the case! Any number of changes
|
||
might have happened in the repository between revisions 10
|
||
and 15. The client knows nothing of those changes in the
|
||
repository, since you haven't yet run <span class="command"><strong>svn
|
||
update</strong></span>, and <span class="command"><strong>svn commit</strong></span> doesn't
|
||
pull down new changes. If, on the other hand,
|
||
<span class="command"><strong>svn commit</strong></span> were to automatically download
|
||
the newest changes, it would be possible to set the
|
||
entire working copy to revision 15—but then we'd be
|
||
breaking the fundamental rule of <span class="quote">“<span class="quote">push</span>”</span>
|
||
and <span class="quote">“<span class="quote">pull</span>”</span> remaining separate actions.
|
||
Therefore, the only safe thing the Subversion client can do
|
||
is mark the one
|
||
file—<code class="filename">foo.html</code>—as being at
|
||
revision 15. The rest of the working copy remains at
|
||
revision 10. Only by running <span class="command"><strong>svn update</strong></span>
|
||
can the latest changes be downloaded and the whole working
|
||
copy be marked as revision 15.</p>
|
||
</div>
|
||
<div class="sect4" title="Mixed revisions are normal">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h5 class="title"><a id="svn.basic.in-action.mixedrevs.normal"></a>Mixed revisions are normal</h5>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The fact is, <span class="emphasis"><em>every time</em></span> you run
|
||
<span class="command"><strong>svn commit</strong></span> your working copy ends up
|
||
with some mixture of revisions. The things you just
|
||
committed are marked as having larger working revisions than
|
||
everything else. After several commits (with no updates
|
||
in between), your working copy will contain a whole mixture
|
||
of revisions. Even if you're the only person using the
|
||
repository, you will still see this phenomenon. To examine
|
||
your mixture of working revisions, use the <span class="command"><strong>svn
|
||
status</strong></span> command with the <code class="option">--verbose</code>
|
||
(<code class="option">-v</code>) option (see
|
||
<a class="xref" href="svn.tour.cycle.html#svn.tour.cycle.examine.status" title="See an overview of your changes">the section called “See an overview of your changes”</a> for more
|
||
information).</p>
|
||
<p>Often, new users are completely unaware that their
|
||
working copy contains mixed revisions. This can be
|
||
confusing, because many client commands are sensitive to the
|
||
working revision of the item they're examining. For
|
||
example, the <span class="command"><strong>svn log</strong></span> command is used to
|
||
display the history of changes to a file or directory (see
|
||
<a class="xref" href="svn.tour.history.html#svn.tour.history.log" title="Generating a List of Historical Changes">the section called “Generating a List of Historical Changes”</a>). When the user
|
||
invokes this command on a working copy object, he expects
|
||
to see the entire history of the object. But if the
|
||
object's working revision is quite old (often because
|
||
<span class="command"><strong>svn update</strong></span> hasn't been run in a long
|
||
time), the history of the <span class="emphasis"><em>older</em></span>
|
||
version of the object is shown.</p>
|
||
</div>
|
||
<div class="sect4" title="Mixed revisions are useful">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h5 class="title"><a id="svn.basic.in-action.mixedrevs.useful"></a>Mixed revisions are useful</h5>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>If your project is sufficiently complex, you'll discover
|
||
that it's sometimes nice to
|
||
forcibly <em class="firstterm">backdate</em> (or update to a
|
||
revision older than the one you already have) portions of
|
||
your working copy to an earlier revision; you'll learn how
|
||
to do that in <a class="xref" href="svn.tour.html" title="Chapter 2. Basic Usage">Chapter 2, <i>Basic Usage</i></a>. Perhaps you'd
|
||
like to test an earlier version of a submodule contained in
|
||
a subdirectory, or perhaps you'd like to figure out when a
|
||
bug first came into existence in a specific file. This is
|
||
the <span class="quote">“<span class="quote">time machine</span>”</span> aspect of a version control
|
||
system—the feature that allows you to move any
|
||
portion of your working copy forward and backward in
|
||
history.</p>
|
||
</div>
|
||
<div class="sect4" title="Mixed revisions have limitations">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h5 class="title"><a id="svn.basic.in-action.mixedrevs.limits"></a>Mixed revisions have limitations</h5>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>However you make use of mixed revisions in your working
|
||
copy, there are limitations to this flexibility.</p>
|
||
<p>First, you cannot commit the deletion of a file or
|
||
directory that isn't fully up to date. If a newer version
|
||
of the item exists in the repository, your attempt to delete
|
||
will be rejected to prevent you from accidentally
|
||
destroying changes you've not yet seen.</p>
|
||
<p>Second, you cannot commit a metadata change to a
|
||
directory unless it's fully up to date. You'll learn about
|
||
attaching <span class="quote">“<span class="quote">properties</span>”</span> to items in <a class="xref" href="svn.advanced.html" title="Chapter 3. Advanced Topics">Chapter 3, <i>Advanced Topics</i></a>. A directory's working revision
|
||
defines a specific set of entries and properties, and thus
|
||
committing a property change to an out-of-date directory may
|
||
destroy properties you've not yet seen.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="navfooter">
|
||
<hr />
|
||
<table width="100%" summary="Navigation footer">
|
||
<tr>
|
||
<td width="40%" align="left"><a accesskey="p" href="svn.basic.version-control-basics.html">Prev</a> </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="u" href="svn.basic.html">Up</a>
|
||
</td>
|
||
<td width="40%" align="right"> <a accesskey="n" href="svn.basic.summary.html">Next</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="40%" align="left" valign="top">Version Control Basics </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="h" href="index.html">Home</a>
|
||
</td>
|
||
<td width="40%" align="right" valign="top"> Summary</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div xmlns="" id="svn-footer">
|
||
<hr />
|
||
<p>You are reading <em>Version Control with Subversion</em> (for Subversion 1.7), by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.<br />
|
||
This work is licensed under the <a href="http://creativecommons.org/licenses/by/2.0/">Creative Commons Attribution License v2.0</a>.<br />
|
||
To submit comments, corrections, or other contributions to the text, please visit <a href="http://www.svnbook.com/">http://www.svnbook.com/</a>.</p>
|
||
</div>
|
||
</body>
|
||
</html>
|