[svnbook commit] r2813 - in trunk/src/ru: . book
dmitriy
noreply at red-bean.com
Fri Jun 29 13:24:49 CDT 2007
Author: dmitriy
Date: Fri Jun 29 13:24:49 2007
New Revision: 2813
Log:
* ru/book/ch-advanced-topics.xml
ru/book/ch-reference.xml
Merge r2608:2625
* ru/sync.py
Fix a typo
* ru/TRANSLATION-STATUS
Automatically update by sync.py
Modified:
trunk/src/ru/TRANSLATION-STATUS
trunk/src/ru/book/ (props changed)
trunk/src/ru/book/ch-advanced-topics.xml
trunk/src/ru/book/ch-reference.xml
trunk/src/ru/sync.py
Modified: trunk/src/ru/TRANSLATION-STATUS
==============================================================================
--- trunk/src/ru/TRANSLATION-STATUS (original)
+++ trunk/src/ru/TRANSLATION-STATUS Fri Jun 29 13:24:49 2007
@@ -38,7 +38,7 @@
Эти файлы переведены частично и работа над переводом продолжается,
или же в данный момент перевод этих файлов обновляется.
- * ch-advanced-topics.xml, 18%
+ * ch-advanced-topics.xml, 22%
* ch-branching-and-merging.xml, 82%
* ch-customizing-svn.xml, 64%
* ch-reference.xml, 22%
Modified: trunk/src/ru/book/ch-advanced-topics.xml
==============================================================================
--- trunk/src/ru/book/ch-advanced-topics.xml (original)
+++ trunk/src/ru/book/ch-advanced-topics.xml Fri Jun 29 13:24:49 2007
@@ -251,17 +251,17 @@
spaces.)</para>
<screen>
-$ svn checkout -r {2002-02-17}
+$ svn checkout -r {2006-02-17}
$ svn checkout -r {15:30}
$ svn checkout -r {15:30:00.200000}
-$ svn checkout -r {"2002-02-17 15:30"}
-$ svn checkout -r {"2002-02-17 15:30 +0230"}
-$ svn checkout -r {2002-02-17T15:30}
-$ svn checkout -r {2002-02-17T15:30Z}
-$ svn checkout -r {2002-02-17T15:30-04:00}
-$ svn checkout -r {20020217T1530}
-$ svn checkout -r {20020217T1530Z}
-$ svn checkout -r {20020217T1530-0500}
+$ svn checkout -r {"2006-02-17 15:30"}
+$ svn checkout -r {"2006-02-17 15:30 +0230"}
+$ svn checkout -r {2006-02-17T15:30}
+$ svn checkout -r {2006-02-17T15:30Z}
+$ svn checkout -r {2006-02-17T15:30-04:00}
+$ svn checkout -r {20060217T1530}
+$ svn checkout -r {20060217T1530Z}
+$ svn checkout -r {20060217T1530-0500}
…
</screen>
@@ -271,9 +271,9 @@
number:</para>
<screen>
-$ svn log --revision {2002-11-28}
+$ svn log -r {2006-11-28}
------------------------------------------------------------------------
-r12 | ira | 2002-11-27 12:31:51 -0600 (Wed, 27 Nov 2002) | 6 lines
+r12 | ira | 2006-11-27 12:31:51 -0600 (Mon, 27 Nov 2006) | 6 lines
…
</screen>
@@ -286,38 +286,38 @@
<!-- @ENGLISH {{{
<para>If you specify a single date as a revision without
specifying a time of day (for example
- <literal>2002-11-27</literal>), you may think that Subversion
+ <literal>2006-11-27</literal>), you may think that Subversion
should give you the last revision that took place on the
27th of November. Instead, you'll get back a revision from
the 26th, or even earlier. Remember that Subversion will
find the <emphasis>most recent revision of the
repository</emphasis> as of the date you give. If you give
a date without a timestamp, like
- <literal>2002-11-27</literal>, Subversion assumes a time of
+ <literal>2006-11-27</literal>, Subversion assumes a time of
00:00:00, so looking for the most recent revision won't
return anything on the day of the 27th.</para>
@ENGLISH }}} -->
<para>Указав при обращении к правке только дату, без указания
- времени (например, <literal>2002-11-27</literal>), возможно
+ времени (например, <literal>2006-11-27</literal>), возможно
вы подумаете, что Subversion выдаст вам последнюю правку за 27
ноября. А вместо этого можете получить правку за 26 число или
даже более раннюю. Помните, что Subversion будет искать
<emphasis>наиболее отвечающую</emphasis> указанной вами дате
правку хранилища. Если вы укажите дату без указания времени,
- например <literal>2002-11-27</literal>, Subversion примет за
+ например <literal>2006-11-27</literal>, Subversion примет за
временную метку 00:00:00 и таким образом поиск ближайшей к 27
числу ревизии не даст ничего относящегося к 27 ноября.</para>
<!-- @ENGLISH {{{
<para>If you want to include the 27th in your search, you can
- either specify the 27th with the time (<literal>{"2002-11-27
+ either specify the 27th with the time (<literal>{"2006-11-27
23:59"}</literal>), or just specify the next day
- (<literal>{2002-11-28}</literal>).</para>
+ (<literal>{2006-11-28}</literal>).</para>
@ENGLISH }}} -->
<para>Если вам необходимо найти именно 27 число, вы можете либо
- указать 27 число с временной меткой (<literal>{"2002-11-27
+ указать 27 число с временной меткой (<literal>{"2006-11-27
23:59"}</literal>) либо просто использовать в запросе следующий
- день (<literal>{2002-11-28}</literal>).</para>
+ день (<literal>{2006-11-28}</literal>).</para>
</sidebar>
@@ -329,9 +329,7 @@
найдет все правки между обеими датами включительно:</para>
<screen>
-$ svn log -r {2002-11-28}
-------------------------------------------------------------------------
-r12 | ira | 2002-11-27 12:31:51 -0600 (Wed, 27 Nov 2002) | 6 lines
+$ svn log -r {2006-11-20}:{2006-11-29}
…
</screen>
@@ -352,834 +350,524 @@
<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
- <sect1 id="svn.advanced.pegrevs">
- <title>Peg and Operative Revisions</title>
+ <sect1 id="svn.advanced.props">
+ <!-- @ENGLISH {{{
+ <title>Properties</title>
- <para>We make use of the ability to copy, move, rename, and
- completely replace files and directories on our computers all
- the time. And your version control system shouldn't get in the
- way of your doing these things with your version-controlled
- files and directories, either. Subversion's file management
- support is quite liberating, affording almost as much
- flexibility for versioned files as you'd expect when
- manipulating your unversioned ones. But that flexibility means
- that across the lifetime of your repository, a given versioned
- object might have many paths, and a given path might represent
- several entirely different versioned objects. And this
- introduces a certain level of complexity to your interactions
- with those paths and objects.</para>
+ <para>We've already covered in detail how Subversion stores and
+ retrieves various versions of files and directories in its
+ repository. Whole chapters have been devoted to this most
+ fundamental piece of functionality provided by the tool. And
+ if the versioning support stopped there, Subversion would still
+ be complete from a version control perspective.</para>
- <para>Subversion is pretty smart about noticing when an object's
- version history includes such <quote>changes of address</quote>.
- For example, if you ask for the revision history log of a
- particular file that was renamed last week, Subversion happily
- provides all those logs—the revision in which the rename
- itself happened, plus the logs of relevant revisions both before
- and after that rename. So, most of the time, you don't even
- have to think about such things. But occasionally, Subversion
- needs your help to clear up ambiguities.</para>
+ <para>But it doesn't stop there.</para>
- <para>The simplest example of this occurs when a directory or file
- is deleted from version control, and then a new directory or
- file is created with the same name and added to version control.
- Clearly the thing you deleted and the thing you later added
- aren't the same thing. They merely happen to have had the same
- path, <filename>/trunk/object</filename> for example. What,
- then, does it mean to ask Subversion about the history of
- <filename>/trunk/object</filename>? Are you asking about the
- thing currently at that location, or the old thing you deleted
- from that location? Are you asking about the operations that
- have happened to <emphasis>all</emphasis> the objects that have
- ever lived at that path? Clearly, Subversion needs a hint about
- what you really want.</para>
+ <para>In addition to versioning your directories and files,
+ Subversion provides interfaces for adding, modifying, and
+ removing versioned metadata on each of your versioned
+ directories and files. We refer to this metadata as
+ <firstterm>properties</firstterm>, and they can be thought of as
+ two-column tables that map property names to arbitrary values
+ attached to each item in your working copy. Generally speaking,
+ the names and values of the properties can be whatever you want
+ them to be, with the constraint that the names must be
+ human-readable text. And the best part about these properties
+ is that they, too, are versioned, just like the textual contents
+ of your files. You can modify, commit, and revert property
+ changes as easily as you can file content changes. And the
+ sending and receiving of property changes occurs as part of your
+ typical commit and update operations—you don't have to
+ change your basic processes to accomodate them.</para>
+ @ENGLISH }}} -->
+ <title>Свойства</title>
+ <para>Мы уже рассмотрели как Subversion сохраняет и получает
+ разные версии файлов и директорий из хранилища. Целые главы были
+ посвящены этой самой фундаментальной части функциональных
+ возможностей этого инструмента. И если поддержка версионирования
+ этим ограничится, Subversion все равно останется полноценным
+ инструментом с точки зрения управления версиями.</para>
+
+ <para>Однако версионирование этим не ограничивается.</para>
- <para>And thanks to moves, versioned object history can get far
- more twisted than that, even. For example, you might have a
- directory named <filename>concept</filename>, containing some
- nascent software project you've been toying with. Eventually,
- though, that project matures to the point that the idea seems to
- actually have some wings, so you do the unthinkable and decide
- to give the project a name.
- <footnote>
- <para><quote>You're not supposed to name it. Once you name it,
- you start getting attached to it.</quote> — Mike
- Wazowski</para>
- </footnote>
- Let's say you called your software Frabnaggilywort. At this
- point, it makes sense to rename the directory to reflect the
- project's new name, so <filename>concept</filename> is renamed
- to <filename>frabnaggilywort</filename>. Life goes on,
- Frabnaggilywort releases a 1.0 version, and is downloaded and
- used daily by hordes of people aiming to improve their
- lives.</para>
-
- <para>It's a nice story, really, but it doesn't end there.
- Entrepreneur that you are, you've already got another think in
- the tank. So you make a new directory,
- <filename>concept</filename>, and the cycle begins again. In
- fact, the cycle begins again many times over the years, each
- time starting with that old <filename>concept</filename>
- directory, then sometimes seeing that directory renamed as the
- idea cures, sometimes seeing it deleted when you scrap the idea.
- Or, to get really sick, maybe you rename
- <filename>concept</filename> to something else for a while, but
- later rename the thing back to <filename>concept</filename> for
- some reason.</para>
+ <para>Дополнительно к версионированнию директорий и файлов,
+ Subversion предоставляет для каждой версионированной директории
+ и файла интерфейс для добавления, изменения и удаления
+ версионированных метаданных. К этим метаданным мы обращаемся как
+ к <firstterm>свойствам</firstterm>, присоединенным к каждому
+ элементу рабочей копии, которые можно представить
+ в виде таблицы с двумя столбцами, которая сопоставляет
+ имена свойств соответствующим значениям. Вообще, имена
+ и значения свойств могут быть тем, чем вы хотите чтобы они были,
+ за исключением того, что имена должны быть читаемым текстом.
+ И лучшим из всего является то, что они тоже версионированы
+ также как и текстовое содержимое файлов. Можно также просто как и
+ для текстовых изменений изменять, фиксировать и отменять изменения
+ свойств. Отправка и получение измененных свойств происходит точно
+ так же как и обычные фиксации и обновления — для этого нет
+ необходимости менять обычный порядок действий.</para>
- <para>When scenarios like these occur, attempting to instruct
- Subversion to work with these re-used paths can be a little like
- instructing a motorist in Chicago's West Suburbs to drive east
- down Roosevelt Road and turn left onto Main Street. In a mere
- twenty minutes, you can cross <quote>Main Street</quote> in
- Wheaton, Glen Ellyn, and Lombard. And no, they aren't the same
- street. Our motorist—and our Subversion—need a
- little more detail in order to do the right thing.</para>
+ <!-- @ENGLISH {{{
+ <para>Properties show up elsewhere in Subversion, too. Just as
+ files and directories may have arbitrary property names and
+ values attached to them, each revision as a whole may have
+ arbitrary properties attached to it. The same constraints
+ apply—human-readable names and anything-you-want binary
+ values. The main difference is that revision properties are not
+ versioned. In other words, if you change the value of, or
+ delete, a revision property, there's no way within the scope of
+ Subversion's functionality to recover the previous value.</para>
+ @ENGLISH }}} -->
+ <para>Подобные приведенным выше, свойства используются и Subversion.
+ Так же как и произвольные имена свойств и соответствующие им значения,
+ имеются у файлов и директорий, каждая правка может иметь
+ произвольные свойства, присоединенные к ней. С теми же исключениями
+ — читаемое имя и любое бинарное значение. Главное отличие в том,
+ что свойства правок не версионируются. Другими словами, если изменить
+ значение свойства правки или удалить такое свойство, у Subversion нет
+ возможностей для восстановления предыдущего значения.</para>
- <para>In version 1.1, Subversion introduced a way for you to tell
- it exactly which Main Street you meant. It's called the
- <firstterm>peg revision</firstterm>, and it is a revision
- provided to Subversion for the sole purpose of identifying a
- unique line of history. Because at most one versioned object
- may occupy a path at any given time—or, more precisely, in
- any one revision—the combination of a path and a peg
- revision is all that is needed to refer to a specific line of
- history. Peg revisions are specified to the Subversion
- command-line client using <firstterm>at syntax</firstterm>, so
- called because the syntax involves appending an <quote>at
- sign</quote> (<literal>@</literal>) and the peg revision to the
- end of the path with which the revision is associated.</para>
+ <para>Subversion has no particular policy regarding the use of
+ properties. It asks only that you not use property names that
+ begin with the prefix <literal>svn:</literal>. That's the
+ namespace that it sets aside for its own use. And Subversion
+ does, in fact, use properties, both the versioned and
+ unversioned variety. Certain versioned properties have special
+ meaning or effects when found on files and directories, or house
+ a particular bit of information about the revisions on which
+ they are found. Certain revision properties are automatically
+ attached to revisions by Subversion's commit process, and carry
+ information about the revision. Most of these properties are
+ mentioned elsewhere in this or other chapters as part of the
+ more general topics to which they are related. For an
+ exhaustive list of Subversion's pre-defined properties, see
+ <xref linkend="svn.ref.svnprops"/>.</para>
- <para>But what of the <option>--revision (-r)</option> of which
- we've spoken so much in this book? That revision (or set of
- revisions) is called the <firstterm>operative
- revision</firstterm> (or <firstterm>operative revision
- range</firstterm>). Once a particular line of history has been
- identified using a path and peg revision, Subversion performs
- the requested operation using the operative revision(s). To map
- this to our Chicagoland streets analogy, if we are told to go to
- 606 N. Main Street in Wheaton,
- <footnote>
- <para>606 N. Main Street, Wheaton, Illinois, is the home of
- the Wheaton History Center. Get it—<quote>History
- Center</quote>? It seemed appropriate….</para>
- </footnote>
- we can think of <quote>Main Street</quote> as our path and
- <quote>Wheaton</quote> as our peg revision. These two pieces of
- information identify a unique path which can travelled (north or
- south on Main Street), and will keep us from travelling up and
- down the wrong Main Street in search of our destination. Now we
- throw in <quote>606 N.</quote> as our operative revision, of
- sorts, and we know <emphasis>exactly</emphasis> where to
- go.</para>
+ <!-- @ENGLISH {{{
+ <para>In this section, we will examine the utility—both to
+ users of Subversion, and to Subversion itself—of property
+ support. You'll learn about the property-related
+ <command>svn</command> subcommands, and how property
+ modifications affect your normal Subversion workflow.
+ Hopefully, you'll be convinced that Subversion properties can
+ enhance your version control experience.</para>
+ @ENGLISH }}} -->
+ <para>В этом разделе мы рассмотрим полезность — как для
+ пользователя, так и для самой Subversion — поддержки
+ свойств. Вы узнаете о командах <command>svn</command>, относящихся к
+ свойствам и том как модификация свойств влияет на привычный рабочий
+ цикл. Надеемся, вы убедитесь в том, что свойства в Subversion
+ расширяют возможности контроля версий.</para>
- <sidebar>
- <title>The peg revision algorithm</title>
-
- <para>The Subversion command-line performs the peg revision
- algorithm any time it needs to resolve possible ambiguities in
- the paths and revisions provided to it. Here's an example of
- such an invocation for the purposes of illustrating that
- algorithm.</para>
+ <!-- =============================================================== -->
+ <sect2 id="svn.advanced.props.why">
+ <!-- @ENGLISH {{{
+ <title>Why Properties?</title>
+ @ENGLISH }}} -->
+ <title>Зачем нужны свойства?</title>
- <screen>
-$ svn <replaceable>command</replaceable> -r <replaceable>OPERATIVE-REV</replaceable> item@<replaceable>PEG-REV</replaceable>
-</screen>
-
- <para>The algorithm has three simple steps:</para>
+ <para>Just as Subversion uses properties to store extra
+ information about the files, directories, and revisions that
+ it contains, you might also find properties to be of similar
+ use. Some part of the processes around Subversion's usage
+ to which you adhere, or maybe some additional tooling around
+ Subversion that you use, might find utility in having a place
+ close to your versioned data to hang custom metadata about
+ that data.</para>
- <itemizedlist>
-
- <listitem>
- <para>Locate <replaceable>item</replaceable> in the revision
- identified by <replaceable>PEG-REV</replaceable>. There
- can be only one such object.</para>
- </listitem>
+ <!-- @ENGLISH {{{
+ <para>Say you wish to design a website that houses many digital
+ photos, and displays them with captions and a datestamp. Now,
+ your set of photos is constantly changing, so you'd like to
+ have as much of this site automated as possible. These photos
+ can be quite large, so as is common with sites of this nature,
+ you want to provide smaller thumbnail images to your site
+ visitors.</para>
- <listitem>
- <para>Trace the object's history backwards (through any
- possible renames) to its ancestor in the
- revision <replaceable>OPERATIVE-REV</replaceable>.</para>
- </listitem>
+ <para>Now, you can get this functionality using traditional
+ files. That is, you can have your
+ <filename>image123.jpg</filename> and an
+ <filename>image123-thumbnail.jpg</filename> side-by-side in a
+ directory. Or if you want to keep the filenames the same, you
+ might have your thumbnails in a different directory, like
+ <filename>thumbnails/image123.jpg</filename>. You can also
+ store your captions and datestamps in a similar fashion, again
+ separated from the original image file. But the problem here
+ is that your collection of files grows in multiples with each
+ new photo added to the site.</para>
+ @ENGLISH }}} -->
+ <para>Скажем, вы хотите разработать веб-сайт, содержащий много
+ цифровых фотографий и показывающий их с подписью и датой.
+ Набор этих фотографий постоянно изменяется и вы захотите
+ по возможности максимально автоматизировать этот сайт. Фотографии
+ могут быть большого размера и как обычно делают на таких
+ сайтах, для своих посетителей вам будет необходимо показывать
+ миниатюры изображений.</para>
- <listitem>
- <para>Perform the requested action on that ancestor,
- wherever it is located, or whatever its name might
- be or have been at that time.</para>
- </listitem>
+ <para>Сделать это вы можете с помощью обычных
+ файлов. То есть рядом, в директории, вы можете иметь файлы
+ <filename>image123.jpg</filename> и
+ <filename>image123-thumbnail.jpg</filename>. Либо если вам необходимо
+ сохранить то-же имя файла, миниатюры должны будут находиться в
+ отдельной директории, например, так
+ <filename>thumbnails/image123.jpg</filename>. Подобным-же образом,
+ отдельно от основного графического файла, можно хранить описание и
+ дату. Проблема здесь в том, что дерево файлов будет многократно
+ увеличиваться при каждом добавлении на сайт фотографии.</para>
- </itemizedlist>
+ <!-- @ENGLISH {{{
+ <para>Now consider the same website deployed in a way that makes
+ use of Subversion's file properties. Imagine having a single
+ image file, <filename>image123.jpg</filename>, and then
+ properties set on that file named <literal>caption</literal>,
+ <literal>datestamp</literal>, and even
+ <literal>thumbnail</literal>. Now your working copy directory
+ looks much more manageable—in fact, it looks to the
+ casual browser like there are nothing but image files in it.
+ But your automation scripts know better. They know that they
+ can use <command>svn</command> (or better yet, they can use
+ the Subversion language bindings—see <xref
+ linkend="svn.developer.usingapi.otherlangs" />) to dig out the
+ extra information that your site needs to display without
+ having to read an index file or play path manipulation
+ games.</para>
+ @ENGLISH }}} -->
+ <para>Представим эту же ситуацию с веб сайтом, но при использовании
+ Subversion-свойств файлов. Допустим, имеется файл
+ <filename>image123.jpg</filename> и у этого файла установлено свойство
+ <literal>caption</literal>, <literal>datestamp</literal> и даже
+ <literal>thumbnail</literal>. В этом случае рабочая копия выглядит
+ гораздо более управляемо — фактически она будет выглядеть
+ так, как будто она ничего кроме графических файлов не содержит.
+ Однако ваш скрипт автоматизации знает больше. Он знает, что может
+ воспользоваться <command>svn</command> (а еще лучше языковой обвязкой
+ Subversion — см. <xref
+ linkend="svn.developer.usingapi.otherlangs" />) для получения
+ дополнительной, необходимой для показа на сайте информации,
+ не занимаясь чтением индексного файла или играми с путями
+ файлов.</para>
- <para>Note that even when you don't explicitly supply a peg
- revision or operative revision, they are still present. For
- your convenience, the default peg revision is
- <literal>BASE</literal> for working copy items and
- <literal>HEAD</literal> for repository URLs. And when no
- operative revision is provided, it defaults to being the same
- revision as the peg revision.</para>
-
- </sidebar>
+ <para>Custom revision properties are also frequently used. One
+ common such use is a property whose value contains an issue
+ tracker ID with which the revision is associated, perhaps
+ because the change made in that revision fixes a bug filed in
+ the tracker issue with that ID. Other uses include hanging
+ more friendly names on the revision—it might be hard to
+ remember that revision 1935 was a fully tested revision. But
+ if there's, say, a <literal>test-results</literal> property on
+ that revision with a value <literal>all passing</literal>,
+ that's meaningful information to have.</para>
- <para>Say that long ago we created our repository, and in revision 1
- added our first <filename>concept</filename> directory, plus an
- <filename>IDEA</filename> file in that directory talking about
- the concept. After several revisions in which real code was
- added and tweaked, we, in revision 20, renamed this directory to
- <filename>frabnaggilywort</filename>. By revision 27, we had a
- new concept, a new <filename>concept</filename> directory to
- hold it, and a new <filename>IDEA</filename> file to describe
- it. And then five years and twenty thousand revisions flew by,
- just like they would in any good romance story.</para>
+ <sidebar>
+ <title>Searchability (or, Why <emphasis>Not</emphasis>
+ Properties)</title>
- <para>Now, years later, we wonder what the
- <filename>IDEA</filename> file looked like back in revision 1.
- But Subversion needs to know if we are asking about how the
- <emphasis>current</emphasis> file looked back in revision 1, or
- are we asking for the contents of whatever file lived at
- <filename>concepts/IDEA</filename> in revision 1? Certainly
- those questions have different answers, and because of peg
- revisions, you can ask either of them. To find out how the
- current <filename>IDEA</filename> file looked in that old
- revision, you run:</para>
+ <para>For all their utility, Subversion properties—or,
+ more accurately, the available interfaces to them—have
+ a major shortcoming which diminishes their practicality.
+ While it is a simple matter to set a custom property,
+ <emphasis>finding</emphasis> that property later is whole
+ different ball of wax.</para>
- <screen>
-$ svn cat -r 1 concept/IDEA
-subversion/libsvn_client/ra.c:775: (apr_err=20014)
-svn: Unable to find repository location for 'concept/IDEA' in revision 1
-</screen>
+ <para>Trying to locate a custom revision property generally
+ involves performing a linear walk across all the revisions
+ of the repository, asking of each revision, "Do you have the
+ property I'm looking for?" Trying to find a custom
+ versioned property is painful, too, and often involves a
+ recursive <command>svn propget</command> across an entire
+ working copy. In your situation, that might not be as bad
+ as a linear walk across all revisions. But it certainly
+ leaves much to be desired in terms of both performance and
+ likelihood of success, especially if the scope of your
+ search would require a working copy from the root of your
+ repository.</para>
- <para>Of course, in this example, the current
- <filename>IDEA</filename> file didn't exist yet in revision 1,
- so Subversion gives an error. The command above is shorthand
- for a longer notation which explicitly lists a peg revision.
- The expanded notation is:</para>
+ <para>For this reason, you might choose—especially in
+ the revision property use-case—to simply add your
+ metadata to the revision's log message, using some
+ policy-driven (and perhaps programmatically-enforced)
+ formatting that is designed to be quickly parsed from the
+ output of <command>svn log</command>. It is quite common to
+ see in Subversion log messages the likes of:</para>
- <screen>
-$ svn cat -r 1 concept/IDEA at BASE
-subversion/libsvn_client/ra.c:775: (apr_err=20014)
-svn: Unable to find repository location for 'concept/IDEA' in revision 1
-</screen>
+ <programlisting>
+Issue(s): IZ2376, IZ1919
+Reviewed by: sally
- <para>And when executed, it has the expected results. Peg revisions
- generally default to a value of <literal>BASE</literal> (the
- revision currently present in the working copy) when applied to
- working copy paths, and of <literal>HEAD</literal> when applied
- to URLs.</para>
+This fixes a nasty segfault in the wort frabbing process
+…
+</programlisting>
- <para>The perceptive reader is probably wondering at this point if
- the peg revision syntax causes problems for working copy paths
- or URLs that actually have at signs in them. After
- all, how does <command>svn</command> know whether
- <literal>news at 11</literal> is the name of a directory in my
- tree, or just a syntax for <quote>revision 11 of
- <filename>news</filename></quote>? Thankfully, while
- <command>svn</command> will always assume the latter, there is a
- trivial workaround. You need only append an at sign to the
- end of the path, such as <literal>news at 11@</literal>.
- <command>svn</command> only cares about the last at sign in
- the argument, and it is not considered illegal to omit a literal
- peg revision specifier after that at sign. This workaround
- even applies to paths that end in an at sign—you would
- use <literal>filename@@</literal> to talk about a file named
- <filename>filename@</filename>.</para>
+ <para>But here again lies some misfortune. Subversion doesn't
+ yet provide a log message templating mechanism, which would
+ go a long way toward helping users be consistent with the
+ formatting of their log-embedded revision metadata.</para>
- <para>Let's ask the other question, then—in revision 1, what
- were the contents of whatever file occupied the address
- <filename>concepts/IDEA</filename> at the time? We'll use an
- explicit peg revision to help us out.</para>
+ </sidebar>
- <screen>
-$ svn cat concept/IDEA at 1
-The idea behind this project is to come up with a piece of software
-that can frab a naggily wort. Frabbing naggily worts is tricky
-business, and doing it incorrectly can have serious ramifications, so
-we need to employ over-the-top input validation and data verification
-mechanisms.
-</screen>
+ </sect2>
- <para>Notice that we didn't provide an operative revision this
- time. That's because when no operative revision is specified,
- Subversion assumes a default operative revision that's the same
- as the peg revision.</para>
+ <!-- =============================================================== -->
+ <sect2 id="svn.advanced.props.manip">
+ <!-- @ENGLISH {{{
+ <title>Manipulating Properties</title>
- <para>As you can see, the output from our operation appears to be
- correct. The text even mentions frabbing naggily worts, so this
- is almost certainly the file which describes the software now
- called Frabnaggilywort. In fact, we can verify this using the
- combination of an explicit peg revision and explicit operative
- revision. We know that in <literal>HEAD</literal>, the
- Frabnaggilywort project is located in the
- <filename>frabnaggilywort</filename> directory. So we specify
- that we want to see how the line of history identified in
- <literal>HEAD</literal> as the path
- <filename>frabnaggilywort/IDEA</filename> looked in revision
- 1.</para>
+ <para>The <command>svn</command> command affords a few ways to
+ add or modify file and directory properties. For properties
+ with short, human-readable values, perhaps the simplest way to
+ add a new property is to specify the property name and value
+ on the command-line of the <command>propset</command>
+ subcommand.</para>
+ @ENGLISH }}} -->
+ <title>Использование свойств</title>
- <screen>
-$ svn cat -r 1 frabnaggilywort/IDEA at HEAD
-The idea behind this project is to come up with a piece of software
-that can frab a naggily wort. Frabbing naggily worts is tricky
-business, and doing it incorrectly can have serious ramifications, so
-we need to employ over-the-top input validation and data verification
-mechanisms.
-</screen>
+ <para>Команда <command>svn</command> предоставляет несколько
+ способов добавления или изменения свойств файлов и директорий.
+ Свойства с короткими, читаемыми значениями, наверное проще всего
+ добавить указав имя и значение свойства в командной строке
+ подкоманды <command>propset</command>.</para>
- <para>And the peg and operative revisions need not be so trivial,
- either. For example, say <filename>frabnaggilywort</filename>
- had been deleted from <literal>HEAD</literal>, but we know it
- existed in revision 20, and we want to see the diffs for its
- <filename>IDEA</filename> file between revisions 4 and 10. We
- can use the peg revision 20 in conjunction with the URL that
- would have held Frabnaggilywort's <filename>IDEA</filename> file
- in revision 20, and then use 4 and 10 as our operative revision
- range.</para>
+ <screen>
+$ svn propset copyright '(c) 2006 Red-Bean Software' calc/button.c
+property 'copyright' set on 'calc/button.c'
+$
+</screen>
- <screen>
-$ svn diff -r 4:10 http://svn.red-bean.com/projects/frabnaggilywort/IDEA@20
-Index: frabnaggilywort/IDEA
-===================================================================
---- frabnaggilywort/IDEA (revision 4)
-+++ frabnaggilywort/IDEA (revision 10)
-@@ -1,5 +1,5 @@
--The idea behind this project is to come up with a piece of software
--that can frab a naggily wort. Frabbing naggily worts is tricky
--business, and doing it incorrectly can have serious ramifications, so
--we need to employ over-the-top input validation and data verification
--mechanisms.
-+The idea behind this project is to come up with a piece of
-+client-server software that can remotely frab a naggily wort.
-+Frabbing naggily worts is tricky business, and doing it incorrectly
-+can have serious ramifications, so we need to employ over-the-top
-+input validation and data verification mechanisms.
-</screen>
+ <!-- @ENGLISH {{{
+ <para>But we've been touting the flexibility that Subversion
+ offers for your property values. And if you are planning to
+ have a multi-line textual, or even binary, property value, you
+ probably do not want to supply that value on the command-line.
+ So the <command>propset</command> subcommand takes a
+ <option>-ﳢ-file</option> (<option>-F</option>) option for
+ specifying the name of
+ a file which contains the new property value.</para>
+ @ENGLISH }}} -->
+ <para>Однако мы уже знаем о гибкости, предлагаемой Subversion
+ для значений свойств. И если вам необходимо иметь многострочное
+ текстовое, или даже бинарное значение свойства, передавать
+ такое значение через командную строку не удобно. Для
+ таких случаев команда <command>propset</command> имеет
+ параметр <option>--file</option> (<option>-F</option>), указывающий
+ имя файла, содержащего новое значение свойства.</para>
- <para>Fortunately, most folks aren't faced with such complex
- situations. But when you are, remember that peg revisions are
- that extra hint Subversion needs to clear up ambiguity.</para>
+ <screen>
+$ svn propset license -F /path/to/LICENSE calc/button.c
+property 'license' set on 'calc/button.c'
+$
+</screen>
- </sect1>
+ <!-- @ENGLISH {{{
+ <para>There are some restrictions on the names you can use for
+ properties. A property name must start with a letter, a colon
+ (<literal>:</literal>), or an underscore
+ (<literal>_</literal>); after that, you can also use digits,
+ hyphens (<literal>-</literal>), and periods
+ (<literal>.</literal>).
+ <footnote>
+ <para>If you're familiar with XML, this is pretty much the
+ ASCII subset of the syntax for XML "Name".</para>
+ </footnote>
+ </para>
+ @ENGLISH }}} -->
+ <para>Для имен свойств существует ряд ограничений. Имя свойства должно
+ начинаться с буквы, двоеточия (<literal>:</literal>) или подчеркивания
+ (<literal>_</literal>); дальше можно использовать цифры, тире
+ (<literal>-</literal>) и точки (<literal>.</literal>).
+ <footnote>
+ <para>Если вы знакомы с XML, то синтаксис XML "Name" использует
+ практически тот же ASCII набор.</para>
+ </footnote>
+ </para>
+ <!-- @ENGLISH {{{
+ <para>In addition to the <command>propset</command> command, the
+ <command>svn</command> program supplies the
+ <command>propedit</command> command. This command uses the
+ configured editor program (see <xref
+ linkend="svn.advanced.confarea.opts.config" />) to add or
+ modify properties. When you run the command,
+ <command>svn</command> invokes your editor program on a
+ temporary file that contains the current value of the property
+ (or which is empty, if you are adding a new property). Then,
+ you just modify that value in your editor program until it
+ represents the new value you wish to store for the property,
+ save the temporary file, and then exit the editor program. If
+ Subversion detects that you've actually changed the existing
+ value of the property, it will accept that as the new property
+ value. If you exit your editor without making any changes, no
+ property modification will occur.</para>
+ @ENGLISH }}} -->
+ <para>Дополнительно к команде <command>propset</command>,
+ <command>svn</command> имеет команду <command>propedit</command>.
+ Эта команда использует для добавления или изменения свойств указанную
+ программу-редактор (см. <xref
+ linkend="svn.advanced.confarea.opts.config" />). При выполнении
+ команды, <command>svn</command> вызывает редактор с временным файлом,
+ содержащим текущее значение свойства (или с пустым файлом, если
+ добавляется новое свойство). Затем вы просто меняете в редакторе
+ значение, пока оно не станет таким, каким бы вы хотели его видеть,
+ сохраняете временный файл и выходите из редактора. Если Subversion
+ обнаружит, что вы действительно изменили существующие значение
+ свойства, будет установлено новое значение. Если вы вышли из
+ редактора не внеся изменений, модификации свойства не
+ произойдет.</para>
- <!-- ================================================================= -->
- <!-- ================================================================= -->
- <!-- ================================================================= -->
- <sect1 id="svn.advanced.props">
- <!-- @ENGLISH {{{
- <title>Properties</title>
+ <screen>
+$ svn propedit copyright calc/button.c ### exit the editor without changes
+No changes to property 'copyright' on 'calc/button.c'
+$
+</screen>
- <para>We've already covered in detail how Subversion stores and
- retrieves various versions of files and directories in its
- repository. Whole chapters have been devoted to this most
- fundamental piece of functionality provided by the tool. And
- if the versioning support stopped there, Subversion would still
- be complete from a version control perspective.</para>
+ <!-- @ENGLISH {{{
+ <para>We should note that, as with other <command>svn</command>
+ subcommands, those related to properties can act on multiple
+ paths at once. This enables you to modify properties on whole
+ sets of files with a single command. For example, we could
+ have done:</para>
+ @ENGLISH }}} -->
+ <para>Обращаем ваше внимание на то, что как и другие команды
+ <command>svn</command>, команды, относящиеся к свойствам
+ могут применяться к нескольким путям за раз. Это дает возможность
+ одной командой изменять свойства целого набора файлов. Например,
+ можно сделать вот так:</para>
- <para>But it doesn't stop there.</para>
+ <screen>
+$ svn propset copyright '(c) 2006 Red-Bean Software' calc/*
+property 'copyright' set on 'calc/Makefile'
+property 'copyright' set on 'calc/button.c'
+property 'copyright' set on 'calc/integer.c'
+…
+$
+</screen>
- <para>In addition to versioning your directories and files,
- Subversion provides interfaces for adding, modifying, and
- removing versioned metadata on each of your versioned
- directories and files. We refer to this metadata as
- <firstterm>properties</firstterm>, and they can be thought of as
- two-column tables that map property names to arbitrary values
- attached to each item in your working copy. Generally speaking,
- the names and values of the properties can be whatever you want
- them to be, with the constraint that the names must be
- human-readable text. And the best part about these properties
- is that they, too, are versioned, just like the textual contents
- of your files. You can modify, commit, and revert property
- changes as easily as you can file content changes. And the
- sending and receiving of property changes occurs as part of your
- typical commit and update operations—you don't have to
- change your basic processes to accomodate them.</para>
- @ENGLISH }}} -->
- <title>Свойства</title>
- <para>Мы уже рассмотрели как Subversion сохраняет и получает
- разные версии файлов и директорий из хранилища. Целые главы были
- посвящены этой самой фундаментальной части функциональных
- возможностей этого инструмента. И если поддержка версионирования
- этим ограничится, Subversion все равно останется полноценным
- инструментом с точки зрения управления версиями.</para>
-
- <para>Однако версионирование этим не ограничивается.</para>
+ <!-- @ENGLISH {{{
+ <para>All of this property adding and editing isn't really very
+ useful if you can't easily get the stored property value. So
+ the <command>svn</command> program supplies two subcommands
+ for displaying the names and values of properties stored on
+ files and directories. The <command>svn proplist</command>
+ command will list the names of properties that exist on a
+ path. Once you know the names of the properties on the node,
+ you can request their values individually using <command>svn
+ propget</command>. This command will, given a path (or set of
+ paths) and a property name, print the value of the property to
+ the standard output stream.</para>
+ @ENGLISH }}} -->
+ <para>Все эти добавления и редактирования свойств не очень полезны,
+ если нельзя просто узнать значение свойства. Поэтому для показа
+ сохраненных для файлов и директорий имен и значений свойств,
+ программа <command>svn</command> предлагает две подкоманды.
+ Команда <command>svn proplist</command> перечисляет существующие
+ для указанного пути свойства. После того как вы знаете имя свойства,
+ можно, используя <command>svn propget</command>, запросить его
+ значение. Эта команда выведет на стандартный поток ввода-вывода
+ значение свойства для элемента по указанному пути (или путями) и с
+ указанным именем.</para>
- <para>Дополнительно к версионированнию директорий и файлов,
- Subversion предоставляет для каждой версионированной директории
- и файла интерфейс для добавления, изменения и удаления
- версионированных метаданных. К этим метаданным мы обращаемся как
- к <firstterm>свойствам</firstterm>, присоединенным к каждому
- элементу рабочей копии, которые можно представить
- в виде таблицы с двумя столбцами, которая сопоставляет
- имена свойств соответствующим значениям. Вообще, имена
- и значения свойств могут быть тем, чем вы хотите чтобы они были,
- за исключением того, что имена должны быть читаемым текстом.
- И лучшим из всего является то, что они тоже версионированы
- также как и текстовое содержимое файлов. Можно также просто как и
- для текстовых изменений изменять, фиксировать и отменять изменения
- свойств. Отправка и получение измененных свойств происходит точно
- так же как и обычные фиксации и обновления — для этого нет
- необходимости менять обычный порядок действий.</para>
+ <screen>
+$ svn proplist calc/button.c
+Properties on 'calc/button.c':
+ copyright
+ license
+$ svn propget copyright calc/button.c
+(c) 2006 Red-Bean Software
+</screen>
- <!-- @ENGLISH {{{
- <para>Properties show up elsewhere in Subversion, too. Just as
- files and directories may have arbitrary property names and
- values attached to them, each revision as a whole may have
- arbitrary properties attached to it. The same constraints
- apply—human-readable names and anything-you-want binary
- values. The main difference is that revision properties are not
- versioned. In other words, if you change the value of, or
- delete, a revision property, there's no way within the scope of
- Subversion's functionality to recover the previous value.</para>
+ <!-- @ENGLISH {{{
+ <para>There's even a variation of the
+ <command>proplist</command> command that will list both the
+ name and value of all of the properties. Simply supply the
+ <option>-ﳢ-verbose</option> (<option>-v</option>) option.</para>
@ENGLISH }}} -->
- <para>Подобные приведенным выше, свойства используются и Subversion.
- Так же как и произвольные имена свойств и соответствующие им значения,
- имеются у файлов и директорий, каждая правка может иметь
- произвольные свойства, присоединенные к ней. С теми же исключениями
- — читаемое имя и любое бинарное значение. Главное отличие в том,
- что свойства правок не версионируются. Другими словами, если изменить
- значение свойства правки или удалить такое свойство, у Subversion нет
- возможностей для восстановления предыдущего значения.</para>
+ <para>Существует даже вариант команды <command>proplist</command>,
+ который перечисляет как имена, так и значения свойств. Просто
+ добавьте параметр <option>--verbose</option>
+ (<option>-v</option>).</para>
- <para>Subversion has no particular policy regarding the use of
- properties. It asks only that you not use property names that
- begin with the prefix <literal>svn:</literal>. That's the
- namespace that it sets aside for its own use. And Subversion
- does, in fact, use properties, both the versioned and
- unversioned variety. Certain versioned properties have special
- meaning or effects when found on files and directories, or house
- a particular bit of information about the revisions on which
- they are found. Certain revision properties are automatically
- attached to revisions by Subversion's commit process, and carry
- information about the revision. Most of these properties are
- mentioned elsewhere in this or other chapters as part of the
- more general topics to which they are related. For an
- exhaustive list of Subversion's pre-defined properties, see
- <xref linkend="svn.ref.svnprops"/>.</para>
+ <screen>
+$ svn proplist --verbose calc/button.c
+Properties on 'calc/button.c':
+ copyright : (c) 2006 Red-Bean Software
+ license : ================================================================
+Copyright (c) 2006 Red-Bean Software. All rights reserved.
- <!-- @ENGLISH {{{
- <para>In this section, we will examine the utility—both to
- users of Subversion, and to Subversion itself—of property
- support. You'll learn about the property-related
- <command>svn</command> subcommands, and how property
- modifications affect your normal Subversion workflow.
- Hopefully, you'll be convinced that Subversion properties can
- enhance your version control experience.</para>
- @ENGLISH }}} -->
- <para>В этом разделе мы рассмотрим полезность — как для
- пользователя, так и для самой Subversion — поддержки
- свойств. Вы узнаете о командах <command>svn</command>, относящихся к
- свойствам и том как модификация свойств влияет на привычный рабочий
- цикл. Надеемся, вы убедитесь в том, что свойства в Subversion
- расширяют возможности контроля версий.</para>
-
- <!-- =============================================================== -->
- <sect2 id="svn.advanced.props.why">
- <!-- @ENGLISH {{{
- <title>Why Properties?</title>
- @ENGLISH }}} -->
- <title>Зачем нужны свойства?</title>
-
- <para>Just as Subversion uses properties to store extra
- information about the files, directories, and revisions that
- it contains, you might also find properties to be of similar
- use. Some part of the processes around Subversion's usage
- to which you adhere, or maybe some additional tooling around
- Subversion that you use, might find utility in having a place
- close to your versioned data to hang custom metadata about
- that data.</para>
-
- <!-- @ENGLISH {{{
- <para>Say you wish to design a website that houses many digital
- photos, and displays them with captions and a datestamp. Now,
- your set of photos is constantly changing, so you'd like to
- have as much of this site automated as possible. These photos
- can be quite large, so as is common with sites of this nature,
- you want to provide smaller thumbnail images to your site
- visitors.</para>
-
- <para>Now, you can get this functionality using traditional
- files. That is, you can have your
- <filename>image123.jpg</filename> and an
- <filename>image123-thumbnail.jpg</filename> side-by-side in a
- directory. Or if you want to keep the filenames the same, you
- might have your thumbnails in a different directory, like
- <filename>thumbnails/image123.jpg</filename>. You can also
- store your captions and datestamps in a similar fashion, again
- separated from the original image file. But the problem here
- is that your collection of files grows in multiples with each
- new photo added to the site.</para>
- @ENGLISH }}} -->
- <para>Скажем, вы хотите разработать веб-сайт, содержащий много
- цифровых фотографий и показывающий их с подписью и датой.
- Набор этих фотографий постоянно изменяется и вы захотите
- по возможности максимально автоматизировать этот сайт. Фотографии
- могут быть большого размера и как обычно делают на таких
- сайтах, для своих посетителей вам будет необходимо показывать
- миниатюры изображений.</para>
-
- <para>Сделать это вы можете с помощью обычных
- файлов. То есть рядом, в директории, вы можете иметь файлы
- <filename>image123.jpg</filename> и
- <filename>image123-thumbnail.jpg</filename>. Либо если вам необходимо
- сохранить то-же имя файла, миниатюры должны будут находиться в
- отдельной директории, например, так
- <filename>thumbnails/image123.jpg</filename>. Подобным-же образом,
- отдельно от основного графического файла, можно хранить описание и
- дату. Проблема здесь в том, что дерево файлов будет многократно
- увеличиваться при каждом добавлении на сайт фотографии.</para>
-
- <!-- @ENGLISH {{{
- <para>Now consider the same website deployed in a way that makes
- use of Subversion's file properties. Imagine having a single
- image file, <filename>image123.jpg</filename>, and then
- properties set on that file named <literal>caption</literal>,
- <literal>datestamp</literal>, and even
- <literal>thumbnail</literal>. Now your working copy directory
- looks much more manageable—in fact, it looks to the
- casual browser like there are nothing but image files in it.
- But your automation scripts know better. They know that they
- can use <command>svn</command> (or better yet, they can use
- the Subversion language bindings—see <xref
- linkend="svn.developer.usingapi.otherlangs" />) to dig out the
- extra information that your site needs to display without
- having to read an index file or play path manipulation
- games.</para>
- @ENGLISH }}} -->
- <para>Представим эту же ситуацию с веб сайтом, но при использовании
- Subversion-свойств файлов. Допустим, имеется файл
- <filename>image123.jpg</filename> и у этого файла установлено свойство
- <literal>caption</literal>, <literal>datestamp</literal> и даже
- <literal>thumbnail</literal>. В этом случае рабочая копия выглядит
- гораздо более управляемо — фактически она будет выглядеть
- так, как будто она ничего кроме графических файлов не содержит.
- Однако ваш скрипт автоматизации знает больше. Он знает, что может
- воспользоваться <command>svn</command> (а еще лучше языковой обвязкой
- Subversion — см. <xref
- linkend="svn.developer.usingapi.otherlangs" />) для получения
- дополнительной, необходимой для показа на сайте информации,
- не занимаясь чтением индексного файла или играми с путями
- файлов.</para>
-
- <para>Custom revision properties are also frequently used. One
- common such use is a property whose value contains an issue
- tracker ID with which the revision is associated, perhaps
- because the change made in that revision fixes a bug filed in
- the tracker issue with that ID. Other uses include hanging
- more friendly names on the revision—it might be hard to
- remember that revision 1935 was a fully tested revision. But
- if there's, say, a <literal>test-results</literal> property on
- that revision with a value <literal>all passing</literal>,
- that's meaningful information to have.</para>
-
- <sidebar>
- <title>Searchability (or, Why <emphasis>Not</emphasis>
- Properties)</title>
-
- <para>For all their utility, Subversion properties—or,
- more accurately, the available interfaces to them—have
- a major shortcoming which diminishes their practicality.
- While it is a simple matter to set a custom property,
- <emphasis>finding</emphasis> that property later is whole
- different ball of wax.</para>
-
- <para>Trying to locate a custom revision property generally
- involves performing a linear walk across all the revisions
- of the repository, asking of each revision, "Do you have the
- property I'm looking for?" Trying to find a custom
- versioned property is painful, too, and often involves a
- recursive <command>svn propget</command> across an entire
- working copy. In your situation, that might not be as bad
- as a linear walk across all revisions. But it certainly
- leaves much to be desired in terms of both performance and
- likelihood of success, especially if the scope of your
- search would require a working copy from the root of your
- repository.</para>
-
- <para>For this reason, you might choose—especially in
- the revision property use-case—to simply add your
- metadata to the revision's log message, using some
- policy-driven (and perhaps programmatically-enforced)
- formatting that is designed to be quickly parsed from the
- output of <command>svn log</command>. It is quite common to
- see in Subversion log messages the likes of:</para>
-
- <programlisting>
-Issue(s): IZ2376, IZ1919
-Reviewed by: sally
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
-This fixes a nasty segfault in the wort frabbing process
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions, and the recipe for Fitz's famous
+red-beans-and-rice.
…
-</programlisting>
-
- <para>But here again lies some misfortune. Subversion doesn't
- yet provide a log message templating mechanism, which would
- go a long way toward helping users be consistent with the
- formatting of their log-embedded revision metadata.</para>
-
- </sidebar>
-
- </sect2>
+</screen>
- <!-- =============================================================== -->
- <sect2 id="svn.advanced.props.manip">
<!-- @ENGLISH {{{
- <title>Manipulating Properties</title>
-
- <para>The <command>svn</command> command affords a few ways to
- add or modify file and directory properties. For properties
- with short, human-readable values, perhaps the simplest way to
- add a new property is to specify the property name and value
- on the command-line of the <command>propset</command>
- subcommand.</para>
+ <para>The last property-related subcommand is
+ <command>propdel</command>. Since Subversion allows you to
+ store properties with empty values, you can't remove a
+ property altogether using <command>propedit</command> or
+ <command>propset</command>. For example, this command will
+ <emphasis>not</emphasis> yield the desired effect:</para>
@ENGLISH }}} -->
- <title>Использование свойств</title>
-
- <para>Команда <command>svn</command> предоставляет несколько
- способов добавления или изменения свойств файлов и директорий.
- Свойства с короткими, читаемыми значениями, наверное проще всего
- добавить указав имя и значение свойства в командной строке
- подкоманды <command>propset</command>.</para>
+ <para>Последней, относящейся к свойствам подкомандой является
+ <command>propdel</command>. Не смотря на то, что Subversion
+ позволяет сохранять свойства с пустыми значениями, полностью
+ удалить свойство, используя <command>propedit</command> или
+ <command>propset</command>, нельзя. Например, такая команда
+ не даст желаемого эффекта:</para>
<screen>
-$ svn propset copyright '(c) 2003 Red-Bean Software' calc/button.c
-property 'copyright' set on 'calc/button.c'
+$ svn propset license '' calc/button.c
+property 'license' set on 'calc/button.c'
+$ svn proplist --verbose calc/button.c
+Properties on 'calc/button.c':
+ copyright : (c) 2006 Red-Bean Software
+ license :
$
</screen>
<!-- @ENGLISH {{{
- <para>But we've been touting the flexibility that Subversion
- offers for your property values. And if you are planning to
- have a multi-line textual, or even binary, property value, you
- probably do not want to supply that value on the command-line.
- So the <command>propset</command> subcommand takes a
- <option>-ﳢ-file</option> (<option>-F</option>) option for
- specifying the name of
- a file which contains the new property value.</para>
+ <para>You need to use the <command>propdel</command> subcommand
+ to delete properties altogether. The syntax is similar to the
+ other property commands:</para>
@ENGLISH }}} -->
- <para>Однако мы уже знаем о гибкости, предлагаемой Subversion
- для значений свойств. И если вам необходимо иметь многострочное
- текстовое, или даже бинарное значение свойства, передавать
- такое значение через командную строку не удобно. Для
- таких случаев команда <command>propset</command> имеет
- параметр <option>--file</option> (<option>-F</option>), указывающий
- имя файла, содержащего новое значение свойства.</para>
+ <para>Для полного удаления свойств необходимо использовать
+ подкоманду <command>propdel</command>. Ее синтаксис такой же
+ как и у других команд работы со свойствами:</para>
<screen>
-$ svn propset license -F /path/to/LICENSE calc/button.c
-property 'license' set on 'calc/button.c'
+$ svn propdel license calc/button.c
+property 'license' deleted from 'calc/button.c'.
+$ svn proplist --verbose calc/button.c
+Properties on 'calc/button.c':
+ copyright : (c) 2006 Red-Bean Software
$
</screen>
<!-- @ENGLISH {{{
- <para>There are some restrictions on the names you can use for
- properties. A property name must start with a letter, a colon
- (<literal>:</literal>), or an underscore
- (<literal>_</literal>); after that, you can also use digits,
- hyphens (<literal>-</literal>), and periods
- (<literal>.</literal>).
+ <para>Remember those unversioned revision properties? You can
+ modify those, too, using the same <command>svn</command>
+ subcommands that we just described. Simply add the
+ <option>-ﳢ-revprop</option> command-line parameter, and specify
+ the revision whose property you wish to modify. Since
+ revisions are global, you don't need to specify a target path
+ to these property-related commands so long as you are
+ positioned in a working copy of the repository whose
+ revision property you wish to modify. Otherwise, you can
+ simply provide the URL of any path in the repository of
+ interest (including the repository's root URL). For example,
+ you might want to replace the commit log message of an
+ existing revision.
<footnote>
- <para>If you're familiar with XML, this is pretty much the
- ASCII subset of the syntax for XML "Name".</para>
- </footnote>
- </para>
- @ENGLISH }}} -->
- <para>Для имен свойств существует ряд ограничений. Имя свойства должно
- начинаться с буквы, двоеточия (<literal>:</literal>) или подчеркивания
- (<literal>_</literal>); дальше можно использовать цифры, тире
- (<literal>-</literal>) и точки (<literal>.</literal>).
- <footnote>
- <para>Если вы знакомы с XML, то синтаксис XML "Name" использует
- практически тот же ASCII набор.</para>
- </footnote>
- </para>
-
- <!-- @ENGLISH {{{
- <para>In addition to the <command>propset</command> command, the
- <command>svn</command> program supplies the
- <command>propedit</command> command. This command uses the
- configured editor program (see <xref
- linkend="svn.advanced.confarea.opts.config" />) to add or
- modify properties. When you run the command,
- <command>svn</command> invokes your editor program on a
- temporary file that contains the current value of the property
- (or which is empty, if you are adding a new property). Then,
- you just modify that value in your editor program until it
- represents the new value you wish to store for the property,
- save the temporary file, and then exit the editor program. If
- Subversion detects that you've actually changed the existing
- value of the property, it will accept that as the new property
- value. If you exit your editor without making any changes, no
- property modification will occur.</para>
- @ENGLISH }}} -->
- <para>Дополнительно к команде <command>propset</command>,
- <command>svn</command> имеет команду <command>propedit</command>.
- Эта команда использует для добавления или изменения свойств указанную
- программу-редактор (см. <xref
- linkend="svn.advanced.confarea.opts.config" />). При выполнении
- команды, <command>svn</command> вызывает редактор с временным файлом,
- содержащим текущее значение свойства (или с пустым файлом, если
- добавляется новое свойство). Затем вы просто меняете в редакторе
- значение, пока оно не станет таким, каким бы вы хотели его видеть,
- сохраняете временный файл и выходите из редактора. Если Subversion
- обнаружит, что вы действительно изменили существующие значение
- свойства, будет установлено новое значение. Если вы вышли из
- редактора не внеся изменений, модификации свойства не
- произойдет.</para>
-
- <screen>
-$ svn propedit copyright calc/button.c ### exit the editor without changes
-No changes to property 'copyright' on 'calc/button.c'
-$
-</screen>
-
- <!-- @ENGLISH {{{
- <para>We should note that, as with other <command>svn</command>
- subcommands, those related to properties can act on multiple
- paths at once. This enables you to modify properties on whole
- sets of files with a single command. For example, we could
- have done:</para>
- @ENGLISH }}} -->
- <para>Обращаем ваше внимание на то, что как и другие команды
- <command>svn</command>, команды, относящиеся к свойствам
- могут применяться к нескольким путям за раз. Это дает возможность
- одной командой изменять свойства целого набора файлов. Например,
- можно сделать вот так:</para>
-
- <screen>
-$ svn propset copyright '(c) 2002 Red-Bean Software' calc/*
-property 'copyright' set on 'calc/Makefile'
-property 'copyright' set on 'calc/button.c'
-property 'copyright' set on 'calc/integer.c'
-…
-$
-</screen>
-
- <!-- @ENGLISH {{{
- <para>All of this property adding and editing isn't really very
- useful if you can't easily get the stored property value. So
- the <command>svn</command> program supplies two subcommands
- for displaying the names and values of properties stored on
- files and directories. The <command>svn proplist</command>
- command will list the names of properties that exist on a
- path. Once you know the names of the properties on the node,
- you can request their values individually using <command>svn
- propget</command>. This command will, given a path (or set of
- paths) and a property name, print the value of the property to
- the standard output stream.</para>
- @ENGLISH }}} -->
- <para>Все эти добавления и редактирования свойств не очень полезны,
- если нельзя просто узнать значение свойства. Поэтому для показа
- сохраненных для файлов и директорий имен и значений свойств,
- программа <command>svn</command> предлагает две подкоманды.
- Команда <command>svn proplist</command> перечисляет существующие
- для указанного пути свойства. После того как вы знаете имя свойства,
- можно, используя <command>svn propget</command>, запросить его
- значение. Эта команда выведет на стандартный поток ввода-вывода
- значение свойства для элемента по указанному пути (или путями) и с
- указанным именем.</para>
-
- <screen>
-$ svn proplist calc/button.c
-Properties on 'calc/button.c':
- copyright
- license
-$ svn propget copyright calc/button.c
-(c) 2003 Red-Bean Software
-</screen>
-
- <!-- @ENGLISH {{{
- <para>There's even a variation of the
- <command>proplist</command> command that will list both the
- name and value of all of the properties. Simply supply the
- <option>-ﳢ-verbose</option> (<option>-v</option>) option.</para>
- @ENGLISH }}} -->
- <para>Существует даже вариант команды <command>proplist</command>,
- который перечисляет как имена, так и значения свойств. Просто
- добавьте параметр <option>--verbose</option>
- (<option>-v</option>).</para>
-
- <screen>
-$ svn proplist --verbose calc/button.c
-Properties on 'calc/button.c':
- copyright : (c) 2003 Red-Bean Software
- license : ================================================================
-Copyright (c) 2003 Red-Bean Software. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions, and the recipe for Fitz's famous
-red-beans-and-rice.
-…
-</screen>
-
- <!-- @ENGLISH {{{
- <para>The last property-related subcommand is
- <command>propdel</command>. Since Subversion allows you to
- store properties with empty values, you can't remove a
- property altogether using <command>propedit</command> or
- <command>propset</command>. For example, this command will
- <emphasis>not</emphasis> yield the desired effect:</para>
- @ENGLISH }}} -->
- <para>Последней, относящейся к свойствам подкомандой является
- <command>propdel</command>. Не смотря на то, что Subversion
- позволяет сохранять свойства с пустыми значениями, полностью
- удалить свойство, используя <command>propedit</command> или
- <command>propset</command>, нельзя. Например, такая команда
- не даст желаемого эффекта:</para>
-
- <screen>
-$ svn propset license '' calc/button.c
-property 'license' set on 'calc/button.c'
-$ svn proplist --verbose calc/button.c
-Properties on 'calc/button.c':
- copyright : (c) 2003 Red-Bean Software
- license :
-$
-</screen>
-
- <!-- @ENGLISH {{{
- <para>You need to use the <command>propdel</command> command to
- delete properties altogether. The syntax is similar to the
- преимущестпреимуществ:</para>
- @ENGLISH }}} -->
- <para>Для полного удаления свойств необходимо использовать
- команду <command>propdel</command>. Ее синтаксис такой же
- как и у других команд работы со свойствами:</para>
-
- <screen>
-$ svn propdel license calc/button.c
-property 'license' deleted from 'calc/button.c'.
-$ svn proplist --verbose calc/button.c
-Properties on 'calc/button.c':
- copyright : (c) 2003 Red-Bean Software
-$
-</screen>
-
- <!-- @ENGLISH {{{
- <para>Remember those unversioned revision properties? You can
- modify those, too, using the same <command>svn</command>
- subcommands that we just described. Simply add the
- <option>-ﳢ-revprop</option> command-line parameter, and specify
- the revision whose property you wish to modify. Since
- revisions are global, you don't need to specify a target path
- to these property-related commands so long as you are
- positioned in a working copy of the repository whose
- revision property you wish to modify. Otherwise, you can
- simply provide the URL of any path in the repository of
- interest (including the repository's root URL). For example,
- you might want to replace the commit log message of an
- existing revision.
- <footnote>
- <para>Fixing spelling errors, grammatical gotchas, and
- <quote>just-plain-wrongness</quote> in commit log
- messages is perhaps the most common use case for the
- <option>-ﳢ-revprop</option> option.</para>
- </footnote>
- If your current working directory is part of a working copy of
- your repository, you can simply run the
- <command>svn propset</command> command with no target path:</para>
+ <para>Fixing spelling errors, grammatical gotchas, and
+ <quote>just-plain-wrongness</quote> in commit log
+ messages is perhaps the most common use case for the
+ <option>-ﳢ-revprop</option> option.</para>
+ </footnote>
+ If your current working directory is part of a working copy of
+ your repository, you can simply run the
+ <command>svn propset</command> command with no target path:</para>
@ENGLISH }}} -->
<para>Помните, мы говорили о неверсионированных свойствах
правок? Их то же можно менять с помощью <command>svn</command>.
@@ -1304,7 +992,7 @@
Property changes on: calc/button.c
___________________________________________________________________
Name: copyright
- + (c) 2003 Red-Bean Software
+ + (c) 2006 Red-Bean Software
$
</screen>
@@ -1406,16 +1094,6 @@
unfortunately mean that to fully apply a patch generated by
<command>svn diff</command>, any property modifications will
need to be applied by hand.</para>
-
- <para>As you can see, the presence of property modifications has
- no outstanding effect on the typical Subversion workflow.
- Your general patterns of updating your working copy, checking
- the status of your files and directories, reporting on the
- modifications you have made, and committing those
- modifications to the repository are completely immune to the
- presence or absence of properties. The <command>svn</command>
- program has some additional subcommands for actually making
- property changes, but that is the only noticeable asymmetry.</para>
@ENGLISH }}} -->
<para>Кроме того нужно помнить о нестандартном подходе, используемом
Subversion при выводе различий для свойств. Безусловно, можно
@@ -1427,14 +1105,6 @@
<command>svn diff</command>, изменения свойств нужно вносить в
ручную.</para>
- <para>Как видите, наличие измененных свойств никак не отражается
- на привычном рабочем цикле. Операции обновления рабочей копии,
- проверки статуса файлов и директорий, вывод сообщений о сделанных
- изменениях и фиксация этих изменений в хранилище никак не зависят от
- наличия или отсутствия свойств. У <command>svn</command> просто
- имеется несколько дополнительных подкоманд для внесения изменений в
- свойства однако это просто достойное внимания отличие.</para>
-
</sect2>
<!-- =============================================================== -->
@@ -1537,67 +1207,76 @@
<sect2 id="svn.advanced.props.special.mime-type">
<title>File Content Type</title>
- <para>Software programs on most modern operating systems make
- assumptions about the type and format of the contents of a
- file by the file's name, specifically its file extension. For
- example, files whose names end in <filename>.txt</filename>
- are generally assumed to be human-readable, able to be
- understood by simple perusal rather than requiring complex
- processing to decipher. Files whose names end in
- <filename>.png</filename>, on the other hand, are assumed to
- be of the Portable Network Graphics type—not
- human-readable at all, and sensible only when interpreted by
- software which understands the PNG format and can render the
- information in that format as a raster image.</para>
-
- <para>Unfortunately, some of those extensions have changed
- meanings over time. When personal computers first appeared, a
- file named <filename>README.DOC</filename> would have almost
- certainly been a plaintext file, just like today's
- <filename>.txt</filename> files. But by the mid-1990's,
- you could almost bet that a file of that name would not be a
- plaintext file at all, but instead a Microsoft Word document
- with a proprietary, non-human-readable format. But this
- change didn't occur overnight—there was certainly a
- period of confusion for computer users over what exactly they
- had in hand when they saw a <filename>.DOC</filename> file.
- <footnote>
- <para>You think that was rough? During that same era,
- WordPerfect also used <filename>.DOC</filename> for their
- proprietary file format's preferred extension!</para>
- </footnote>
- </para>
+ <para>Subversion joins the ranks of the many applications which
+ recognize and make use of Multipurpose Internet Mail
+ Extensions (MIME) content types. Besides being a
+ general-purpose storage location for a file's content type,
+ the value of the <literal>svn:mime-type</literal> file
+ property determines some behavioral characteristics of
+ Subversion itself.</para>
+
+ <sidebar>
+ <title>Identifying File Types</title>
+
+ <para>Software programs on most modern operating systems make
+ assumptions about the type and format of the contents of a
+ file by the file's name, specifically its file extension.
+ For example, files whose names end in
+ <filename>.txt</filename> are generally assumed to be
+ human-readable, able to be understood by simple perusal
+ rather than requiring complex processing to decipher. Files
+ whose names end in <filename>.png</filename>, on the other
+ hand, are assumed to be of the Portable Network Graphics
+ type—not human-readable at all, and sensible only when
+ interpreted by software which understands the PNG format and
+ can render the information in that format as a raster
+ image.</para>
+
+ <para>Unfortunately, some of those extensions have changed
+ meanings over time. When personal computers first appeared,
+ a file named <filename>README.DOC</filename> would have
+ almost certainly been a plaintext file, just like today's
+ <filename>.txt</filename> files. But by the mid-1990's, you
+ could almost bet that a file of that name would not be a
+ plaintext file at all, but instead a Microsoft Word document
+ with a proprietary, non-human-readable format. But this
+ change didn't occur overnight—there was certainly a
+ period of confusion for computer users over what exactly
+ they had in hand when they saw a <filename>.DOC</filename>
+ file.
+ <footnote>
+ <para>You think that was rough? During that same era,
+ WordPerfect also used <filename>.DOC</filename> for their
+ proprietary file format's preferred extension!</para>
+ </footnote>
+ </para>
- <para>The popularity of computer networking cast still more
- doubt on the mapping between a file's name and its content.
- With information being served across networks and generated
- dynamically by server-side scripts, there was often no real
- file <foreignphrase>per se</foreignphrase> to speak of, and
- therefore no file name. Web servers, for example, needed some
- other way to tell browsers what they were downloading so the
- browser could do something intelligent with that information,
- whether that was to display the data using a program
- registered to handle that data type, or to prompt the user for
- where on the client machine to store the downloaded
- data.</para>
-
- <para>Eventually, a standard emerged for, among other things,
- describing the contents of a data stream. In 1996, RFC2045
- was published, the first of five RFCs describing Multipurpose
- Internet Mail Extensions (MIME). In it, this RFC describes
- the concept of media types and subtypes, and recommends a
- syntax for the representation of those types. Today, MIME
- media types—or, MIME types— are used almost
- universally across e-mail applications, Web servers, and other
- software as the <foreignphrase>de facto</foreignphrase>
- mechanism for clearing up the file content confusion.</para>
-
- <para>Subversion joins the ranks of applications which recognize
- and make use of MIME types. Besides being a general-purpose
- storage location for a file's content type, the value of the
- <literal>svn:mime-type</literal> file property determines some
- behavioral characteristics of Subversion itself.</para>
+ <para>The popularity of computer networking cast still more
+ doubt on the mapping between a file's name and its content.
+ With information being served across networks and generated
+ dynamically by server-side scripts, there was often no real
+ file <foreignphrase>per se</foreignphrase> to speak of, and
+ therefore no file name. Web servers, for example, needed
+ some other way to tell browsers what they were downloading
+ so the browser could do something intelligent with that
+ information, whether that was to display the data using a
+ program registered to handle that data type, or to prompt
+ the user for where on the client machine to store the
+ downloaded data.</para>
+
+ <para>Eventually, a standard emerged for, among other things,
+ describing the contents of a data stream. In 1996, RFC2045
+ was published, the first of five RFCs describing MIME. In
+ it, this RFC describes the concept of media types and
+ subtypes, and recommends a syntax for the representation of
+ those types. Today, MIME media types—or, MIME
+ types— are used almost universally across e-mail
+ applications, Web servers, and other software as the
+ <foreignphrase>de facto</foreignphrase> mechanism for
+ clearing up the file content confusion.</para>
+ </sidebar>
+
<para>For example, one of the benefits that Subversion typically
provides is contextual, line-based merging of changes received
from the server during an update into your working file. But
@@ -1819,7 +1498,7 @@
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.advanced.props.special.ignore">
- <title>Selective Versioning</title>
+ <title>Ignoring Unversioned Items</title>
<para>In any given working copy there is a good chance that
alongside all those versioned files and directories are other
@@ -1847,7 +1526,7 @@
directories—its output can get quite noisy where many of
these things exist.</para>
- <para>So Subversion provides a pair of ways for telling it which
+ <para>So Subversion provides two ways for telling it which
files you would prefer that it simply disregard. One of the
ways involves the use of Subversion's runtime configuration
system (see <xref linkend="svn.advanced.confarea" />), and
@@ -1895,7 +1574,7 @@
<para>Subversion's support for ignorable file patterns extends
only to the one-time process of adding unversioned
files and directories to version control. Once an object is
- under Subversion's watchkeep, the ignore pattern mechanisms no
+ under Subversion's control, the ignore pattern mechanisms no
longer apply to it. In other words, don't expect Subversion
to avoid committing changes you've made to a versioned file
simply because that file's name matches an ignore
@@ -1904,1367 +1583,1738 @@
</warning>
<sidebar>
- <title>Ignore Patterns for CVS Users</title>
-
- <para>The Subversion <literal>svn:ignore</literal> property is
- very similar in syntax and function to the CVS
- <filename>.cvsignore</filename> file. In fact, if you are
- migrating a CVS working copy to Subversion, you can directly
- migrate the ignore patterns by using the
- <filename>.cvsignore</filename> file as input file to the
- <command>svn propset</command> command:</para>
-
- <screen>
-$ svn propset svn:ignore -F .cvsignore .
-property 'svn:ignore' set on '.'
-$
-</screen>
-
- <para>There are, however, some differences in the ways that CVS
- and Subversion handle ignore patterns. The two systems use
- the ignore patterns at some different times, and there are
- slight discrepancies in what the ignore patterns apply to.
- Also, Subversion does not recognize the use of the
- <literal>!</literal> pattern as a reset back to having no
- ignore patterns at all.</para>
+ <title>Ignore Patterns for CVS Users</title>
+
+ <para>The Subversion <literal>svn:ignore</literal> property is
+ very similar in syntax and function to the CVS
+ <filename>.cvsignore</filename> file. In fact, if you are
+ migrating a CVS working copy to Subversion, you can directly
+ migrate the ignore patterns by using the
+ <filename>.cvsignore</filename> file as input file to the
+ <command>svn propset</command> command:</para>
+
+ <screen>
+$ svn propset svn:ignore -F .cvsignore .
+property 'svn:ignore' set on '.'
+$
+</screen>
+
+ <para>There are, however, some differences in the ways that CVS
+ and Subversion handle ignore patterns. The two systems use
+ the ignore patterns at some different times, and there are
+ slight discrepancies in what the ignore patterns apply to.
+ Also, Subversion does not recognize the use of the
+ <literal>!</literal> pattern as a reset back to having no
+ ignore patterns at all.</para>
+
+ </sidebar>
+
+ <para>The global list of ignore patterns tends to be more a
+ matter of personal taste, and tied more closely to a user's
+ particular tool chain than to the details of any particular
+ working copy's needs. So, the rest of this section will focus
+ on the <literal>svn:ignore</literal> property and its
+ uses.</para>
+
+ <para>Say you have the following output from <command>svn
+ status</command>:</para>
+
+ <screen>
+$ svn status calc
+ M calc/button.c
+? calc/calculator
+? calc/data.c
+? calc/debug_log
+? calc/debug_log.1
+? calc/debug_log.2.gz
+? calc/debug_log.3.gz
+</screen>
+
+ <para>In this example, you have made some property modifications
+ to <filename>button.c</filename>, but in your working copy you
+ also have some unversioned files: the latest
+ <filename>calculator</filename> program that you've compiled
+ from your source code, a source file named
+ <filename>data.c</filename>, and a set of debugging output log
+ files. Now, you know that your build system always results in
+ the <filename>calculator</filename> program being generated.
+ <footnote>
+ <para>Isn't that the whole point of a build system?</para>
+ </footnote>
+ And you know that your test suite always leaves those debugging
+ log files lying around. These facts are true for all working
+ copies of this project, not just your own. And you know that
+ you aren't interested in seeing those things every time you run
+ <command>svn status</command>, and pretty sure that nobody else
+ is interested in them either. So you use <command>svn propedit
+ svn:ignore calc</command> to add some ignore patterns to the
+ <filename>calc</filename> directory. For example, you might add
+ this as the new value of the <literal>svn:ignore</literal>
+ property:</para>
+
+ <programlisting>
+calculator
+debug_log*
+</programlisting>
+
+ <para>After you've added this property, you will now have a local
+ property modification on the <filename>calc</filename>
+ directory. But notice what else is different about your
+ <command>svn status</command> output:</para>
+
+ <screen>
+$ svn status
+ M calc
+ M calc/button.c
+? calc/data.c
+</screen>
+
+ <para>Now, all that cruft is missing from the output! Of course,
+ your <filename>calculator</filename> compiled program and all
+ those logfiles are still in your working copy. Subversion is
+ simply not reminding you that they are present and unversioned.
+ And now with all the uninteresting noise removed from the
+ display, you are left with more interesting items—such as
+ that source code file <filename>data.c</filename> that you
+ probably forgot to add to version control.</para>
+
+ <para>Of course, this less-verbose report of your working copy
+ status isn't the only one available. If you actually want to
+ see the ignored files as part of the status report, you can pass
+ the <option>--no-ignore</option> option to Subversion:</para>
+
+ <screen>
+$ svn status --no-ignore
+ M calc
+ M calc/button.c
+I calc/calculator
+? calc/data.c
+I calc/debug_log
+I calc/debug_log.1
+I calc/debug_log.2.gz
+I calc/debug_log.3.gz
+</screen>
+
+ <para>As mentioned earlier, the list of file patterns to ignore is
+ also used by <command>svn add</command> and <command>svn
+ import</command>. Both of these operations involve asking
+ Subversion to begin managing some set of files and directories.
+ Rather than force the user to pick and choose which files in a
+ tree she wishes to start versioning, Subversion uses the ignore
+ patterns—both the global and the per-directory
+ lists—to determine which files should not be swept into
+ the version control system as part of a larger recursive
+ addition or import operation. And here again, you can use the
+ <option>--no-ignore</option> option to tell Subversion ignore
+ its ignores list and operate on all the files and directories
+ present.</para>
+
+ </sect1>
+
+ <!-- ================================================================= -->
+ <!-- ================================================================= -->
+ <!-- ================================================================= -->
+ <sect1 id="svn.advanced.props.special.keywords">
+ <title>Keyword Substitution</title>
+
+ <para>Subversion has the ability to substitute
+ <firstterm>keywords</firstterm>—pieces of useful,
+ dynamic information about a versioned file—into the
+ contents of the file itself. Keywords generally describe
+ information about the last time the file was known to be
+ modified. Because this information changes each time the
+ file changes, and more importantly, just
+ <emphasis>after</emphasis> the file changes, it is a hassle
+ for any process except the version control system to keep
+ the data completely up-to-date. Left to human authors, the
+ information would inevitably grow stale.</para>
+
+ <para>For example, say you have a document in which you would
+ like to display the last date on which it was modified. You
+ could burden every author of that document to, just before
+ committing their changes, also tweak the part of the
+ document that describes when it was last changed. But
+ sooner or later, someone would forget to do that. Instead
+ simply ask Subversion to perform keyword substitution on the
+ <literal>LastChangedDate</literal> keyword. You control
+ where the keyword is inserted into your document by placing
+ a <firstterm>keyword anchor</firstterm> at the desired
+ location in the file. This anchor is just a string of text
+ formatted as
+ <literal>$</literal><replaceable>KeywordName</replaceable><literal>$</literal>.</para>
+
+ <para>All keywords are case-sensitive where they appear as
+ anchors in files: you must use the correct capitalization in
+ order for the keyword to be expanded. You should consider the
+ value of the <literal>svn:keywords</literal> property to be
+ case-sensitive too—certain keyword names will be recognized
+ regardless of case, but this behavior is deprecated.</para>
+
+ <para>Subversion defines the list of keywords available for
+ substitution. That list contains the following five keywords,
+ some of which have aliases that you can also use:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Date</literal></term>
+ <listitem>
+ <para>This keyword describes the last time the file was
+ known to have been changed in the repository, and
+ looks something like <literal>$Date:
+ 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006)
+ $</literal>. It may also be specified as
+ <literal>LastChangedDate</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Revision</literal></term>
+ <listitem>
+ <para>This keyword describes the last known revision in
+ which this file changed in the repository, and looks
+ something like <literal>$Revision: 144 $</literal>.
+ It may also be specified as
+ <literal>LastChangedRevision</literal> or
+ <literal>Rev</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Author</literal></term>
+ <listitem>
+ <para>This keyword describes the last known user to
+ change this file in the repository, and looks
+ something like <literal>$Author: harry $</literal>.
+ It may also be specified as
+ <literal>LastChangedBy</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>HeadURL</literal></term>
+ <listitem>
+ <para>This keyword describes the full URL to the latest
+ version of the file in the repository, and looks
+ something like <literal>$HeadURL:
+ http://svn.collab.net/repos/trunk/README $</literal>.
+ It may be abbreviated as
+ <literal>URL</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Id</literal></term>
+ <listitem>
+ <para>This keyword is a compressed combination of the
+ other keywords. Its substitution looks something like
+ <literal>$Id: calc.c 148 2006-07-28 21:30:43Z sally
+ $</literal>, and is interpreted to mean that the file
+ <filename>calc.c</filename> was last changed in revision
+ 148 on the evening of July 28, 2006 by the user
+ <literal>sally</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Simply adding keyword anchor text to your file does
+ nothing special. Subversion will never attempt to perform
+ textual substitutions on your file contents unless
+ explicitly asked to do so. After all, you might be writing
+ a document
+ <footnote>
+ <para>… or maybe even a section of a book …</para>
+ </footnote>
+ about how to use keywords, and you don't want Subversion to
+ substitute your beautiful examples of un-substituted keyword
+ anchors!</para>
+
+ <para>To tell Subversion whether or not to substitute keywords
+ on a particular file, we again turn to the property-related
+ subcommands. The <literal>svn:keywords</literal> property,
+ when set on a versioned file, controls which keywords will
+ be substituted on that file. The value is a space-delimited
+ list of the keyword names or aliases found in the previous
+ table.</para>
+
+ <para>For example, say you have a versioned file named
+ <filename>weather.txt</filename> that looks like
+ this:</para>
+
+ <programlisting>
+Here is the latest report from the front lines.
+$LastChangedDate$
+$Rev$
+Cumulus clouds are appearing more frequently as summer approaches.
+</programlisting>
+
+ <para>With no <literal>svn:keywords</literal> property set on
+ that file, Subversion will do nothing special. Now, let's
+ enable substitution of the
+ <literal>LastChangedDate</literal> keyword.</para>
+
+ <screen>
+$ svn propset svn:keywords "Date Author" weather.txt
+property 'svn:keywords' set on 'weather.txt'
+$
+</screen>
+
+ <para>Now you have made a local property modification on the
+ <filename>weather.txt</filename> file. You will see no
+ changes to the file's contents (unless you made some of your
+ own prior to setting the property). Notice that the file
+ contained a keyword anchor for the <literal>Rev</literal>
+ keyword, yet we did not include that keyword in the property
+ value we set. Subversion will happily ignore requests to
+ substitute keywords that are not present in the file, and
+ will not substitute keywords that are not present in the
+ <literal>svn:keywords</literal> property value.</para>
+
+ <para>Immediately after you commit this property change,
+ Subversion will update your working file with the new
+ substitute text. Instead of seeing your keyword anchor
+ <literal>$LastChangedDate$</literal>, you'll see its
+ substituted result. That result also contains the name of
+ the keyword, and continues to be bounded by the dollar sign
+ (<literal>$</literal>) characters. And as we predicted, the
+ <literal>Rev</literal> keyword was not substituted because
+ we didn't ask for it to be.</para>
+
+ <para>Note also that we set the <literal>svn:keywords</literal>
+ property to <quote>Date Author</quote> yet the keyword
+ anchor used the alias <literal>$LastChangedDate$</literal>
+ and still expanded correctly.</para>
+
+ <screen>
+Here is the latest report from the front lines.
+$LastChangedDate: 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006) $
+$Rev$
+Cumulus clouds are appearing more frequently as summer approaches.
+</screen>
+
+ <para>If someone else now commits a change to
+ <filename>weather.txt</filename>, your copy of that file
+ will continue to display the same substituted keyword value
+ as before—until you update your working copy. At that
+ time the keywords in your <filename>weather.txt</filename>
+ file will be re-substituted with information that
+ reflects the most recent known commit to that file.</para>
+
+ <sidebar>
+ <title>Where's $GlobalRev$?</title>
+
+ <para>New users are often confused by how the
+ <literal>$Rev$</literal> keyword works. Since the repository
+ has a single, globally increasing revision number, many people
+ assume that it is this number which is reflected by the
+ <literal>$Rev$</literal> keyword's value. But
+ <literal>$Rev$</literal> expands to show the last revision in
+ which the file <emphasis>changed</emphasis>, not the last
+ revision to which it was updated. Understanding this clears
+ the confusion, but frustration often remains—without the
+ support of a Subversion keyword to do so, how can you
+ automatically get the global revision number into your
+ files?</para>
+
+ <para>To do this, you need external processing. Subversion
+ ships with a tool called <command>svnversion</command> which
+ was designed for just this purpose.
+ <command>svnversion</command> crawls your working copy and
+ generates as output the revision(s) it finds. You can use
+ this program, plus some additionally tooling, to embed that
+ revision information into your files. For more information on
+ <command>svnversion</command>, see <xref
+ linkend="svn.ref.svnversion"/>.</para>
</sidebar>
- <para>The global list of ignore patterns tends to be more a
- matter of personal taste, and tied more closely to a user's
- particular tool chain than to the details of any particular
- working copy's needs. So, the rest of this section will focus
- on the <literal>svn:ignore</literal> property and its
- uses.</para>
+ <para>Subversion 1.2 introduced a new variant of the keyword
+ syntax which brought additional, useful—though perhaps
+ atypical—functionality. You can now tell Subversion
+ to maintain a fixed length (in terms of the number of bytes
+ consumed) for the substituted keyword. By using a
+ double-colon (<literal>::</literal>) after the keyword name,
+ followed by a number of space characters, you define that
+ fixed width. When Subversion goes to substitute your
+ keyword for the keyword and its value, it will essentially
+ replace only those space characters, leaving the overall
+ width of the keyword field unchanged. If the substituted
+ value is shorter than the defined field width, there will be
+ extra padding characters (spaces) at the end of the
+ substituted field; if it is too long, it is truncated with a
+ special hash (<literal>#</literal>) character just before
+ the final dollar sign terminator.</para>
- <para>Say you have the following output from <command>svn
- status</command>:</para>
+ <para>For example, say you have a document in which you have
+ some section of tabular data reflecting the document's
+ Subversion keywords. Using the original Subversion keyword
+ substitution syntax, your file might look something
+ like:</para>
<screen>
-$ svn status calc
- M calc/button.c
-? calc/calculator
-? calc/data.c
-? calc/debug_log
-? calc/debug_log.1
-? calc/debug_log.2.gz
-? calc/debug_log.3.gz
+$Rev$: Revision of last commit
+$Author$: Author of last commit
+$Date$: Date of last commit
</screen>
- <para>In this example, you have made some property modifications
- to <filename>button.c</filename>, but in your working copy you
- also have some unversioned files: the latest
- <filename>calculator</filename> program that you've compiled
- from your source code, a source file named
- <filename>data.c</filename>, and a set of debugging output log
- files. Now, you know that your build system always results in
- the <filename>calculator</filename> program being generated.
- <footnote>
- <para>Isn't that the whole point of a build system?</para>
- </footnote>
- And you know that your test suite always leaves those debugging
- log files lying around. These facts are true for all working
- copies of this project, not just your own. And you know that
- you aren't interested in seeing those things every time you run
- <command>svn status</command>, and pretty sure that nobody else
- is interested in them either. So you use <command>svn propedit
- svn:ignore calc</command> to add some ignore patterns to the
- <filename>calc</filename> directory. For example, you might add
- this as the new value of the <literal>svn:ignore</literal>
- property:</para>
+ <para>Now, that looks nice and tabular at the start of things.
+ But when you then commit that file (with keyword substitution
+ enabled, of course), you see:</para>
- <programlisting>
-calculator
-debug_log*
-</programlisting>
+ <screen>
+$Rev: 12 $: Revision of last commit
+$Author: harry $: Author of last commit
+$Date: 2006-03-15 02:33:03 -0500 (Wed, 15 Mar 2006) $: Date of last commit
+</screen>
- <para>After you've added this property, you will now have a local
- property modification on the <filename>calc</filename>
- directory. But notice what else is different about your
- <command>svn status</command> output:</para>
+ <para>The result is not so beautiful. And you might be
+ tempted to then adjust the file after the substitution so
+ that it again looks tabular. But that only holds as long as
+ the keyword values are the same width. If the last
+ committed revision rolls into a new place value (say, from
+ 99 to 100), or if another person with a longer username
+ commits the file, stuff gets all crooked again. However, if
+ you are using Subversion 1.2 or better, you can use the new
+ fixed-length keyword syntax, define some field widths that
+ seem sane, and now your file might look like this:</para>
<screen>
-$ svn status
- M calc
- M calc/button.c
-? calc/data.c
+$Rev:: $: Revision of last commit
+$Author:: $: Author of last commit
+$Date:: $: Date of last commit
</screen>
- <para>Now, all that cruft is missing from the output! Of course,
- your <filename>calculator</filename> compiled program and all
- those logfiles are still in your working copy. Subversion is
- simply not reminding you that they are present and unversioned.
- And now with all the uninteresting noise removed from the
- display, you are left with more interesting items—such as
- that source code file <filename>data.c</filename> that you
- probably forgot to add to version control.</para>
-
- <para>Of course, this less-verbose report of your working copy
- status isn't the only one available. If you actually want to
- see the ignored files as part of the status report, you can pass
- the <option>--no-ignore</option> option to Subversion:</para>
+ <para>You commit this change to your file. This time,
+ Subversion notices the new fixed-length keyword syntax, and
+ maintains the width of the fields as defined by the padding
+ you placed between the double-colon and the trailing dollar
+ sign. After substitution, the width of the fields is
+ completely unchanged—the short values for
+ <literal>Rev</literal> and <literal>Author</literal> are
+ padded with spaces, and the long <literal>Date</literal>
+ field is truncated by a hash character:</para>
<screen>
-$ svn status --no-ignore
- M calc/button.c
-I calc/calculator
-? calc/data.c
-I calc/debug_log
-I calc/debug_log.1
-I calc/debug_log.2.gz
-I calc/debug_log.3.gz
+$Rev:: 13 $: Revision of last commit
+$Author:: harry $: Author of last commit
+$Date:: 2006-03-15 0#$: Date of last commit
</screen>
-
- <para>As mentioned earlier, the list of file patterns to ignore is
- also used by <command>svn add</command> and <command>svn
- import</command>. Both of these operations involve asking
- Subversion to begin managing some set of files and directories.
- Rather than force the user to pick and choose which files in a
- tree she wishes to start versioning, Subversion uses the ignore
- patterns—both the global and the per-directory
- lists—to determine which files should not be swept into
- the version control system as part of a larger recursive
- addition or import operation. And here again, you can use the
- <option>--no-ignore</option> option to tell Subversion ignore
- its ignores list and operate on all the files and directories
- present.</para>
+
+ <para>The use of fixed-length keywords is especially handy
+ when performing substitutions into complex file formats that
+ themselves use fixed-length fields for data, or for which
+ the stored size of a given data field is overbearingly
+ difficult to modify from outside the format's native
+ application (such as for Microsoft Office documents).</para>
+
+ <warning>
+ <para>Be aware that because the width of a keyword field is
+ measured in bytes, the potential for corruption of
+ multi-byte values exists. For example, a username which
+ contains some multi-byte UTF-8 characters might suffer
+ truncation in the middle of the string of bytes which make
+ up one of those characters. The result will be a mere
+ truncation when viewed at the byte level, but will likely
+ appear as a string with an incorrect or garbled final
+ character when viewed as UTF-8 text. It is conceivable
+ that certain applications, when asked to load the file,
+ would notice the broken UTF-8 text and deem the entire
+ file corrupt, refusing to operate on the file
+ altogether.</para>
+ </warning>
</sect1>
<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
- <sect1 id="svn.advanced.props.special.keywords">
- <title>Keyword Substitution</title>
+ <sect1 id="svn.advanced.locking">
+ <title>Locking</title>
+
+ <para>Subversion's copy-modify-merge version control model lives
+ and dies on its data merging algorithms, specifically on how
+ well those algorithms perform when trying to resolve conflicts
+ caused by multiple users modifying the same file concurrently.
+ Subversion itself provides only one such algorithm, a three-way
+ differencing algorithm which is smart enough to handle data at a
+ granularity of a single line of text. Subversion also allows
+ you to supplement its content merge processing with external
+ differencing utilities (as described in <xref
+ linkend="svn.advanced.externaldifftools.diff3" />), some of
+ which may do an even better job, perhaps providing granularity
+ of a word or a single character of text. But common among those
+ algorithms is that they generally work only on text files. The
+ landscape starts to look pretty grim when you start talking
+ about content merges of non-textual file formats. And when you
+ can't find a tool that can handle that type of merging, you
+ begin to run into problems with the copy-modify-merge
+ model.</para>
+
+ <para>Let's look at a real-life example of where this model runs
+ aground. Harry and Sally are both graphic designers working on
+ the same project, a bit of marketing collateral for an
+ automobile mechanic. Central to the design of a particular
+ poster is an image of a car in need of some body work, stored in
+ a file using the PNG image format. The poster's layout is
+ almost finished, and both Harry and Sally are pleased with the
+ particular photo they chose for their damaged car—a baby
+ blue 1967 Ford Mustang with an unfortunate bit of crumpling on
+ the left front fender.</para>
+
+ <para>Now, as is common in graphic design work, there's a change
+ in plans which causes the car's color to be a concern. So Sally
+ updates her working copy to <literal>HEAD</literal>, fires up
+ her photo editing software, and sets about tweaking the image so
+ that the car is now cherry red. Meanwhile, Harry, feeling
+ particularly inspired that day, decides that the image would
+ have greater impact if the car also appears to have suffered
+ greater impact. He, too, updates to <literal>HEAD</literal>,
+ and then draws some cracks on the vehicle's windshield. He
+ manages to finish his work before Sally finishes hers, and after
+ admiring the fruits of his undeniable talent, commits the
+ modified image. Shortly thereafter, Sally is finished with the
+ car's new finish, and tries to commit her changes. But, as
+ expected, Subversion fails the commit, informing Sally that now
+ her version of the image is out of date.</para>
+
+ <para>Here's where the difficulty sets in. Were Harry and Sally
+ making changes to a text file, Sally would simply update her
+ working copy, receiving Harry's changes in the process. In the
+ worst possible case, they would have modified the same region of
+ the file, and Sally would have to work out by hand the proper
+ resolution to the conflict. But these aren't text
+ files—they are binary images. And while it's a simple
+ matter to describe what one would expect the results of this
+ content merge to be, there is precious little chance that any
+ software exists which is smart enough to examine the common
+ baseline image that each of these graphic artists worked
+ against, the changes that Harry made, and the changes that Sally
+ made, and spit out an image of a busted-up red Mustang with a
+ cracked windshield!</para>
- <para>Subversion has the ability to substitute
- <firstterm>keywords</firstterm>—pieces of useful,
- dynamic information about a versioned file—into the
- contents of the file itself. Keywords generally describe
- information about the last time the file was known to be
- modified. Because this information changes each time the
- file changes, and more importantly, just
- <emphasis>after</emphasis> the file changes, it is a hassle
- for any process except the version control system to keep
- the data completely up-to-date. Left to human authors, the
- information would inevitably grow stale.</para>
+ <para>Clearly, things would have gone more smoothly if Harry and
+ Sally had serialized their modifications to the image. If, say,
+ Harry had waited to draw his windshield cracks on Sally's
+ now-red car, or if Sally had tweaked the color of a car whose
+ windshield was already cracked. As is discussed in <xref
+ linkend="svn.basic.vsn-models.copy-merge" />, much of these
+ types problems go away entirely where perfect communication
+ between Harry and Sally exists.
+ <footnote>
+ <para>Communication wouldn't have been such bad medicine for
+ Harry and Sally's Hollywood namesakes, either, for that
+ matter.</para>
+ </footnote>
+ But as one's version control system is, in fact, one form of
+ communication, it follows that having that software facilitate
+ the serialization of non-parallelizable energies is no bad
+ thing. And this where Subversion's implementation of the
+ lock-modify-unlock model steps into the spotlight. This is
+ where we talk about Subversion's <firstterm>locking</firstterm>
+ feature, which is similar to the <quote>reserved
+ checkouts</quote> mechanisms of other version control
+ systems.</para>
- <para>For example, say you have a document in which you would
- like to display the last date on which it was modified. You
- could burden every author of that document to, just before
- committing their changes, also tweak the part of the
- document that describes when it was last changed. But
- sooner or later, someone would forget to do that. Instead
- simply ask Subversion to perform keyword substitution on the
- <literal>LastChangedDate</literal> keyword. You control
- where the keyword is inserted into your document by placing
- a <firstterm>keyword anchor</firstterm> at the desired
- location in the file. This anchor is just a string of text
- formatted as
- <literal>$</literal><replaceable>KeywordName</replaceable><literal>$</literal>.</para>
+ <para>Subversion's locking feature serves two main
+ purposes:</para>
- <para>All keywords are case-sensitive where they appear as
- anchors in files: you must use the correct capitalization in
- order for the keyword to be expanded. You should consider the
- value of the <literal>svn:keywords</literal> property to be
- case-sensitive too—certain keyword names will be recognized
- regardless of case, but this behavior is deprecated.</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Serializing access to a versioned
+ object</emphasis>. By allowing a user to
+ programmatically claim the exclusive right to change to a
+ file in the repository, that user can be reasonably
+ confident that energy invested on unmergeable changes won't
+ be wasted—his commit of those changes will succeed.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Aiding communication</emphasis>. By alerting
+ other users that serialization is in effect for particular
+ versioned object, those other users can reasonably expect
+ that the object is about to be changed by someone else,
+ and they, too, can avoid wasting their time and energy on
+ unmergeable changes that won't be committable due to eventual
+ out-of-dateness.</para>
+ </listitem>
+ </itemizedlist>
- <para>Subversion defines the list of keywords available for
- substitution. That list contains the following five keywords,
- some of which have aliases that you can also use:</para>
+ <para>When referring to Subversion's locking feature, one is
+ actually talking about a fairly diverse collection of behaviors
+ which include the ability to lock a versioned file
+ <footnote>
+ <para>Subversion does not currently allow locks on directories.</para>
+ </footnote>
+ (claiming the exclusive right to modify the file), to unlock
+ that file (yielding that exclusive right to modify), to see
+ reports about which files are locked and by whom, to annotate
+ files for which locking before editing is strongly advised, and
+ so on. In this section, we'll cover all of these facets of the
+ larger locking feature.</para>
- <variablelist>
- <varlistentry>
- <term><literal>Date</literal></term>
- <listitem>
- <para>This keyword describes the last time the file was
- known to have been changed in the repository, and
- looks something like <literal>$Date:
- 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002)
- $</literal>. It may also be specified as
- <literal>LastChangedDate</literal>.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>Revision</literal></term>
- <listitem>
- <para>This keyword describes the last known revision in
- which this file changed in the repository, and looks
- something like <literal>$Revision: 144 $</literal>.
- It may also be specified as
- <literal>LastChangedRevision</literal> or
- <literal>Rev</literal>.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>Author</literal></term>
- <listitem>
- <para>This keyword describes the last known user to
- change this file in the repository, and looks
- something like <literal>$Author: harry $</literal>.
- It may also be specified as
- <literal>LastChangedBy</literal>.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>HeadURL</literal></term>
- <listitem>
- <para>This keyword describes the full URL to the latest
- version of the file in the repository, and looks
- something like <literal>$HeadURL:
- http://svn.collab.net/repos/trunk/README $</literal>.
- It may be abbreviated as
- <literal>URL</literal>.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>Id</literal></term>
- <listitem>
- <para>This keyword is a compressed combination of the
- other keywords. Its substitution looks something like
- <literal>$Id: calc.c 148 2002-07-28 21:30:43Z sally
- $</literal>, and is interpreted to mean that the file
- <filename>calc.c</filename> was last changed in revision
- 148 on the evening of July 28, 2002 by the user
- <literal>sally</literal>.</para>
- </listitem>
- </varlistentry>
- </variablelist>
+ <sidebar id="svn.advanced.locking.meanings">
+ <title>Three meanings of <quote>lock</quote></title>
- <para>Simply adding keyword anchor text to your file does
- nothing special. Subversion will never attempt to perform
- textual substitutions on your file contents unless
- explicitly asked to do so. After all, you might be writing
- a document
- <footnote>
- <para>… or maybe even a section of a book …</para>
- </footnote>
- about how to use keywords, and you don't want Subversion to
- substitute your beautiful examples of un-substituted keyword
- anchors!</para>
+ <para>In this section, and almost everywhere in this book, the
+ words <quote>lock</quote> and <quote>locking</quote> describe
+ a mechanism for mutual exclusion between users to avoid
+ clashing commits. Unfortunately, there are two other sorts
+ of <quote>lock</quote> with which Subversion, and therefore
+ this book, sometimes needs to be concerned.</para>
- <para>To tell Subversion whether or not to substitute keywords
- on a particular file, we again turn to the property-related
- subcommands. The <literal>svn:keywords</literal> property,
- when set on a versioned file, controls which keywords will
- be substituted on that file. The value is a space-delimited
- list of the keyword names or aliases found in the previous
- table.</para>
+ <para>The first is <firstterm>working copy locks</firstterm>,
+ used internally by Subversion to prevent clashes between
+ multiple Subversion clients operating on the same working
+ copy. This is the sort of lock indicated by an
+ <computeroutput>L</computeroutput> in the third column of
+ <command>svn status</command> output, and removed by the
+ <command>svn cleanup</command> command, as described in <xref
+ linkend="svn.tour.other.cleanup"/>.</para>
- <para>For example, say you have a versioned file named
- <filename>weather.txt</filename> that looks like
- this:</para>
+ <para>Secondly, there are <firstterm>database locks</firstterm>,
+ used internally by the Berkeley DB backend to prevent clashes
+ between multiple programs trying to access the database. This
+ is the sort of lock whose unwanted persistence after an error
+ can cause a repository to be <quote>wedged</quote>, as
+ described in <xref linkend="svn.reposadmin.maint.recovery"/>.</para>
- <programlisting>
-Here is the latest report from the front lines.
-$LastChangedDate$
-$Rev$
-Cumulus clouds are appearing more frequently as summer approaches.
-</programlisting>
+ <para>You can generally forget about these other kinds of locks
+ until something goes wrong that requires you to care about
+ them. In this book, <quote>lock</quote> means the first sort
+ unless the contrary is either clear from context or explicitly
+ stated.</para>
- <para>With no <literal>svn:keywords</literal> property set on
- that file, Subversion will do nothing special. Now, let's
- enable substitution of the
- <literal>LastChangedDate</literal> keyword.</para>
+ </sidebar>
- <screen>
-$ svn propset svn:keywords "Date Author" weather.txt
-property 'svn:keywords' set on 'weather.txt'
-$
-</screen>
-
- <para>Now you have made a local property modification on the
- <filename>weather.txt</filename> file. You will see no
- changes to the file's contents (unless you made some of your
- own prior to setting the property). Notice that the file
- contained a keyword anchor for the <literal>Rev</literal>
- keyword, yet we did not include that keyword in the property
- value we set. Subversion will happily ignore requests to
- substitute keywords that are not present in the file, and
- will not substitute keywords that are not present in the
- <literal>svn:keywords</literal> property value.</para>
+ <!-- =============================================================== -->
+ <sect2 id="svn.advanced.locking.creation">
+ <title>Creating locks</title>
- <para>Immediately after you commit this property change,
- Subversion will update your working file with the new
- substitute text. Instead of seeing your keyword anchor
- <literal>$LastChangedDate$</literal>, you'll see its
- substituted result. That result also contains the name of
- the keyword, and continues to be bounded by the dollar sign
- (<literal>$</literal>) characters. And as we predicted, the
- <literal>Rev</literal> keyword was not substituted because
- we didn't ask for it to be.</para>
+ <para>In the Subversion repository, a
+ <firstterm>lock</firstterm> is a piece of metadata which
+ grants exclusive access to one user to change a file. This
+ user is said to be the <firstterm>lock owner</firstterm>.
+ Each lock also has a unique identifier, typically a long
+ string of characters, known as the <firstterm>lock
+ token</firstterm>. The repository manages locks, ultimately
+ handling their creation, enforcement, and removal. If any
+ commit transaction attempts to modify or delete a locked file
+ (or delete one of the parent directories of the file), the
+ repository will demand two pieces of information—that
+ the client performing the commit be authenticated as the lock
+ owner, and that the lock token has been provided as part of
+ the commit process as a sort of proof that client knows which
+ lock it is using.</para>
- <para>Note also that we set the <literal>svn:keywords</literal>
- property to <quote>Date Author</quote> yet the keyword
- anchor used the alias <literal>$LastChangedDate$</literal>
- and still expanded correctly.</para>
+ <para>To demonstrate lock creation, let's refer back to our
+ example of multiple graphic designers working with on the same
+ binary image files. Harry has decided to change a JPEG image.
+ To prevent other people from committing changes to the file
+ while he is modifying it (as well as alerting them that he is
+ about to change it), he locks the file in the repository using
+ the <command>svn lock</command> command.</para>
- <screen>
-Here is the latest report from the front lines.
-$LastChangedDate: 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002) $
-$Rev$
-Cumulus clouds are appearing more frequently as summer approaches.
+ <screen>
+$ svn lock banana.jpg --message "Editing file for tomorrow's release."
+'banana.jpg' locked by user 'harry'.
+$
</screen>
- <para>If someone else now commits a change to
- <filename>weather.txt</filename>, your copy of that file
- will continue to display the same substituted keyword value
- as before—until you update your working copy. At that
- time the keywords in your <filename>weather.txt</filename>
- file will be re-substituted with information that
- reflects the most recent known commit to that file.</para>
-
- <sidebar>
- <title>Where's $GlobalRev$?</title>
+ <para>There are a number of new things demonstrated in the
+ previous example. First, notice that Harry passed the
+ <option>--message</option> option to <command>svn
+ lock</command>. Similar to <command>svn commit</command>, the
+ <command>svn lock</command> command can take comments (either
+ via <option>--message (-m)</option> or <option>--file
+ (-F)</option>) to describe the reason for locking the file.
+ Unlike <command>svn commit</command>, however, <command>svn
+ lock</command> will not demand a message by launching your
+ preferred text editor. Lock comments are optional, but still
+ recommended to aid communication.</para>
- <para>### TODO: Write me</para>
+ <para>Secondly, the lock attempt succeeded. This means that the
+ file wasn't already locked, and that Harry had the latest
+ version of the file. If Harry's working copy of the file had
+ been out-of-date, the repository would have rejected the
+ request, forcing Harry to <command>svn update</command> and
+ reattempt the locking command. The locking command would also
+ have failed if the file already been locked by someone
+ else.</para>
- </sidebar>
+ <para>As you can see, the <command>svn lock</command> command
+ prints confirmation of the successful lock. At this point,
+ the fact that the file is locked becomes apparent in the
+ output of the <command>svn status</command> and <command>svn
+ info</command> reporting subcommands.</para>
- <para>Subversion 1.2 introduced a new variant of the keyword
- syntax which brought additional, useful—though perhaps
- atypical—functionality. You can now tell Subversion
- to maintain a fixed length (in terms of the number of bytes
- consumed) for the substituted keyword. By using a
- double-colon (<literal>::</literal>) after the keyword name,
- followed by a number of space characters, you define that
- fixed width. When Subversion goes to substitute your
- keyword for the keyword and its value, it will essentially
- replace only those space characters, leaving the overall
- width of the keyword field unchanged. If the substituted
- value is shorter than the defined field width, there will be
- extra padding characters (spaces) at the end of the
- substituted field; if it is too long, it is truncated with a
- special hash (<literal>#</literal>) character just before
- the final dollar sign terminator.</para>
+ <screen>
+$ svn status
+ K banana.jpg
- <para>For example, say you have a document in which you have
- some section of tabular data reflecting the document's
- Subversion keywords. Using the original Subversion keyword
- substitution syntax, your file might look something
- like:</para>
+$ svn info banana.jpg
+Path: banana.jpg
+Name: banana.jpg
+URL: http://svn.example.com/repos/project/banana.jpg
+Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec
+Revision: 2198
+Node Kind: file
+Schedule: normal
+Last Changed Author: frank
+Last Changed Rev: 1950
+Last Changed Date: 2006-03-15 12:43:04 -0600 (Wed, 15 Mar 2006)
+Text Last Updated: 2006-06-08 19:23:07 -0500 (Thu, 08 Jun 2006)
+Properties Last Updated: 2006-06-08 19:23:07 -0500 (Thu, 08 Jun 2006)
+Checksum: 3b110d3b10638f5d1f4fe0f436a5a2a5
+Lock Token: opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e
+Lock Owner: harry
+Lock Created: 2006-06-14 17:20:31 -0500 (Wed, 14 Jun 2006)
+Lock Comment (1 line):
+Editing file for tomorrow's release.
- <screen>
-$Rev$: Revision of last commit
-$Author$: Author of last commit
-$Date$: Date of last commit
+$
</screen>
-
- <para>Now, that looks nice and tabular at the start of things.
- But when you then commit that file (with keyword substitution
- enabled, of course), you see:</para>
- <screen>
-$Rev: 12 $: Revision of last commit
-$Author: harry $: Author of last commit
-$Date: 2006-03-15 02:33:03 -0500 (Wed, 15 Mar 2006) $: Date of last commit
-</screen>
-
- <para>The result is not so beautiful. And you might be
- tempted to then adjust the file after the substitution so
- that it again looks tabular. But that only holds as long as
- the keyword values are the same width. If the last
- committed revision rolls into a new place value (say, from
- 99 to 100), or if another person with a longer username
- commits the file, stuff gets all crooked again. However, if
- you are using Subversion 1.2 or better, you can use the new
- fixed-length keyword syntax, define some field widths that
- seem sane, and now your file might look like this:</para>
+ <para>That the <command>svn info</command> command, which does
+ not contact the repository when run against working copy
+ paths, can display the lock token reveals an important fact
+ about lock tokens—that they are cached in the working
+ copy. The presence of the lock token is critical. It gives
+ the working copy authorization to make use of the lock later
+ on. Also, the <command>svn status</command> command shows a
+ <literal>K</literal> next to the file (short for locKed),
+ indicating that the lock token is present.</para>
- <screen>
-$Rev:: $: Revision of last commit
-$Author:: $: Author of last commit
-$Date:: $: Date of last commit
-</screen>
-
- <para>You commit this change to your file. This time,
- Subversion notices the new fixed-length keyword syntax, and
- maintains the width of the fields as defined by the padding
- you placed between the double-colon and the trailing dollar
- sign. After substitution, the width of the fields is
- completely unchanged—the short values for
- <literal>Rev</literal> and <literal>Author</literal> are
- padded with spaces, and the long <literal>Date</literal>
- field is truncated by a hash character:</para>
+ <sidebar>
+ <title>Regarding lock tokens</title>
- <screen>
-$Rev:: 13 $: Revision of last commit
-$Author:: harry $: Author of last commit
-$Date:: 2006-03-15 0#$: Date of last commit
+ <para>A lock token isn't an authentication token, so much as
+ an <emphasis>authorization</emphasis> token. The token
+ isn't a protected secret. In fact, a lock's unique token is
+ discoverable by anyone who runs <command>svn info
+ URL</command>. A lock token is special only when it lives
+ inside a working copy. It's proof that the lock was created
+ in that particular working copy, and not somewhere else by
+ some other client. Merely authenticating as the lock owner
+ isn't enough to prevent accidents.</para>
+
+ <para>For example, suppose you lock a file using a computer at
+ your office, but leave work for the day before you finish
+ your changes to that file. It should not be possible to
+ accidentally commit changes to that same file from your home
+ computer later that evening simply because you've
+ authenticated as the lock's owner. In other words, the lock
+ token prevents one piece of Subversion-related software from
+ undermining the work of another. (In our example, if you
+ really need to change the file from an alternate working
+ copy, you would need to break the lock and re-lock the
+ file.)</para>
+
+ </sidebar>
+
+ <para>Now that Harry has locked <filename>banana.jpg</filename>,
+ Sally is unable to change or delete that file:</para>
+
+ <screen>
+$ svn delete banana.jpg
+D banana.jpg
+$ svn commit -m "Delete useless file."
+Deleting banana.jpg
+svn: Commit failed (details follow):
+svn: DELETE of
+'/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banana.jpg':
+423 Locked (http://svn.example.com)
+$
</screen>
-
- <para>The use of fixed-length keywords is especially handy
- when performing substitutions into complex file formats that
- themselves use fixed-length fields for data, or for which
- the stored size of a given data field is overbearingly
- difficult to modify from outside the format's native
- application (such as for Microsoft Office documents).</para>
- <warning>
- <para>Be aware that because the width of a keyword field is
- measured in bytes, the potential for corruption of
- multi-byte values exists. For example, a username which
- contains some multi-byte UTF-8 characters might suffer
- truncation in the middle of the string of bytes which make
- up one of those characters. The result will be a mere
- truncation when viewed at the byte level, but will likely
- appear as a string with an incorrect or garbled final
- character when viewed as UTF-8 text. It is conceivable
- that certain applications, when asked to load the file,
- would notice the broken UTF-8 text and deem the entire
- file corrupt, refusing to operate on the file
- altogether.</para>
- </warning>
+ <para>But Harry, after touching up the banana's shade of yellow,
+ is able to commit his changes to the file. That's because he
+ authenticates as the lock owner, and also because his working
+ copy holds the correct lock token:</para>
- </sect1>
+ <screen>
+$ svn status
+M K banana.jpg
+$ svn commit -m "Make banana more yellow"
+Sending banana.jpg
+Transmitting file data .
+Committed revision 2201.
+$ svn status
+$
+</screen>
- <!-- ================================================================= -->
- <!-- ================================================================= -->
- <!-- ================================================================= -->
- <sect1 id="svn.advanced.locking">
- <title>Locking</title>
+ <para>Notice that after the commit is finished, <command>svn
+ status</command> shows that the lock token is no longer
+ present in working copy. This is the standard behavior of
+ <command>svn commit</command>—it searches the working
+ copy (or list of targets, if you provide such a list) for
+ local modifications, and sends all the lock tokens it
+ encounters during this walk to the server as part of the
+ commit transaction. After the commit completes successfully,
+ all of the repository locks that were mentioned are
+ released—<emphasis>even on files that weren't
+ committed</emphasis>. This is meant to discourage users from
+ being sloppy about locking, or from holding locks for too
+ long. If Harry haphazardly locks thirty files in a directory
+ named <filename>images</filename> because he's unsure of which
+ files he needs to change, yet only only changes four of those
+ file, when he runs <command>svn commit images</command>, the
+ process will still release all thirty locks.</para>
- <para>Subversion's copy-modify-merge version control model lives
- and dies on its data merging algorithms, specifically on how
- well those algorithms perform when trying to resolve conflicts
- caused by multiple users modifying the same file concurrently.
- Subversion itself provides only one such algorithm, a three-way
- differencing algorithm which is smart enough to handle data at a
- granularity of a single line of text. Subversion also allows
- you to supplement its content merge processing with external
- differencing utilities (as described in <xref
- linkend="svn.advanced.externaldifftools.diff3" />), some of
- which may do an even better job, perhaps providing granularity
- of a word or a single character of text. But common among those
- algorithms is that they generally work only on text files. The
- landscape starts to look pretty grim when you start talking
- about content merges of non-textual file formats. And when you
- can't find a tool that can handle that type of merging, you
- begin to run into problems with the copy-modify-merge
- model.</para>
+ <para>This behavior of automatically releasing locks can be
+ overridden with the <option>--no-unlock</option> option to
+ <command>svn commit</command>. This is best used for those
+ times when you want to commit changes, but still plan to make
+ more changes and thus need to retain existing locks. You can
+ also make this your default behavior by setting the
+ <literal>no-unlock</literal> runtime configuration option (see
+ <xref linkend="svn.advanced.confarea" />).</para>
- <para>Let's look at a real-life example of where this model runs
- aground. Harry and Sally are both graphic designers working on
- the same project, a bit of marketing collateral for an
- automobile mechanic. Central to the design of a particular
- poster is an image of a car in need of some body work, stored in
- a file using the PNG image format. The poster's layout is
- almost finished, and both Harry and Sally are pleased with the
- particular photo they chose for their damaged car—a baby
- blue 1967 Ford Mustang with an unfortunate bit of crumpling on
- the left front fender.</para>
+ <para>Of course, locking a file doesn't oblige one to commit a
+ change to it. The lock can be released at any time with a
+ simple <command>svn unlock</command> command:</para>
- <para>Now, as is common in graphic design work, there's a change
- in plans which causes the car's color to be a concern. So Sally
- updates her working copy to <literal>HEAD</literal>, fires up
- her photo editing software, and sets about tweaking the image so
- that the car is now cherry red. Meanwhile, Harry, feeling
- particularly inspired that day, decides that the image would
- have greater impact if the car also appears to have suffered
- greater impact. He, too, updates to <literal>HEAD</literal>,
- and then draws some cracks on the vehicle's windshield. He
- manages to finish his work before Sally finishes hers, and after
- admiring the fruits of his undeniable talent, commits the
- modified image. Shortly thereafter, Sally is finished with the
- car's new finish, and tries to commit her changes. But, as
- expected, Subversion fails the commit, informing Sally that now
- her version of the image is out of date.</para>
+ <screen>
+$ svn unlock banana.c
+'banana.c' unlocked.
+</screen>
- <para>Here's where the difficulty sets in. Were Harry and Sally
- making changes to a text file, Sally would simply update her
- working copy, receiving Harry's changes in the process. In the
- worst possible case, they would have modified the same region of
- the file, and Sally would have to work out by hand the proper
- resolution to the conflict. But these aren't text
- files—they are binary images. And while it's a simple
- matter to describe what one would expect the results of this
- content merge to be, there is precious little chance that any
- software exists which is smart enough to examine the common
- baseline image that each of these graphic artists worked
- against, the changes that Harry made, and the changes that Sally
- made, and spit out an image of a busted-up red Mustang with a
- cracked windshield!</para>
+ </sect2>
- <para>Clearly, things would have gone more smoothly if Harry and
- Sally had serialized their modifications to the image. If, say,
- Harry had waited to draw his windshield cracks on Sally's
- now-red car, or if Sally had tweaked the color of a car whose
- windshield was already cracked. As is discussed in <xref
- linkend="svn.basic.vsn-models.copy-merge" />, much of these
- types problems go away entirely where perfect communication
- between Harry and Sally exists.
- <footnote>
- <para>Communication wouldn't have been such bad medicine for
- Harry and Sally's Hollywood namesakes, either, for that
- matter.</para>
- </footnote>
- But as one's version control system is, in fact, one form of
- communication, it follows that having that software facilitate
- the serialization of non-parallelizable energies is no bad
- thing. And this where Subversion's implementation of the
- lock-modify-unlock model steps into the spotlight. This is
- where we talk about Subversion's <firstterm>locking</firstterm>
- feature, which is similar to the <quote>reserved
- checkouts</quote> mechanisms of other version control
- systems.</para>
+ <!-- =============================================================== -->
+ <sect2 id="svn.advanced.locking.discovery">
+ <title>Discovering locks</title>
- <para>Subversion's locking feature serves two main
- purposes:</para>
+ <para>When a commit fails due to someone else's locks, it's
+ fairly easy to learn about them. The easiest of
+ these is <command>svn status --show-updates</command>:</para>
- <itemizedlist>
- <listitem>
- <para><emphasis>Serializing access to a versioned
- object</emphasis>. By allowing a user to
- programmatically claim the exclusive right to change to a
- file in the repository, that user can be reasonably
- confident that energy invested on unmergeable changes won't
- be wasted—his commit of those changes will succeed.</para>
- </listitem>
- <listitem>
- <para><emphasis>Aiding communication</emphasis>. By alerting
- other users that serialization is in effect for particular
- versioned object, those other users can reasonably expect
- that the object is about to be changed by someone else,
- and they, too, can avoid wasting their time and energy on
- unmergeable changes that won't be committable due to eventual
- out-of-dateness.</para>
- </listitem>
- </itemizedlist>
+ <screen>
+$ svn status --show-updates
+M 23 bar.c
+M O 32 raisin.jpg
+ * 72 foo.h
+Status against revision: 105
+$
+</screen>
- <para>When referring to Subversion's locking feature, one is
- actually talking about a fairly diverse collection of behaviors
- which include the ability to lock a versioned file
- <footnote>
- <para>Subversion does not currently allow locks on directories.</para>
- </footnote>
- (claiming the exclusive right to modify the file), to unlock
- that file (yielding that exclusive right to modify), to see
- reports about which files are locked and by whom, to annotate
- files for which locking before editing is strongly advised, and
- so on. In this section, we'll cover all of these facets of the
- larger locking feature.</para>
+ <para>In this example, Sally can see not only that her copy of
+ <filename>foo.h</filename> is out-of-date, but that one of the
+ two modified files she plans to commit is locked in the
+ repository. The <literal>O</literal> symbol stands for
+ <quote>Other</quote>, meaning that a lock exists on the file,
+ and was created by somebody else. If she were to attempt a
+ commit, the lock on <filename>raisin.jpg</filename> would
+ prevent it. Sally is left wondering who made the lock, when,
+ and why. Once again, <command>svn info</command> has the
+ answers:</para>
- <sidebar id="svn.advanced.locking.meanings">
- <title>Three meanings of <quote>lock</quote></title>
+ <screen>
+$ svn info http://svn.example.com/repos/project/raisin.jpg
+Path: raisin.jpg
+Name: raisin.jpg
+URL: http://svn.example.com/repos/project/raisin.jpg
+Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec
+Revision: 105
+Node Kind: file
+Last Changed Author: sally
+Last Changed Rev: 32
+Last Changed Date: 2006-01-25 12:43:04 -0600 (Sun, 25 Jan 2006)
+Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
+Lock Owner: harry
+Lock Created: 2006-02-16 13:29:18 -0500 (Thu, 16 Feb 2006)
+Lock Comment (1 line):
+Need to make a quick tweak to this image.
+$
+</screen>
+ <para>Just as <command>svn info</command> can be used to examine
+ objects in the working copy, it can also be used to examine
+ objects in the repository. If the main argument to
+ <command>svn info</command> is a working copy path, then all
+ of the working copy's cached information is displayed; any
+ mention of a lock means that the working copy is holding a
+ lock token (if a file is locked by another user or in another
+ working copy, <command>svn info</command> on a working copy
+ path will show no lock information at all). If the main
+ argument to <command>svn info</command> is a URL, then the
+ information reflects the latest version of an object in the
+ repository, and any mention of a lock describes the current
+ lock on the object.</para>
- <para>In this section, and almost everywhere in this book, the
- words <quote>lock</quote> and <quote>locking</quote> describe
- a mechanism for mutual exclusion between users to avoid
- clashing commits. Unfortunately, there are two other sorts
- of <quote>lock</quote> with which Subversion, and therefore
- this book, sometimes needs to be concerned.</para>
+ <para>So in this particular example, Sally can see that Harry
+ locked the file on February 16th to <quote>make a quick
+ tweak</quote>. It being June, she suspects that he probably
+ forgot all about the lock. She might phone Harry to complain
+ and ask him to release the lock. If he's unavailable, she
+ might try to forcibly break the lock herself or ask an
+ administrator to do so.</para>
- <para>The first is <firstterm>working copy locks</firstterm>,
- used internally by Subversion to prevent clashes between
- multiple Subversion clients operating on the same working
- copy. This is the sort of lock indicated by an
- <computeroutput>L</computeroutput> in the third column of
- <command>svn status</command> output, and removed by the
- <command>svn cleanup</command> command, as described in <xref
- linkend="svn.tour.other.cleanup"/>.</para>
+ </sect2>
- <para>Secondly, there are <firstterm>database locks</firstterm>,
- used internally by the Berkeley DB backend to prevent clashes
- between multiple programs trying to access the database. This
- is the sort of lock whose unwanted persistence after an error
- can cause a repository to be <quote>wedged</quote>, as
- described in <xref linkend="svn.reposadmin.maint.recovery"/>.</para>
+ <!-- =============================================================== -->
+ <sect2 id="svn.advanced.locking.break-steal">
+ <title>Breaking and stealing locks</title>
- <para>You can generally forget about these other sorts of lock,
- until something goes wrong that requires you to care about
- them. In this book, <quote>lock</quote> means the first sort
- unless the contrary is either clear from context or explicitly
- stated.</para>
+ <para>A repository lock isn't sacred—in Subversion's
+ default configuration state, locks can be released not only by
+ the person who created them, but by anyone at all. When
+ somebody other than the original lock creator destroys a lock,
+ we refer to this as <firstterm>breaking</firstterm> the
+ lock.</para>
- </sidebar>
+ <para>From the administrator's chair, it's simple to break
+ locks. The <command>svnlook</command>
+ and <command>svnadmin</command> programs have the ability to
+ display and remove locks directly from the repository. (For
+ more information about these tools, see
+ <xref linkend="svn.reposadmin.maint.tk"/>.)</para>
- <!-- =============================================================== -->
- <sect2 id="svn.advanced.locking.creation">
- <title>Creating locks</title>
+ <screen>
+$ svnadmin lslocks /usr/local/svn/repos
+Path: /project2/images/banana.jpg
+UUID Token: opaquelocktoken:c32b4d88-e8fb-2310-abb3-153ff1236923
+Owner: frank
+Created: 2006-06-15 13:29:18 -0500 (Thu, 15 Jun 2006)
+Expires:
+Comment (1 line):
+Still improving the yellow color.
- <para>In the Subversion repository, a
- <firstterm>lock</firstterm> is a piece of metadata which
- grants exclusive access to one user to change a file. This
- user is said to be the <firstterm>lock owner</firstterm>.
- Each lock also has a unique identifier, typically a long
- string of characters, known as the <firstterm>lock
- token</firstterm>. The repository manages locks, ultimately
- handling their creation, enforcement, and removal. If any
- commit transaction attempts to modify or delete a locked file
- (or delete one of the parent directories of the file), the
- repository will demand two pieces of information—that
- the client performing the commit be authenticated as the lock
- owner, and that the lock token has been provided as part of
- the commit process as a sort of proof that client knows which
- lock it is using.</para>
+Path: /project/raisin.jpg
+UUID Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
+Owner: harry
+Created: 2006-02-16 13:29:18 -0500 (Thu, 16 Feb 2006)
+Expires:
+Comment (1 line):
+Need to make a quick tweak to this image.
- <para>To demonstrate lock creation, let's refer back to our
- example of multiple graphic designers working with on the same
- binary image files. Harry has decided to change a JPEG image.
- To prevent other people from committing changes to the file
- while he is modifying it (as well as alerting them that he is
- about to change it), he locks the file in the repository using
- the <command>svn lock</command> command.</para>
+$ svnadmin rmlocks /usr/local/svn/repos /project/raisin.jpg
+Removed lock on '/project/raisin.jpg'.
+$
+</screen>
+
+ <para>The more interesting option is allowing users to break
+ each other's locks over the network. To do this, Sally simply
+ needs to pass the <option>--force</option> to the unlock
+ command:</para>
<screen>
-$ svn lock banana.jpg --message "Editing file for tomorrow's release."
-'banana.jpg' locked by user 'harry'.
+$ svn status --show-updates
+M 23 bar.c
+M O 32 raisin.jpg
+ * 72 foo.h
+Status against revision: 105
+$ svn unlock raisin.jpg
+svn: 'raisin.jpg' is not locked in this working copy
+$ svn info raisin.jpg | grep URL
+URL: http://svn.example.com/repos/project/raisin.jpg
+$ svn unlock http://svn.example.com/repos/project/raisin.jpg
+svn: Unlock request failed: 403 Forbidden (http://svn.example.com)
+$ svn unlock --force http://svn.example.com/repos/project/raisin.jpg
+'raisin.jpg' unlocked.
$
</screen>
- <para>There are a number of new things demonstrated in the
- previous example. First, notice that Harry passed the
- <option>--message</option> option to <command>svn
- lock</command>. Similar to <command>svn commit</command>, the
- <command>svn lock</command> command can take comments (either
- via <option>--message (-m)</option> or <option>--file
- (-F)</option>) to describe the reason for locking the file.
- Unlike <command>svn commit</command>, however, <command>svn
- lock</command> will not demand a message by launching your
- preferred text editor. Lock comments are optional, but still
- recommended to aid communication.</para>
-
- <para>Secondly, the lock attempt succeeded. This means that the
- file wasn't already locked, and that Harry had the latest
- version of the file. If Harry's working copy of the file had
- been out-of-date, the repository would have rejected the
- request, forcing Harry to <command>svn update</command> and
- reattempt the locking command. The locking command would also
- have failed if the file already been locked by someone
- else.</para>
+ <para>Now, Sally's initial attempt to unlock failed because she
+ ran <command>svn unlock</command> directly on her working copy
+ of the file, and no lock token was present. To remove the
+ lock directly from the repository, she needs to pass a URL
+ to <command>svn unlock</command>. Her first attempt to unlock
+ the URL fails, because she can't authenticate as the lock
+ owner (nor does she have the lock token). But when she
+ passes <option>--force</option>, the authentication and
+ authorization requirements are ignored, and the remote lock is
+ broken.</para>
- <para>As you can see, the <command>svn lock</command> command
- prints confirmation of the successful lock. At this point,
- the fact that the file is locked becomes apparent in the
- output of the <command>svn status</command> and <command>svn
- info</command> reporting subcommands.</para>
+ <para>Of course, simply breaking a lock may not be enough. In
+ the running example, Sally may not only want to break Harry's
+ long-forgotten lock, but re-lock the file for her own use.
+ She can accomplish this by running <command>svn unlock
+ --force</command> and then <command>svn lock</command>
+ back-to-back, but there's a small chance that somebody else
+ might lock the file between the two commands. The simpler thing
+ to is <firstterm>steal</firstterm> the lock, which involves
+ breaking and re-locking the file all in one atomic step. To
+ do this, Sally passes the <option>--force</option> option
+ to <command>svn lock</command>:</para>
<screen>
-$ svn status
- K banana.jpg
+$ svn lock raisin.jpg
+svn: Lock request failed: 423 Locked (http://svn.example.com)
+$ svn lock --force raisin.jpg
+'raisin.jpg' locked by user 'sally'.
+$
+</screen>
-$ svn info banana.jpg
-Path: banana.jpg
-Name: banana.jpg
-URL: http://svn.example.com/repos/project/banana.jpg
-Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec
-Revision: 2198
-Node Kind: file
-Schedule: normal
-Last Changed Author: frank
-Last Changed Rev: 1950
-Last Changed Date: 2005-03-15 12:43:04 -0600 (Tue, 15 Mar 2005)
-Text Last Updated: 2005-06-08 19:23:07 -0500 (Wed, 08 Jun 2005)
-Properties Last Updated: 2005-06-08 19:23:07 -0500 (Wed, 08 Jun 2005)
-Checksum: 3b110d3b10638f5d1f4fe0f436a5a2a5
-Lock Token: opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e
-Lock Owner: harry
-Lock Created: 2005-06-14 17:20:31 -0500 (Tue, 14 Jun 2005)
-Lock Comment (1 line):
-Editing file for tomorrow's release.
+ <para>In any case, whether the lock is broken or stolen, Harry
+ may be in for a surprise. Harry's working copy still contains
+ the original lock token, but that lock no longer exists. The
+ lock token is said to be <firstterm>defunct</firstterm>. The
+ lock represented by the lock-token has either been broken (no
+ longer in the repository), or stolen (replaced with a
+ different lock). Either way, Harry can see this by asking
+ <command>svn status</command> to contact the
+ repository:</para>
+ <screen>
+$ svn status
+ K raisin.jpg
+$ svn status --show-updates
+ B 32 raisin.jpg
+$ svn update
+ B raisin.jpg
+$ svn status
$
</screen>
- <para>That the <command>svn info</command> command, which does
- not contact the repository when run against working copy
- paths, can display the lock token reveals an important fact
- about lock tokens—that they are cached in the working
- copy. The presence of the lock token is critical. It gives
- the working copy authorization to make use of the lock later
- on. Also, the <command>svn status</command> command shows a
- <literal>K</literal> next to the file (short for locKed),
- indicating that the lock token is present.</para>
+ <para>If the repository lock was broken, then <command>svn
+ status --show-updates</command> displays a
+ <literal>B</literal> (Broken) symbol next to the file. If a
+ new lock exists in place of the old one, then a
+ <literal>T</literal> (sTolen) symbol is shown. Finally,
+ <command>svn update</command> notices any defunct lock tokens
+ and removes them from the working copy.</para>
<sidebar>
- <title>Regarding lock tokens</title>
+ <title>Locking Policies</title>
- <para>A lock token isn't an authentication token, so much as
- an <emphasis>authorization</emphasis> token. The token
- isn't a protected secret. In fact, a lock's unique token is
- discoverable by anyone who runs <command>svn info
- URL</command>. A lock token is special only when it lives
- inside a working copy. It's proof that the lock was created
- in that particular working copy, and not somewhere else by
- some other client. Merely authenticating as the lock owner
- isn't enough to prevent accidents.</para>
+ <para>Different systems have different notions of how strict a
+ lock should be. Some folks argue that locks must be
+ strictly enforced at all costs, releasable only by the
+ original creator or administrator. They argue that if
+ anyone can break a lock, then chaos runs rampant and the
+ whole point of locking is defeated. The other side argues
+ that locks are first and foremost a communication tool. If
+ users are constantly breaking each others' locks, then it
+ represents a cultural failure within the team and the
+ problem falls outside the scope of software enforcement.</para>
- <para>For example, suppose you lock a file using a computer at
- your office, but leave work for the day before you finish
- your changes to that file. It should not be possible to
- accidentally commit changes to that same file from your home
- computer later that evening simply because you've
- authenticated as the lock's owner. In other words, the lock
- token prevents one piece of Subversion-related software from
- undermining the work of another. (In our example, if you
- really need to change the file from an alternate working
- copy, you would need to break the lock and re-lock the
- file.)</para>
+ <para>Subversion defaults to the <quote>softer</quote>
+ approach, but still allows administrators to create stricter
+ enforcement policies through the use of hook scripts. In
+ particular, the <filename>pre-lock</filename> and
+ <filename>pre-unlock</filename> hooks allow administrators
+ to decide when lock creation and lock releases are allowed
+ to happen. Depending on whether or not a lock already
+ exists, these two hooks can decide whether or not to allow a
+ certain user to break or steal a lock. The
+ <filename>post-lock</filename> and
+ <filename>post-unlock</filename> hooks are also available,
+ and can be used to send email after locking actions. To
+ learn more about repository hooks, see <xref
+ linkend="svn.reposadmin.create.hooks" />.</para>
</sidebar>
- <para>Now that Harry has locked <filename>banana.jpg</filename>,
- Sally is unable to change or delete that file:</para>
-
- <screen>
-$ svn delete banana.jpg
-D banana.jpg
-$ svn commit -m "Delete useless file."
-Deleting banana.jpg
-svn: Commit failed (details follow):
-svn: DELETE of
-'/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banana.jpg':
-423 Locked (http://svn.example.com)
-$
-</screen>
+ </sect2>
- <para>But Harry, after touching up the banana's shade of yellow,
- is able to commit his changes to the file. That's because he
- authenticates as the lock owner, and also because his working
- copy holds the correct lock token:</para>
+ <!-- =============================================================== -->
+ <sect2 id="svn.advanced.locking.lock-communication">
+ <title>Lock Communication</title>
- <screen>
-$ svn status
-M K banana.jpg
-$ svn commit -m "Make banana more yellow"
-Sending banana.jpg
-Transmitting file data .
-Committed revision 2201.
-$ svn status
-$
-</screen>
+ <para>We've seen how <command>svn lock</command>
+ and <command>svn unlock</command> can be used to create,
+ release, break, and steal locks. This satisfies the goal of
+ serializing commit access to a file. But what about the
+ larger problem of preventing wasted time?</para>
- <para>Notice that after the commit is finished, <command>svn
- status</command> shows that the lock token is no longer
- present in working copy. This is the standard behavior of
- <command>svn commit</command>—it searches the working
- copy (or list of targets, if you provide such a list) for
- local modifications, and sends all the lock tokens it
- encounters during this walk to the server as part of the
- commit transaction. After the commit completes successfully,
- all of the repository locks that were mentioned are
- released—<emphasis>even on files that weren't
- committed</emphasis>. This is meant to discourage users from
- being sloppy about locking, or from holding locks for too
- long. If Harry haphazardly locks thirty files in a directory
- named <filename>images</filename> because he's unsure of which
- files he needs to change, yet only only changes four of those
- file, when he runs <command>svn commit images</command>, the
- process will still release all thirty locks.</para>
+ <para>For example, suppose Harry locks an image file and then
+ begins editing it. Meanwhile, miles away, Sally wants to do
+ the same thing. She doesn't think to run <command>svn status
+ --show-updates</command>, so she has no idea that Harry has
+ already locked the file. She spends hours editing the file,
+ and when she tries to commit her change, she discovers that
+ either the file is locked or that she's out-of-date.
+ Regardless, her changes aren't mergeable with Harry's. One of
+ these two people has to throw away their work, and a lot of
+ time has been wasted.</para>
- <para>This behavior of automatically releasing locks can be
- overridden with the <option>--no-unlock</option> option to
- <command>svn commit</command>. This is best used for those
- times when you want to commit changes, but still plan to make
- more changes and thus need to retain existing locks. You can
- also make this your default behavior by setting the
- <literal>no-unlock</literal> runtime configuration option (see
- <xref linkend="svn.advanced.confarea" />).</para>
+ <para>Subversion's solution to this problem is to provide a
+ mechanism to remind users that a file ought to be locked
+ <emphasis>before</emphasis> the editing begins. The mechanism
+ is a special property, <literal>svn:needs-lock</literal>. If
+ that property is attached to a file (regardless of its value,
+ which is irrelevant), then Subversion will try to use
+ filesystem-level permissions to make the file read-only,
+ unless, of course, the user has explicitly locked the file.
+ When a lock-token is present (as a result of running
+ <command>svn lock</command>), the file becomes read-write.
+ When the lock is released, the file becomes read-only
+ again.</para>
- <para>Of course, locking a file doesn't oblige one to commit a
- change to it. The lock can be released at any time with a
- simple <command>svn unlock</command> command:</para>
+ <para>The theory, then, is that if the image file has this
+ property attached, then Sally would immediately notice
+ something is strange when she opens the file for editing.
+ Many applications alert users immediately when a read-only
+ file is opened for editing. And nearly all applications would
+ at least prevent her from saving changes to the file. This
+ reminds her to lock the file before editing, whereby she
+ discovers the pre-existing lock:</para>
<screen>
-$ svn unlock banana.c
-'banana.c' unlocked.
+$ /usr/local/bin/gimp raisin.jpg
+gimp: error: file is read-only!
+$ ls -l raisin.jpg
+-r--r--r-- 1 sally sally 215589 Jun 8 19:23 raisin.jpg
+$ svn lock raisin.jpg
+svn: Lock request failed: 423 Locked (http://svn.example.com)
+$ svn info http://svn.example.com/repos/project/raisin.jpg | grep Lock
+Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
+Lock Owner: harry
+Lock Created: 2006-06-08 07:29:18 -0500 (Thu, 08 June 2006)
+Lock Comment (1 line):
+Making some tweaks. Locking for the next two hours.
+$
</screen>
+ <tip>
+ <para>Users and administrators alike are encouraged to attach
+ the <literal>svn:needs-lock</literal> property to any file
+ which cannot be contextually merged. This is the primary
+ technique for encouraging good locking habits and preventing
+ wasted effort.</para>
+ </tip>
+
+ <para>Note that this property is a communication tool which
+ works independently from the locking system. In other words,
+ any file can be locked, whether or not this property is
+ present. And conversely, the presence of this property
+ doesn't make the repository require a lock when
+ committing.</para>
+
+ <para>Unfortunately, the system isn't flawless. It's possible
+ that even when a file has the property, the read-only reminder
+ won't always work. Sometimes applications misbehave and
+ <quote>hijack</quote> the read-only file, silently allowing
+ users to edit and save the file anyway. There's not much that
+ Subversion can do in this situation—at the end of the
+ day, there's simply no substitution for good interpersonal
+ communication.
+ <footnote>
+ <para>Except, perhaps, a classic Vulcan mind-meld.</para>
+ </footnote>
+ </para>
+
</sect2>
- <!-- =============================================================== -->
- <sect2 id="svn.advanced.locking.discovery">
- <title>Discovering locks</title>
+ </sect1>
- <para>When a commit fails due to someone else's locks, it's
- fairly easy to learn about them. The easiest of
- these is <command>svn status --show-updates</command>:</para>
+ <!-- ================================================================= -->
+ <!-- ================================================================= -->
+ <!-- ================================================================= -->
+ <sect1 id="svn.advanced.externals">
+ <!-- @ENGLISH {{{
+ <title>Externals Definitions</title>
+ @ENGLISH }}} -->
+ <title>Внешние определения</title>
- <screen>
-$ svn status --show-updates
-M 23 bar.c
-M O 32 raisin.jpg
- * 72 foo.h
-Status against revision: 105
-$
-</screen>
+ <!-- @ENGLISH {{{
+ <para>Sometimes it is useful to construct a working copy that is
+ made out of a number of different checkouts. For example, you
+ may want different subdirectories to come from different
+ locations in a repository, or perhaps from different
+ repositories altogether. You could certainly setup such a
+ scenario by hand—using <command>svn checkout</command> to
+ create the sort of nested working copy structure you are trying
+ to achieve. But if this layout is important for everyone who
+ uses your repository, every other user will need to perform the
+ same checkout operations that you did.</para>
+ @ENGLISH }}} -->
+ <para>Иногда полезно сконструировать рабочую копию так, чтобы делать
+ несколько различных извлечений. Например, вы хотите иметь
+ различные подпапки соответствующие различным путям в
+ хранилище, или возможно из различных хранилищ. Конечно, вы можете
+ выполнить этот сценарий вручную — используя <command>svn
+ checkout</command> для создания требуемой вложенной структуры рабочей
+ копии. Но если этот формат важен для всех кто использует
+ хранилище, каждый новый пользователь нуждается в выполнении тех
+ же операций извлечения что делали и вы.</para>
+ <!-- @ENGLISH {{{
+ <para>Fortunately, Subversion provides support for
+ <firstterm>externals definitions</firstterm>. An externals
+ definition is a mapping of a local directory to the
+ URL—and possibly a particular revision—of a
+ versioned directory. In Subversion, you declare externals
+ definitions in groups using the <literal>svn:externals</literal>
+ property. You can create or modify this property using
+ <command>svn propset</command> or <command>svn
+ propedit</command> (see <xref linkend="svn.advanced.props.manip"
+ />). It can be set on any versioned directory, and its value is
+ a multi-line table of subdirectories (relative to the versioned
+ directory on which the property is set) and fully qualified,
+ absolute Subversion repository URLs.</para>
+ @ENGLISH }}} -->
+ <para>Ксчастью, Subversion предоставляет поддержку
+ <firstterm>внешних определений</firstterm>. Внешние определения
+ это отображение локальной папки в URL — и возможно
+ конкретной ревизии — версионировнанной директории. В
+ Subversion вы декларируете внешние определения в группах используя
+ свойство <literal>svn:externals</literal>. Вы можете создать или
+ изменить это свойство используя <command>svn propset</command> или
+ <command>svn propedit</command> (смотри <xref
+ linkend="svn.advanced.props.manip"
+ />). Оно может быть установлено на любой версионированной папке,
+ и его значение многостроковая таблица подпапок (относительно
+ версионированной папки для которой устанавливается значение) и
+ полные, абсолютные URL в хранилище Subversion.</para>
- <para>In this example, Sally can see not only that her copy of
- <filename>foo.h</filename> is out-of-date, but that one of the
- two modified files she plans to commit is locked in the
- repository. The <literal>O</literal> symbol stands for
- <quote>Other</quote>, meaning that a lock exists on the file,
- and was created by somebody else. If she were to attempt a
- commit, the lock on <filename>raisin.jpg</filename> would
- prevent it. Sally is left wondering who made the lock, when,
- and why. Once again, <command>svn info</command> has the
- answers:</para>
- <screen>
-$ svn info http://svn.example.com/repos/project/raisin.jpg
-Path: raisin.jpg
-Name: raisin.jpg
-URL: http://svn.example.com/repos/project/raisin.jpg
-Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec
-Revision: 105
-Node Kind: file
-Last Changed Author: sally
-Last Changed Rev: 32
-Last Changed Date: 2005-01-25 12:43:04 -0600 (Tue, 25 Jan 2005)
-Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
-Lock Owner: harry
-Lock Created: 2005-02-16 13:29:18 -0500 (Wed, 16 Feb 2005)
-Lock Comment (1 line):
-Need to make a quick tweak to this image.
-$
+ <screen>
+$ svn propget svn:externals calc
+third-party/sounds http://sounds.red-bean.com/repos
+third-party/skins http://skins.red-bean.com/repositories/skinproj
+third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker
</screen>
- <para>Just as <command>svn info</command> can be used to examine
- objects in the working copy, it can also be used to examine
- objects in the repository. If the main argument to
- <command>svn info</command> is a working copy path, then all
- of the working copy's cached information is displayed; any
- mention of a lock means that the working copy is holding a
- lock token (if a file is locked by another user or in another
- working copy, <command>svn info</command> on a working copy
- path will show no lock information at all). If the main
- argument to <command>svn info</command> is a URL, then the
- information reflects the latest version of an object in the
- repository, and any mention of a lock describes the current
- lock on the object.</para>
- <para>So in this particular example, Sally can see that Harry
- locked the file on February 16th to <quote>make a quick
- tweak</quote>. It being June, she suspects that he probably
- forgot all about the lock. She might phone Harry to complain
- and ask him to release the lock. If he's unavailable, she
- might try to forcibly break the lock herself or ask an
- administrator to do so.</para>
+ <!-- @ENGLISH {{{
+ <para>The convenience of the <literal>svn:externals</literal>
+ property is that once it is set on a versioned directory,
+ everyone who checks out a working copy with that directory also
+ gets the benefit of the externals definition. In other words,
+ once one person has made the effort to define those nested
+ working copy checkouts, no one else has to
+ bother—Subversion will, upon checkout of the original
+ working copy, also checkout the external working copies.</para>
- </sect2>
+ <para>Note the previous externals definition example. When
+ someone checks out a working copy of the
+ <filename>calc</filename> directory, Subversion also continues
+ to checkout the items found in its externals definition.</para>
+ @ENGLISH }}} -->
+ <para>Удобство свойства <literal>svn:externals</literal> заключается
+ в том что однажды установленное на версионную папку, любой кто
+ извлекает рабочую копию с такой папкой также получает преимущества
+ внешнего представления. Другими словами, однажды один человек
+ сделал усилие для определения этих вложенных извлечений рабочих
+ копии, никто другой не беспокоится об этом — Subversion при
+ извлечении оригинальной рабочей копии, будет также извлекать
+ внешнии рабочие копии.</para>
- <!-- =============================================================== -->
- <sect2 id="svn.advanced.locking.break-steal">
- <title>Breaking and stealing locks</title>
+ <para>Примечание к предыдущему примеру внешнего определения. Когда
+ кто-то извлекает рабочую копию папки <filename>calc</filename>,
+ Subversion также продолжает извлекать элементы найденные в его
+ внешних определениях.</para>
- <para>A repository lock isn't sacred—in Subversion's
- default configuration state, locks can be released not only by
- the person who created them, but by anyone at all. When
- somebody other than the original lock creator destroys a lock,
- we refer to this as <firstterm>breaking</firstterm> the
- lock.</para>
- <para>From the administrator's chair, it's simple to break
- locks. The <command>svnlook</command>
- and <command>svnadmin</command> programs have the ability to
- display and remove locks directly from the repository. (For
- more information about these tools, see
- <xref linkend="svn.reposadmin.maint.tk"/>.)</para>
+ <screen>
+$ svn checkout http://svn.example.com/repos/calc
+A calc
+A calc/Makefile
+A calc/integer.c
+A calc/button.c
+Checked out revision 148.
- <screen>
-$ svnadmin lslocks /usr/local/svn/repos
-Path: /project2/images/banana.jpg
-UUID Token: opaquelocktoken:c32b4d88-e8fb-2310-abb3-153ff1236923
-Owner: frank
-Created: 2005-06-15 13:29:18 -0500 (Wed, 15 Jun 2005)
-Expires:
-Comment (1 line):
-Still improving the yellow color.
+Fetching external item into calc/third-party/sounds
+A calc/third-party/sounds/ding.ogg
+A calc/third-party/sounds/dong.ogg
+A calc/third-party/sounds/clang.ogg
+…
+A calc/third-party/sounds/bang.ogg
+A calc/third-party/sounds/twang.ogg
+Checked out revision 14.
+
+Fetching external item into calc/third-party/skins
+…
+</screen>
+
+ <!-- @ENGLISH {{{
+ <para>If you need to change the externals definition, you can do
+ so using the regular property modification subcommands. When
+ you commit a change to the <literal>svn:externals</literal>
+ property, Subversion will synchronize the checked-out items
+ against the changed externals definition when you next run
+ <command>svn update</command>. The same thing will happen when
+ others update their working copies and receive your changes to
+ the externals definition.</para>
+
+ <tip>
+ <para>Because the <literal>svn:externals</literal> property has
+ a multiline value, we strongly recommend that you use
+ <command>svn propedit</command> instead of <command>svn
+ propset</command>.</para>
+ </tip>
+ @ENGLISH }}} -->
+ <para>Если вы нуждаетесь в изменении внешних определений, вы можете
+ их делать используя обычные подкоманды изменения свойств. Когда вы
+ фиксируете изменения в свойстве <literal>svn:externals</literal>,
+ Subversion будет синхронизировать извлекаемые элементы измененные
+ во внешнем определении при следующем выполнении <command>svn
+ update</command>. Тоже самое будет происходить когда другие
+ обновляют свои рабочие копии и получать ваши изменения во внешнем
+ определении.</para>
-Path: /project/raisin.jpg
-UUID Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
-Owner: harry
-Created: 2005-02-16 13:29:18 -0500 (Wed, 16 Feb 2005)
-Expires:
-Comment (1 line):
-Need to make a quick tweak to this image.
+ <para>Команда <command>svn status</command> также распознает внешние
+ определения, отображая код статуса <literal>X</literal> для
+ нарушающих структуру подпапок в которые внешние извлечены, и затем
+ рекурсивно по этим подпапкам для отображения статуса самих внешних
+ элементов.</para>
-$ svnadmin rmlocks /usr/local/svn/repos /project/raisin.jpg
-Removed lock on '/project/raisin.jpg'.
-$
-</screen>
+ <tip>
+ <!-- @ENGLISH {{{
+ <para>You should strongly consider using explicit revision
+ numbers in all of your externals definitions. Doing so means
+ that you get to decide when to pull down a different snapshot
+ of external information, and exactly which snapshot to pull.
+ Besides avoiding the surprise of getting changes to
+ third-party repositories that you might not have any control
+ over, using explicit revision numbers also means that as you
+ backdate your working copy to a previous revision, your
+ externals definitions will also revert to the way they looked
+ in that previous revision, which in turn means that the
+ external working copies will be updated to match they way
+ <emphasis>they</emphasis> looked back when your repository was
+ at that previous revision. For software projects, this could
+ be the difference between a successful and a failed build of
+ an older snapshot of your complex codebase.</para>
+ @ENGLISH }}} -->
+ <para>Вы должны тщательно подумать пред использованием конкретной
+ ревизии во всех ваших внешних определениях. Делая так, при
+ переходе к другому снимку внешней информации, вы должны решить к
+ какому конкретно снимку перейти. Помимо этого общего аспекта, вы
+ не должны удивляться изменениям происходящим в хранилищах над
+ которыми вы не имеете никакого контроля, использование
+ конкретной ревизии означает что если вы возвращаете вашу рабочую
+ копию к предыдущей ревизии задним числом, ваши внешние
+ определения также будут возвращены в тот вид, как они выглядели
+ в этой предыдущей ревизии, что в свою очередь означает что
+ внешние рабочие копии будут обновлены для соответствия тому как
+ <emphasis>они</emphasis> выглядели когда ваше хранилище было я
+ в предыдущей ревизии. Для программных проектов это может быть
+ различием между успешной и не успешной сборкой на старых снимках
+ вашей комплексной базы кода. </para>
+ </tip>
- <para>The more interesting option is allowing users to break
- each other's locks over the network. To do this, Sally simply
- needs to pass the <option>--force</option> to the unlock
- command:</para>
+ <para>The <command>svn status</command> command also recognizes
+ externals definitions, displaying a status code of
+ <literal>X</literal> for the disjoint subdirectories into which
+ externals are checked out, and then recursing into those
+ subdirectories to display the status of the external items
+ themselves.</para>
+ <!-- @ENGLISH {{{
+ <para>The support that exists for externals definitions in
+ Subversion today can be a little misleading, though. First, an
+ externals definition can only point to directories, not files.
+ Second, the externals definition cannot point to relative paths
+ (paths like <filename>../../skins/myskin</filename>). Third, the
+ working copies created via the externals definition support are
+ still disconnected from the primary working copy (on whose
+ versioned directories the <literal>svn:externals</literal>
+ property was actually set). And Subversion still only truly
+ operates on non-disjoint working copies. So, for example, if
+ you want to commit changes that you've made in one or more of
+ those external working copies, you must run <command>svn
+ commit</command> explicitly on those working
+ copies—committing on the primary working copy will not
+ recurse into any external ones.</para>
- <screen>
-$ svn status --show-updates
-M 23 bar.c
-M O 32 raisin.jpg
- * 72 foo.h
-Status against revision: 105
-$ svn unlock raisin.jpg
-svn: 'raisin.jpg' is not locked in this working copy
-$ svn info raisin.jpg | grep URL
-URL: http://svn.example.com/repos/project/raisin.jpg
-$ svn unlock http://svn.example.com/repos/project/raisin.jpg
-svn: Unlock request failed: 403 Forbidden (http://svn.example.com)
-$ svn unlock --force http://svn.example.com/repos/project/raisin.jpg
-'raisin.jpg' unlocked.
-$
-</screen>
+ <para>Also, since the definitions themselves use absolute URLs,
+ moving or copying a directory to which they are attached will
+ not affect what gets checked out as an external (though the
+ relative local target subdirectory will, of course, move with
+ renamed directory). This can be confusing—even
+ frustrating—in certain situations. For example, say you
+ have a top-level directory named
+ <filename>my-project</filename>, and you've created an externals
+ definition on one of its subdirectories
+ (<filename>my-project/some-dir</filename>) which tracks the
+ latest revision of another of its subdirectories
+ (<filename>my-project/external-dir</filename>).</para>
+ @ENGLISH }}} -->
+ <para>Поддержка существующих внешних определений в Subversion
+ сегодня может вводить в заблуждение. Во первых, внешние определения
+ могут указывать только на папки, не на файлы. Во вторых, внешние
+ определения не могут указывать на относительные пути (пути
+ подобные <filename>../../skins/myskin</filename>). В третьих,
+ рабочие копии созданные через внешние определения поддерживаются
+ отсоединенными от первичной рабочей копии (на чьи версионированные
+ папки установлено свойство <literal>svn:externals</literal>). И
+ Subversion продолжает по-прежнему оперировать на неотстоединенных
+ (non-disjoint) рабочих копиях. Та что, например, если вы хотите
+ зафиксировать изменения которые вы сделали в одной или более
+ внешней рабочей копии, вы должны явно выполнить
+ <command>svn commit</command> на этих рабочих копиях — фиксация
+ первичной рабочей копии не выполняется рекурсивно на любых внешних
+ определениях.</para>
- <para>Now, Sally's initial attempt to unlock failed because she
- ran <command>svn unlock</command> directly on her working copy
- of the file, and no lock token was present. To remove the
- lock directly from the repository, she needs to pass a URL
- to <command>svn unlock</command>. Her first attempt to unlock
- the URL fails, because she can't authenticate as the lock
- owner (nor does she have the lock token). But when she
- passes <option>--force</option>, the authentication and
- authorization requirements are ignored, and the remote lock is
- broken.</para>
+ <para>Кроме того, так как подобные определения используют абсолютные URL,
+ перемещение или копирование папки к которой они присоединены не
+ будет влиять на то, что будет вытаскиваться из хранилища как
+ внешнее определение (при этом, локальные поддирекотрии, назначенные
+ как целевые для внешних определений, при переименовании родительской
+ директории будут, естественно, перемещенны вместе с ней).
+ В определенных ситуациях это может сбивать с толку и запутывать.
+ Например, у вас есть корневая директория <filename>my-project</filename>
+ и одну из её поддиректорий (<filename>my-project/some-dir</filename>)
+ вы делаете внешним определением, отслеживающим изменения другой
+ поддиректории (<filename>my-project/external-dir</filename>).</para>
- <para>Of course, simply breaking a lock may not be enough. In
- the running example, Sally may not only want to break Harry's
- long-forgotten lock, but re-lock the file for her own use.
- She can accomplish this by running <command>svn unlock
- --force</command> and then <command>svn lock</command>
- back-to-back, but there's a small chance that somebody else
- might lock the file between the two commands. The simpler thing
- to is <firstterm>steal</firstterm> the lock, which involves
- breaking and re-locking the file all in one atomic step. To
- do this, Sally passes the <option>--force</option> option
- to <command>svn lock</command>:</para>
+ <screen>
+$ svn co http://svn.example.com/projects .
+A my-project
+A my-project/some-dir
+A my-project/external-dir
+…
+Fetching external item into 'my-project/some-dir/subdir'
+Checked out external at revision 11.
+
+Checked out revision 11.
+$ svn pget svn:externals my-project/some-dir
+subdir http://svn.example.com/projects/my-project/external-dir
- <screen>
-$ svn lock raisin.jpg
-svn: Lock request failed: 423 Locked (http://svn.example.com)
-$ svn lock --force raisin.jpg
-'raisin.jpg' locked by user 'sally'.
$
</screen>
- <para>In any case, whether the lock is broken or stolen, Harry
- may be in for a surprise. Harry's working copy still contains
- the original lock token, but that lock no longer exists. The
- lock token is said to be <firstterm>defunct</firstterm>. The
- lock represented by the lock-token has either been broken (no
- longer in the repository), or stolen (replaced with a
- different lock). Either way, Harry can see this by asking
- <command>svn status</command> to contact the
- repository:</para>
+ <para>Now you use <command>svn move</command> to rename the
+ <filename>my-project</filename> directory. At this point, your
+ externals definition will still refer to a path under the
+ <filename>my-project</filename> directory, even though that
+ directory no longer exists.</para>
- <screen>
-$ svn status
- K raisin.jpg
-$ svn status --show-updates
- B 32 raisin.jpg
-$ svn update
- B raisin.jpg
-$ svn status
+ <screen>
+$ svn mv -q my-project renamed-project
+$ svn ci -m "Rename my-project to renamed-project."
+Deleting my-project
+Adding my-renamed-project
+
+Committed revision 12.
+$ svn up
+
+Fetching external item into 'renamed-project/some-dir/subdir'
+svn: Target path does not exist
$
</screen>
- <para>If the repository lock was broken, then <command>svn
- status --show-updates</command> displays a
- <literal>B</literal> (Broken) symbol next to the file. If a
- new lock exists in place of the old one, then a
- <literal>T</literal> (sTolen) symbol is shown. Finally,
- <command>svn update</command> notices any defunct lock tokens
- and removes them from the working copy.</para>
+ <para>Also, the fact that externals definitions use absolute URLs
+ can cause problems with repositories that are available via
+ multiple URL schemes. For example, if your Subversion server is
+ configured to allow everyone to checkout the repository over
+ <literal>http://</literal> or <literal>https://</literal>, but
+ only allow commits to come in via <literal>https://</literal>,
+ you have an interesting problem on your hands. If your
+ externals definitions use the <literal>http://</literal> form
+ of the repository URLs, you won't be able to commit anything
+ from the working copies created by those externals. On the
+ other hand, if they use the <literal>https://</literal> form of
+ the URLs, anyone who might be checking out via
+ <literal>http://</literal> because their client doesn't support
+ <literal>https://</literal> will be unable to fetch the external
+ items. Be aware, too, that if you need to re-parent your
+ working copy (using <command>svn switch --relocate</command>),
+ externals definitions will <emphasis>not</emphasis> also be
+ re-parented.</para>
- <sidebar>
- <title>Locking Policies</title>
+ <!-- @ENGLISH {{{
+ <para>Finally, there might be times when you would prefer that
+ <command>svn</command> subcommands would not recognize or
+ otherwise operate on the external working copies created as the
+ result of externals definition handling. In those instances,
+ you can pass the <option>--><!--ignore-externals</option> option to
+ the subcommand.</para>
+ @ENGLISH }}} -->
+ <para>Наконец, могут буть ситуации в которых предпочтительно, чтобы
+ подкоманды <command>svn</command> не идентифицировали и не оперировали
+ над рабочими копиями, созданными как внешние определения. Для таких
+ случаев, при вызове подкоманды можно использовать параметр
+ <option>--ignore-externals</option>.</para>
- <para>Different systems have different notions of how strict a
- lock should be. Some folks argue that locks must be
- strictly enforced at all costs, releasable only by the
- original creator or administrator. They argue that if
- anyone can break a lock, then chaos runs rampant and the
- whole point of locking is defeated. The other side argues
- that locks are first and foremost a communication tool. If
- users are constantly breaking each others' locks, then it
- represents a cultural failure within the team and the
- problem falls outside the scope of software enforcement.</para>
+ </sect1>
- <para>Subversion defaults to the <quote>softer</quote>
- approach, but still allows administrators to create stricter
- enforcement policies through the use of hook scripts. In
- particular, the <filename>pre-lock</filename> and
- <filename>pre-unlock</filename> hooks allow administrators
- to decide when lock creation and lock releases are allowed
- to happen. Depending on whether or not a lock already
- exists, these two hooks can decide whether or not to allow a
- certain user to break or steal a lock. The
- <filename>post-lock</filename> and
- <filename>post-unlock</filename> hooks are also available,
- and can be used to send email after locking actions. To
- learn more about repository hooks, see <xref
- linkend="svn.reposadmin.create.hooks" />.</para>
+ <!-- ================================================================= -->
+ <!-- ================================================================= -->
+ <!-- ================================================================= -->
+ <sect1 id="svn.advanced.pegrevs">
+ <title>Peg and Operative Revisions</title>
- </sidebar>
+ <para>We make use of the ability to copy, move, rename, and
+ completely replace files and directories on our computers all
+ the time. And your version control system shouldn't get in the
+ way of your doing these things with your version-controlled
+ files and directories, either. Subversion's file management
+ support is quite liberating, affording almost as much
+ flexibility for versioned files as you'd expect when
+ manipulating your unversioned ones. But that flexibility means
+ that across the lifetime of your repository, a given versioned
+ object might have many paths, and a given path might represent
+ several entirely different versioned objects. And this
+ introduces a certain level of complexity to your interactions
+ with those paths and objects.</para>
- </sect2>
+ <para>Subversion is pretty smart about noticing when an object's
+ version history includes such <quote>changes of address</quote>.
+ For example, if you ask for the revision history log of a
+ particular file that was renamed last week, Subversion happily
+ provides all those logs—the revision in which the rename
+ itself happened, plus the logs of relevant revisions both before
+ and after that rename. So, most of the time, you don't even
+ have to think about such things. But occasionally, Subversion
+ needs your help to clear up ambiguities.</para>
- <!-- =============================================================== -->
- <sect2 id="svn.advanced.locking.lock-communication">
- <title>Lock Communication</title>
+ <para>The simplest example of this occurs when a directory or file
+ is deleted from version control, and then a new directory or
+ file is created with the same name and added to version control.
+ Clearly the thing you deleted and the thing you later added
+ aren't the same thing. They merely happen to have had the same
+ path, <filename>/trunk/object</filename> for example. What,
+ then, does it mean to ask Subversion about the history of
+ <filename>/trunk/object</filename>? Are you asking about the
+ thing currently at that location, or the old thing you deleted
+ from that location? Are you asking about the operations that
+ have happened to <emphasis>all</emphasis> the objects that have
+ ever lived at that path? Clearly, Subversion needs a hint about
+ what you really want.</para>
+
+ <para>And thanks to moves, versioned object history can get far
+ more twisted than that, even. For example, you might have a
+ directory named <filename>concept</filename>, containing some
+ nascent software project you've been toying with. Eventually,
+ though, that project matures to the point that the idea seems to
+ actually have some wings, so you do the unthinkable and decide
+ to give the project a name.
+ <footnote>
+ <para><quote>You're not supposed to name it. Once you name it,
+ you start getting attached to it.</quote> — Mike
+ Wazowski</para>
+ </footnote>
+ Let's say you called your software Frabnaggilywort. At this
+ point, it makes sense to rename the directory to reflect the
+ project's new name, so <filename>concept</filename> is renamed
+ to <filename>frabnaggilywort</filename>. Life goes on,
+ Frabnaggilywort releases a 1.0 version, and is downloaded and
+ used daily by hordes of people aiming to improve their
+ lives.</para>
+
+ <para>It's a nice story, really, but it doesn't end there.
+ Entrepreneur that you are, you've already got another think in
+ the tank. So you make a new directory,
+ <filename>concept</filename>, and the cycle begins again. In
+ fact, the cycle begins again many times over the years, each
+ time starting with that old <filename>concept</filename>
+ directory, then sometimes seeing that directory renamed as the
+ idea cures, sometimes seeing it deleted when you scrap the idea.
+ Or, to get really sick, maybe you rename
+ <filename>concept</filename> to something else for a while, but
+ later rename the thing back to <filename>concept</filename> for
+ some reason.</para>
- <para>We've seen how <command>svn lock</command>
- and <command>svn unlock</command> can be used to create,
- release, break, and steal locks. This satisfies the goal of
- serializing commit access to a file. But what about the
- larger problem of preventing wasted time?</para>
+ <para>When scenarios like these occur, attempting to instruct
+ Subversion to work with these re-used paths can be a little like
+ instructing a motorist in Chicago's West Suburbs to drive east
+ down Roosevelt Road and turn left onto Main Street. In a mere
+ twenty minutes, you can cross <quote>Main Street</quote> in
+ Wheaton, Glen Ellyn, and Lombard. And no, they aren't the same
+ street. Our motorist—and our Subversion—need a
+ little more detail in order to do the right thing.</para>
- <para>For example, suppose Harry locks an image file and then
- begins editing it. Meanwhile, miles away, Sally wants to do
- the same thing. She doesn't think to run <command>svn status
- --show-updates</command>, so she has no idea that Harry has
- already locked the file. She spends hours editing the file,
- and when she tries to commit her change, she discovers that
- either the file is locked or that she's out-of-date.
- Regardless, her changes aren't mergeable with Harry's. One of
- these two people has to throw away their work, and a lot of
- time has been wasted.</para>
+ <para>In version 1.1, Subversion introduced a way for you to tell
+ it exactly which Main Street you meant. It's called the
+ <firstterm>peg revision</firstterm>, and it is a revision
+ provided to Subversion for the sole purpose of identifying a
+ unique line of history. Because at most one versioned object
+ may occupy a path at any given time—or, more precisely, in
+ any one revision—the combination of a path and a peg
+ revision is all that is needed to refer to a specific line of
+ history. Peg revisions are specified to the Subversion
+ command-line client using <firstterm>at syntax</firstterm>, so
+ called because the syntax involves appending an <quote>at
+ sign</quote> (<literal>@</literal>) and the peg revision to the
+ end of the path with which the revision is associated.</para>
- <para>Subversion's solution to this problem is to provide a
- mechanism to remind users that a file ought to be locked
- <emphasis>before</emphasis> the editing begins. The mechanism
- is a special property, <literal>svn:needs-lock</literal>. If
- that property is attached to a file (regardless of its value,
- which is irrelevant), then Subversion will try to use
- filesystem-level permissions to make the file read-only,
- unless, of course, the user has explicitly locked the file.
- When a lock-token is present (as a result of running
- <command>svn lock</command>), the file becomes read-write.
- When the lock is released, the file becomes read-only
- again.</para>
+ <para>But what of the <option>--revision (-r)</option> of which
+ we've spoken so much in this book? That revision (or set of
+ revisions) is called the <firstterm>operative
+ revision</firstterm> (or <firstterm>operative revision
+ range</firstterm>). Once a particular line of history has been
+ identified using a path and peg revision, Subversion performs
+ the requested operation using the operative revision(s). To map
+ this to our Chicagoland streets analogy, if we are told to go to
+ 606 N. Main Street in Wheaton,
+ <footnote>
+ <para>606 N. Main Street, Wheaton, Illinois, is the home of
+ the Wheaton History Center. Get it—<quote>History
+ Center</quote>? It seemed appropriate….</para>
+ </footnote>
+ we can think of <quote>Main Street</quote> as our path and
+ <quote>Wheaton</quote> as our peg revision. These two pieces of
+ information identify a unique path which can travelled (north or
+ south on Main Street), and will keep us from travelling up and
+ down the wrong Main Street in search of our destination. Now we
+ throw in <quote>606 N.</quote> as our operative revision, of
+ sorts, and we know <emphasis>exactly</emphasis> where to
+ go.</para>
- <para>The theory, then, is that if the image file has this
- property attached, then Sally would immediately notice
- something is strange when she opens the file for editing.
- Many applications alert users immediately when a read-only
- file is opened for editing. And nearly all applications would
- at least prevert her from saving changes to the file. This
- reminds her to lock the file before editing, whereby she
- discovers the pre-existing lock:</para>
+ <sidebar>
+ <title>The peg revision algorithm</title>
+
+ <para>The Subversion command-line performs the peg revision
+ algorithm any time it needs to resolve possible ambiguities in
+ the paths and revisions provided to it. Here's an example of
+ such an invocation for the purposes of illustrating that
+ algorithm.</para>
<screen>
-$ /usr/local/bin/gimp raisin.jpg
-gimp: error: file is read-only!
-$ ls -l raisin.jpg
--r--r--r-- 1 sally sally 215589 Jun 8 19:23 raisin.jpg
-$ svn lock raisin.jpg
-svn: Lock request failed: 423 Locked (http://svn.example.com)
-$ svn info http://svn.example.com/repos/project/raisin.jpg | grep Lock
-Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
-Lock Owner: harry
-Lock Created: 2005-06-08 07:29:18 -0500 (Thu, 08 June 2005)
-Lock Comment (1 line):
-Making some tweaks. Locking for the next two hours.
-$
+$ svn <replaceable>command</replaceable> -r <replaceable>OPERATIVE-REV</replaceable> item@<replaceable>PEG-REV</replaceable>
</screen>
+
+ <para>The algorithm has three simple steps:</para>
- <tip>
- <para>Users and administrators alike are encouraged to attach
- the <literal>svn:needs-lock</literal> property to any file
- which cannot be contextually merged. This is the primary
- technique for encouraging good locking habits and preventing
- wasted effort.</para>
- </tip>
+ <itemizedlist>
+
+ <listitem>
+ <para>Locate <replaceable>item</replaceable> in the revision
+ identified by <replaceable>PEG-REV</replaceable>. There
+ can be only one such object.</para>
+ </listitem>
- <para>Note that this property is a communication tool which
- works independently from the locking system. In other words,
- any file can be locked, whether or not this property is
- present. And conversely, the presence of this property
- doesn't make the repository require a lock when
- committing.</para>
+ <listitem>
+ <para>Trace the object's history backwards (through any
+ possible renames) to its ancestor in the
+ revision <replaceable>OPERATIVE-REV</replaceable>.</para>
+ </listitem>
- <para>Unfortunately, the system isn't flawless. It's possible
- that even when a file has the property, the read-only reminder
- won't always work. Sometimes applications misbehave and
- <quote>hijack</quote> the read-only file, silently allowing
- users to edit and save the file anyway. There's not much that
- Subversion can do in this situation—at the end of the
- day, there's simply no substitution for good interpersonal
- communication.
- <footnote>
- <para>Except, perhaps, a classic Vulcan mind-meld.</para>
- </footnote>
- </para>
+ <listitem>
+ <para>Perform the requested action on that ancestor,
+ wherever it is located, or whatever its name might
+ be or have been at that time.</para>
+ </listitem>
- </sect2>
+ </itemizedlist>
- </sect1>
+ <para>Note that even when you don't explicitly supply a peg
+ revision or operative revision, they are still present. For
+ your convenience, the default peg revision is
+ <literal>BASE</literal> for working copy items and
+ <literal>HEAD</literal> for repository URLs. And when no
+ operative revision is provided, it defaults to being the same
+ revision as the peg revision.</para>
+
+ </sidebar>
- <!-- ================================================================= -->
- <!-- ================================================================= -->
- <!-- ================================================================= -->
- <sect1 id="svn.advanced.externals">
- <!-- @ENGLISH {{{
- <title>Externals Definitions</title>
- @ENGLISH }}} -->
- <title>Внешние определения</title>
+ <para>Say that long ago we created our repository, and in revision 1
+ added our first <filename>concept</filename> directory, plus an
+ <filename>IDEA</filename> file in that directory talking about
+ the concept. After several revisions in which real code was
+ added and tweaked, we, in revision 20, renamed this directory to
+ <filename>frabnaggilywort</filename>. By revision 27, we had a
+ new concept, a new <filename>concept</filename> directory to
+ hold it, and a new <filename>IDEA</filename> file to describe
+ it. And then five years and twenty thousand revisions flew by,
+ just like they would in any good romance story.</para>
- <!-- @ENGLISH {{{
- <para>Sometimes it is useful to construct a working copy that is
- made out of a number of different checkouts. For example, you
- may want different subdirectories to come from different
- locations in a repository, or perhaps from different
- repositories altogether. You could certainly setup such a
- scenario by hand—using <command>svn checkout</command> to
- create the sort of nested working copy structure you are trying
- to achieve. But if this layout is important for everyone who
- uses your repository, every other user will need to perform the
- same checkout operations that you did.</para>
- @ENGLISH }}} -->
- <para>Иногда полезно сконструировать рабочую копию так, чтобы делать
- несколько различных извлечений. Например, вы хотите иметь
- различные подпапки соответствующие различным путям в
- хранилище, или возможно из различных хранилищ. Конечно, вы можете
- выполнить этот сценарий вручную — используя <command>svn
- checkout</command> для создания требуемой вложенной структуры рабочей
- копии. Но если этот формат важен для всех кто использует
- хранилище, каждый новый пользователь нуждается в выполнении тех
- же операций извлечения что делали и вы.</para>
- <!-- @ENGLISH {{{
- <para>Fortunately, Subversion provides support for
- <firstterm>externals definitions</firstterm>. An externals
- definition is a mapping of a local directory to the
- URL—and possibly a particular revision—of a
- versioned object. In Subversion, you declare externals
- definitions in groups using the <literal>svn:externals</literal>
- property. You can create or modify this property using
- <command>svn propset</command> or <command>svn
- propedit</command> (see <xref linkend="svn.advanced.props.manip"
- />). It can be set on any versioned directory, and its value is
- a multi-line table of subdirectories (relative to the versioned
- directory on which the property is set) and fully qualified,
- absolute Subversion repository URLs.</para>
- @ENGLISH }}} -->
- <para>Ксчастью, Subversion предоставляет поддержку
- <firstterm>внешних определений</firstterm>. Внешние определения
- это отображение локальной папки в URL — и возможно
- конкретной ревизии — версионировнанного ресурса. В
- Subversion вы декларируете внешние определения в группах используя
- свойство <literal>svn:externals</literal>. Вы можете создать или
- изменить это свойство используя <command>svn propset</command> или
- <command>svn propedit</command> (смотри <xref
- linkend="svn.advanced.props.manip"
- />). Оно может быть установлено на любой версионированной папке,
- и его значение многостроковая таблица подпапок (относительно
- версионированной папки для которой устанавливается значение) и
- полные, абсолютные URL в хранилище Subversion.</para>
+ <para>Now, years later, we wonder what the
+ <filename>IDEA</filename> file looked like back in revision 1.
+ But Subversion needs to know if we are asking about how the
+ <emphasis>current</emphasis> file looked back in revision 1, or
+ are we asking for the contents of whatever file lived at
+ <filename>concepts/IDEA</filename> in revision 1? Certainly
+ those questions have different answers, and because of peg
+ revisions, you can ask either of them. To find out how the
+ current <filename>IDEA</filename> file looked in that old
+ revision, you run:</para>
+
+ <screen>
+$ svn cat -r 1 concept/IDEA
+svn: Unable to find repository location for 'concept/IDEA' in revision 1
+</screen>
+ <para>Of course, in this example, the current
+ <filename>IDEA</filename> file didn't exist yet in revision 1,
+ so Subversion gives an error. The command above is shorthand
+ for a longer notation which explicitly lists a peg revision.
+ The expanded notation is:</para>
<screen>
-$ svn propget svn:externals calc
-third-party/sounds http://sounds.red-bean.com/repos
-third-party/skins http://skins.red-bean.com/repositories/skinproj
-third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker
+$ svn cat -r 1 concept/IDEA at BASE
+svn: Unable to find repository location for 'concept/IDEA' in revision 1
</screen>
- <!-- @ENGLISH {{{
- <para>The convenience of the <literal>svn:externals</literal>
- property is that once it is set on a versioned directory,
- everyone who checks out a working copy with that directory also
- gets the benefit of the externals definition. In other words,
- once one person has made the effort to define those nested
- working copy checkouts, no one else has to
- bother—Subversion will, upon checkout of the original
- working copy, also checkout the external working copies.</para>
-
- <para>Note the previous externals definition example. When
- someone checks out a working copy of the
- <filename>calc</filename> directory, Subversion also continues
- to checkout the items found in its externals definition.</para>
- @ENGLISH }}} -->
- <para>Удобство свойства <literal>svn:externals</literal> заключается
- в том что однажды установленное на версионную папку, любой кто
- извлекает рабочую копию с такой папкой также получает преимущества
- внешнего представления. Другими словами, однажды один человек
- сделал усилие для определения этих вложенных извлечений рабочих
- копии, никто другой не беспокоится об этом — Subversion при
- извлечении оригинальной рабочей копии, будет также извлекать
- внешнии рабочие копии.</para>
+ <para>And when executed, it has the expected results. Peg revisions
+ generally default to a value of <literal>BASE</literal> (the
+ revision currently present in the working copy) when applied to
+ working copy paths, and of <literal>HEAD</literal> when applied
+ to URLs.</para>
- <para>Примечание к предыдущему примеру внешнего определения. Когда
- кто-то извлекает рабочую копию папки <filename>calc</filename>,
- Subversion также продолжает извлекать элементы найденные в его
- внешних определениях.</para>
+ <para>The perceptive reader is probably wondering at this point if
+ the peg revision syntax causes problems for working copy paths
+ or URLs that actually have at signs in them. After
+ all, how does <command>svn</command> know whether
+ <literal>news at 11</literal> is the name of a directory in my
+ tree, or just a syntax for <quote>revision 11 of
+ <filename>news</filename></quote>? Thankfully, while
+ <command>svn</command> will always assume the latter, there is a
+ trivial workaround. You need only append an at sign to the
+ end of the path, such as <literal>news at 11@</literal>.
+ <command>svn</command> only cares about the last at sign in
+ the argument, and it is not considered illegal to omit a literal
+ peg revision specifier after that at sign. This workaround
+ even applies to paths that end in an at sign—you would
+ use <literal>filename@@</literal> to talk about a file named
+ <filename>filename@</filename>.</para>
+ <para>Let's ask the other question, then—in revision 1, what
+ were the contents of whatever file occupied the address
+ <filename>concepts/IDEA</filename> at the time? We'll use an
+ explicit peg revision to help us out.</para>
<screen>
-$ svn checkout http://svn.example.com/repos/calc
-A calc
-A calc/Makefile
-A calc/integer.c
-A calc/button.c
-Checked out revision 148.
-
-Fetching external item into calc/third-party/sounds
-A calc/third-party/sounds/ding.ogg
-A calc/third-party/sounds/dong.ogg
-A calc/third-party/sounds/clang.ogg
-…
-A calc/third-party/sounds/bang.ogg
-A calc/third-party/sounds/twang.ogg
-Checked out revision 14.
-
-Fetching external item into calc/third-party/skins
-…
+$ svn cat concept/IDEA at 1
+The idea behind this project is to come up with a piece of software
+that can frab a naggily wort. Frabbing naggily worts is tricky
+business, and doing it incorrectly can have serious ramifications, so
+we need to employ over-the-top input validation and data verification
+mechanisms.
</screen>
- <!-- @ENGLISH {{{
- <para>If you need to change the externals definition, you can do
- so using the regular property modification subcommands. When
- you commit a change to the <literal>svn:externals</literal>
- property, Subversion will synchronize the checked-out items
- against the changed externals definition when you next run
- <command>svn update</command>. The same thing will happen when
- others update their working copies and receive your changes to
- the externals definition.</para>
-
- <tip>
- <para>Because the <literal>svn:externals</literal> property has
- a multiline value, we strongly recommend that you use
- <command>svn propedit</command> instead of <command>svn
- propset</command>.</para>
- </tip>
- @ENGLISH }}} -->
- <para>Если вы нуждаетесь в изменении внешних определений, вы можете
- их делать используя обычные подкоманды изменения свойств. Когда вы
- фиксируете изменения в свойстве <literal>svn:externals</literal>,
- Subversion будет синхронизировать извлекаемые элементы измененные
- во внешнем определении при следующем выполнении <command>svn
- update</command>. Тоже самое будет происходить когда другие
- обновляют свои рабочие копии и получать ваши изменения во внешнем
- определении.</para>
-
- <para>Команда <command>svn status</command> также распознает внешние
- определения, отображая код статуса <literal>X</literal> для
- нарушающих структуру подпапок в которые внешние извлечены, и затем
- рекурсивно по этим подпапкам для отображения статуса самих внешних
- элементов.</para>
+ <para>Notice that we didn't provide an operative revision this
+ time. That's because when no operative revision is specified,
+ Subversion assumes a default operative revision that's the same
+ as the peg revision.</para>
- <tip>
- <!-- @ENGLISH {{{
- <para>You should strongly consider using explicit revision
- numbers in all of your externals definitions. Doing so means
- that you get to decide when to pull down a different snapshot
- of external information, and exactly which snapshot to pull.
- Besides avoiding the surprise of getting changes to
- third-party repositories that you might not have any control
- over, using explicit revision numbers also means that as you
- backdate your working copy to a previous revision, your
- externals definitions will also revert to the way they looked
- in that previous revision, which in turn means that the
- external working copies will be updated to match they way
- <emphasis>they</emphasis> looked back when your repository was
- at that previous revision. For software projects, this could
- be the difference between a successful and a failed build of
- an older snapshot of your complex codebase.</para>
- @ENGLISH }}} -->
- <para>Вы должны тщательно подумать пред использованием конкретной
- ревизии во всех ваших внешних определениях. Делая так, при
- переходе к другому снимку внешней информации, вы должны решить к
- какому конкретно снимку перейти. Помимо этого общего аспекта, вы
- не должны удивляться изменениям происходящим в хранилищах над
- которыми вы не имеете никакого контроля, использование
- конкретной ревизии означает что если вы возвращаете вашу рабочую
- копию к предыдущей ревизии задним числом, ваши внешние
- определения также будут возвращены в тот вид, как они выглядели
- в этой предыдущей ревизии, что в свою очередь означает что
- внешние рабочие копии будут обновлены для соответствия тому как
- <emphasis>они</emphasis> выглядели когда ваше хранилище было я
- в предыдущей ревизии. Для программных проектов это может быть
- различием между успешной и не успешной сборкой на старых снимках
- вашей комплексной базы кода. </para>
- </tip>
+ <para>As you can see, the output from our operation appears to be
+ correct. The text even mentions frabbing naggily worts, so this
+ is almost certainly the file which describes the software now
+ called Frabnaggilywort. In fact, we can verify this using the
+ combination of an explicit peg revision and explicit operative
+ revision. We know that in <literal>HEAD</literal>, the
+ Frabnaggilywort project is located in the
+ <filename>frabnaggilywort</filename> directory. So we specify
+ that we want to see how the line of history identified in
+ <literal>HEAD</literal> as the path
+ <filename>frabnaggilywort/IDEA</filename> looked in revision
+ 1.</para>
- <para>The <command>svn status</command> command also recognizes
- externals definitions, displaying a status code of
- <literal>X</literal> for the disjoint subdirectories into which
- externals are checked out, and then recursing into those
- subdirectories to display the status of the external items
- themselves.</para>
- <!-- @ENGLISH {{{
- <para>The support that exists for externals definitions in
- Subversion today can be a little misleading, though. First, an
- externals definition can only point to directories, not files.
- Second, the externals definition cannot point to relative paths
- (paths like <filename>../../skins/myskin</filename>). Third, the
- working copies created via the externals definition support are
- still disconnected from the primary working copy (on whose
- versioned directories the <literal>svn:externals</literal>
- property was actually set). And Subversion still only truly
- operates on non-disjoint working copies. So, for example, if
- you want to commit changes that you've made in one or more of
- those external working copies, you must run <command>svn
- commit</command> explicitly on those working
- copies—committing on the primary working copy will not
- recurse into any external ones.</para>
+ <screen>
+$ svn cat -r 1 frabnaggilywort/IDEA at HEAD
+The idea behind this project is to come up with a piece of software
+that can frab a naggily wort. Frabbing naggily worts is tricky
+business, and doing it incorrectly can have serious ramifications, so
+we need to employ over-the-top input validation and data verification
+mechanisms.
+</screen>
- <para>Also, since the definitions themselves use absolute URLs,
- moving or copying a directory to which they are attached will
- not affect what gets checked out as an external (though the
- relative local target subdirectory will, of course, move with
- renamed directory). This can be confusing—even
- frustrating—in certain situations. For example, say you
- have a top-level directory named <filename>project</filename>.
- If you create an externals definition on one subdirectory of
- your <filename>project</filename> directory which tracks the
- latest revision of some other subdirectory of that same tree,
- and then you use <command>svn move</command> to rename the
- <filename>project</filename> directory
- <filename>/branches/my-branch</filename>, the externals
- definitions on items in your new branch will still refer to
- versioned objects in the <filename>project</filename> directory,
- even though that directory no longer exists. Be aware, too,
- that if you need to re-parent your working copy (using
- <command>svn switch --><!--relocate</command>), externals definitions
- will <emphasis>not</emphasis> also be re-parented.</para>
- @ENGLISH }}} -->
- <para>Поддержка существующих внешних определений в Subversion
- сегодня может вводить в заблуждение. Во первых, внешние определения
- могут указывать только на папки, не на файлы. Во вторых, внешние
- определения не могут указывать на относительные пути (пути
- подобные <filename>../../skins/myskin</filename>). В третьих,
- рабочие копии созданные через внешние определения поддерживаются
- отсоединенными от первичной рабочей копии (на чьи версионированные
- папки установлено свойство <literal>svn:externals</literal>). И
- Subversion продолжает по-прежнему оперировать на неотстоединенных
- (non-disjoint) рабочих копиях. Та что, например, если вы хотите
- зафиксировать изменения которые вы сделали в одной или более
- внешней рабочей копии, вы должны явно выполнить <command>svn
- commit</command> на этих рабочих копиях — фиксация
- первичной рабочей копии не выполняется рекурсивно на любых внешних
- определениях.</para>
+ <para>And the peg and operative revisions need not be so trivial,
+ either. For example, say <filename>frabnaggilywort</filename>
+ had been deleted from <literal>HEAD</literal>, but we know it
+ existed in revision 20, and we want to see the diffs for its
+ <filename>IDEA</filename> file between revisions 4 and 10. We
+ can use the peg revision 20 in conjunction with the URL that
+ would have held Frabnaggilywort's <filename>IDEA</filename> file
+ in revision 20, and then use 4 and 10 as our operative revision
+ range.</para>
- <para>Также, так как определения используют абсолютные URL,
- перемещение или копирование папки к которой они присоединены не
- будет иметь влияния когда извлекаются как внешние (через
- относительную локальную целевую подпапку, конечно, перемещение с
- переименованием папки). Это может сбивать с толку — даже
- потрясать — в некоторых ситуациях. Например, если вы
- используете внешнее определение на папке в вашей линии разработки
- <filename>/trunk</filename> которая указывает на другую область в
- той же линии, и затем вы используете <command>svn copy</command>
- для ветвления этой линии в некоторое новое место
- <filename>/branches/my-branch</filename>, внешние определения на
- элементах в вашей новой ветке будут продолжать ссылаться на
- версионированные ресурсы в <filename>/trunk</filename>. Также
- знайте, что если вы нуждаетесь в re-parent рабочей копии
- (используя <command>svn switch --relocate</command>), внешние
- определения <emphasis>не</emphasis> будут re-parented.</para>
+ <screen>
+$ svn diff -r 4:10 http://svn.red-bean.com/projects/frabnaggilywort/IDEA@20
+Index: frabnaggilywort/IDEA
+===================================================================
+--- frabnaggilywort/IDEA (revision 4)
++++ frabnaggilywort/IDEA (revision 10)
+@@ -1,5 +1,5 @@
+-The idea behind this project is to come up with a piece of software
+-that can frab a naggily wort. Frabbing naggily worts is tricky
+-business, and doing it incorrectly can have serious ramifications, so
+-we need to employ over-the-top input validation and data verification
+-mechanisms.
++The idea behind this project is to come up with a piece of
++client-server software that can remotely frab a naggily wort.
++Frabbing naggily worts is tricky business, and doing it incorrectly
++can have serious ramifications, so we need to employ over-the-top
++input validation and data verification mechanisms.
+</screen>
- <!-- @ENGLISH {{{
- <para>Finally, there might be times when you would prefer that
- <command>svn</command> subcommands would not recognize or
- otherwise operate on the external working copies created as the
- result of externals definition handling. In those instances,
- you can pass the <option>--><!--ignore-externals</option> option to
- the subcommand.</para>
- @ENGLISH }}} -->
- <para>В заключение может быть случаи когда вы будете предпочитать
- чтобы подкоманды <command>svn</command> не распознавали или
- оперировали другим способом с внешними рабочими копиями созданными
- как результат обработки внешних определений. В этих случаях, вы
- можете передавать параметр <option>--ignore-externals</option> в
- подкоманду.</para>
+ <para>Fortunately, most folks aren't faced with such complex
+ situations. But when you are, remember that peg revisions are
+ that extra hint Subversion needs to clear up ambiguity.</para>
</sect1>
Modified: trunk/src/ru/book/ch-reference.xml
==============================================================================
--- trunk/src/ru/book/ch-reference.xml (original)
+++ trunk/src/ru/book/ch-reference.xml Fri Jun 29 13:24:49 2007
@@ -1060,6 +1060,13 @@
<!-- @ENGLISH {{{
<refentry id="svn.ref.svn.c.add">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>add</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn add</refname>
<refpurpose>Add files, directories, or symbolic links.</refpurpose>
@@ -1160,6 +1167,13 @@
@ENGLISH }}} -->
<refentry id="svn.ref.svn.c.add">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>add</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn add</refname>
<refpurpose>Добавляет файлы, директории и символические
@@ -1260,6 +1274,13 @@
</refentry>
<refentry id="svn.ref.svn.c.blame">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>blame</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn blame</refname>
<!-- @ENGLISH {{{
@@ -1361,6 +1382,13 @@
</refentry>
<refentry id="svn.ref.svn.c.cat">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>cat</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn cat</refname>
<!-- @ENGLISH {{{
@@ -1484,6 +1512,13 @@
</refentry>
<refentry id="svn.ref.svn.c.checkout">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>checkout</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn checkout</refname>
<!-- @ENGLISH {{{
@@ -1667,6 +1702,13 @@
</refentry>
<refentry id="svn.ref.svn.c.cleanup">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>cleanup</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn cleanup</refname>
<!-- @ENGLISH {{{
@@ -1790,6 +1832,13 @@
</refentry>
<refentry id="svn.ref.svn.c.commit">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>commit</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn commit</refname>
<!-- @ENGLISH {{{
@@ -1997,6 +2046,13 @@
</refentry>
<refentry id="svn.ref.svn.c.copy">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>copy</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn copy</refname>
<!-- @ENGLISH {{{
@@ -2254,6 +2310,13 @@
</refentry>
<refentry id="svn.ref.svn.c.delete">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>delete</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn delete</refname>
<!-- @ENGLISH {{{
@@ -2417,6 +2480,13 @@
</refentry>
<refentry id="svn.ref.svn.c.diff">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>diff</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn diff</refname>
<refpurpose>Display the differences between two paths.</refpurpose>
@@ -2662,6 +2732,13 @@
</refentry>
<refentry id="svn.ref.svn.c.export">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>export</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn export</refname>
<refpurpose>Export a clean directory tree.</refpurpose>
@@ -2769,6 +2846,13 @@
<refentry id="svn.ref.svn.c.help">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>help</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn help</refname>
<refpurpose>Help!</refpurpose>
@@ -2814,6 +2898,13 @@
</refentry>
<refentry id="svn.ref.svn.c.import">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>import</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn import</refname>
<refpurpose>Commit an unversioned file or tree into the
@@ -2909,6 +3000,13 @@
</refentry>
<refentry id="svn.ref.svn.c.info">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>info</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn info</refname>
<refpurpose>Display information about a local or remote
@@ -3063,6 +3161,13 @@
</refentry>
<refentry id="svn.ref.svn.c.list">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>list</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn list</refname>
<refpurpose>List directory entries in the repository.</refpurpose>
@@ -3169,6 +3274,13 @@
<refentry id="svn.ref.svn.c.lock">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>lock</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn lock</refname>
<refpurpose>Lock working copy paths or URLs in the
@@ -3263,6 +3375,13 @@
<refentry id="svn.ref.svn.c.log">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>log</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn log</refname>
<refpurpose>Display commit log messages.</refpurpose>
@@ -3500,6 +3619,13 @@
</refentry>
<refentry id="svn.ref.svn.c.merge">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>merge</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn merge</refname>
<refpurpose>Apply the differences between two sources to a
@@ -3614,6 +3740,13 @@
</refentry>
<refentry id="svn.ref.svn.c.mkdir">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>mkdir</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn mkdir</refname>
<refpurpose>Create a new directory under version control.</refpurpose>
@@ -3693,6 +3826,13 @@
</refentry>
<refentry id="svn.ref.svn.c.move">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>move</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn move</refname>
<refpurpose>Move a file or directory.</refpurpose>
@@ -3800,6 +3940,13 @@
</refentry>
<refentry id="svn.ref.svn.c.propdel">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>propdel</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn propdel</refname>
<refpurpose>Remove a property from an item.</refpurpose>
@@ -3871,6 +4018,13 @@
</refentry>
<refentry id="svn.ref.svn.c.propedit">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>propedit</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn propedit</refname>
<refpurpose>Edit the property of one or more items under
@@ -3940,6 +4094,13 @@
</refentry>
<refentry id="svn.ref.svn.c.propget">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>propget</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn propget</refname>
<refpurpose>Print the value of a property.</refpurpose>
@@ -4016,6 +4177,13 @@
</refentry>
<refentry id="svn.ref.svn.c.proplist">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>proplist</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn proplist</refname>
<refpurpose>List all properties.</refpurpose>
@@ -4096,6 +4264,13 @@
</refentry>
<refentry id="svn.ref.svn.c.propset">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>propset</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn propset</refname>
<refpurpose>Set PROPNAME to PROPVAL on files, directories, or revisions.</refpurpose>
@@ -4226,6 +4401,13 @@
</refentry>
<refentry id="svn.ref.svn.c.resolved">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>resolved</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn resolved</refname>
<refpurpose>Remove <quote>conflicted</quote> state on
@@ -4309,6 +4491,13 @@
</refentry>
<refentry id="svn.ref.svn.c.revert">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>revert</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn revert</refname>
<refpurpose>Undo all local edits.</refpurpose>
@@ -4406,6 +4595,13 @@
</refentry>
<refentry id="svn.ref.svn.c.status">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>status</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn status</refname>
<refpurpose>Print the status of working copy files and directories.</refpurpose>
@@ -4805,6 +5001,13 @@
</refentry>
<refentry id="svn.ref.svn.c.switch">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>switch</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn switch</refname>
<refpurpose>Update working copy to a different URL.</refpurpose>
@@ -4959,6 +5162,13 @@
<refentry id="svn.ref.svn.c.unlock">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>unlock</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn unlock</refname>
<refpurpose>Unlock working copy paths or URLs.</refpurpose>
@@ -5046,6 +5256,13 @@
<refentry id="svn.ref.svn.c.update">
+
+ <indexterm>
+ <primary>svn</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>update</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svn update</refname>
<refpurpose>Update your working copy.</refpurpose>
@@ -5328,6 +5545,13 @@
<title><command>svnadmin</command> Subcommands</title>
<refentry id="svn.ref.svnadmin.c.create">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>create</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin create</refname>
<refpurpose>Create a new, empty repository.</refpurpose>
@@ -5384,6 +5608,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.deltify">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>deltify</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin deltify</refname>
<refpurpose>Deltify changed paths in a revision range.</refpurpose>
@@ -5417,6 +5648,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.dump">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>dump</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin dump</refname>
<refpurpose>Dump the contents of filesystem to stdout.</refpurpose>
@@ -5520,6 +5758,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.help">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>help</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin help</refname> <refpurpose>Help!</refpurpose>
</refnamediv>
@@ -5545,6 +5790,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.hotcopy">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>hotcopy</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin hotcopy</refname>
<refpurpose>Make a hot copy of a repository.</refpurpose>
@@ -5580,6 +5832,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.list-dblogs">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>list-dblogs</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin list-dblogs</refname> <refpurpose>Ask
Berkeley DB which log files exist for a given Subversion
@@ -5606,6 +5865,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.list-unused-dblogs">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>list-unused-dblogs</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin list-unused-dblogs</refname>
<refpurpose>Ask Berkeley DB which log files can be safely
@@ -5648,6 +5914,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.load">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>load</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin load</refname> <refpurpose>Read a
<quote>dumpfile</quote>-formatted stream from
@@ -5707,6 +5980,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.lslocks">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>lslocks</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin lslocks</refname>
<refpurpose>Print descriptions of all locks.</refpurpose>
@@ -5748,6 +6028,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.lstxns">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>lstxns</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin lstxns</refname>
<refpurpose>Print the names of all uncommitted transactions.</refpurpose>
@@ -5781,6 +6068,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.recover">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>recover</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin recover</refname>
@@ -5856,6 +6150,13 @@
<refentry id="svn.ref.svnadmin.c.rmlocks">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>rmlocks</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin rmlocks</refname>
<refpurpose>Unconditionally remove one or more locks from a
@@ -5895,6 +6196,13 @@
<refentry id="svn.ref.svnadmin.c.rmtxns">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>rmtxns</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin rmtxns</refname>
<refpurpose>Delete transactions from a repository.</refpurpose>
@@ -5943,6 +6251,13 @@
<refentry id="svn.ref.svnadmin.c.setlog">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>setlog</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin setlog</refname>
<refpurpose>Set the log-message on a revision.</refpurpose>
@@ -5996,6 +6311,13 @@
</refentry>
<refentry id="svn.ref.svnadmin.c.verify">
+
+ <indexterm>
+ <primary>svnadmin</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>verify</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnadmin verify</refname>
<refpurpose>Verify the data stored in the repository.</refpurpose>
@@ -6124,6 +6446,13 @@
<title><command>svnlook</command></title>
<refentry id="svn.ref.svnlook.c.author">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>author</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook author</refname>
<refpurpose>Print the author.</refpurpose>
@@ -6163,6 +6492,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.cat">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>cat</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook cat</refname>
<refpurpose>Print the contents of a file.</refpurpose>
@@ -6214,6 +6550,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.changed">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>changed</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook changed</refname>
<refpurpose>Print the paths that were changed.</refpurpose>
@@ -6306,6 +6649,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.date">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>date</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook date</refname>
<refpurpose>Print the datestamp.</refpurpose>
@@ -6345,6 +6695,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.diff">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>diff</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook diff</refname>
<refpurpose>Print differences of changed files and properties.</refpurpose>
@@ -6409,6 +6766,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.dirs-changed">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>dirs-changed</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook dirs-changed</refname>
<refpurpose>Print the directories that were themselves changed.</refpurpose>
@@ -6449,6 +6813,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.help">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>help</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook help</refname> <refpurpose>Help!</refpurpose>
</refnamediv>
@@ -6473,6 +6844,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.history">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>history</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook history</refname>
<refpurpose>Print information about the history of a path in
@@ -6531,6 +6909,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.info">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>info</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook info</refname>
<refpurpose>Print the author, datestamp, log message size,
@@ -6575,6 +6960,13 @@
<refentry id="svn.ref.svnlook.c.lock">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>lock</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook lock</refname>
<refpurpose>If a lock exists on a path in the repository,
@@ -6620,6 +7012,13 @@
<refentry id="svn.ref.svnlook.c.log">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>log</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook log</refname>
<refpurpose>Print the log message.</refpurpose>
@@ -6658,6 +7057,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.propget">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>propget</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook propget</refname>
<refpurpose>Print the raw value of a property on a path in
@@ -6706,6 +7112,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.proplist">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>proplist</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook proplist</refname>
<refpurpose>Print the names and values of versioned file and
@@ -6765,6 +7178,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.tree">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>tree</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook tree</refname>
<refpurpose>Print the tree.</refpurpose>
@@ -6812,6 +7232,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.uuid">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>uuid</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook uuid</refname>
<refpurpose>Print the repository's
@@ -6844,6 +7271,13 @@
</refentry>
<refentry id="svn.ref.svnlook.c.youngest">
+
+ <indexterm>
+ <primary>svnlook</primary>
+ <secondary>subcommands</secondary>
+ <tertiary>youngest</tertiary>
+ </indexterm>
+
<refnamediv>
<refname>svnlook youngest</refname>
<refpurpose>Print the youngest revision number.</refpurpose>
@@ -7043,6 +7477,11 @@
<title><command>svnversion</command></title>
<refentry id="svn.ref.svnversion.re">
+
+ <indexterm>
+ <primary>svnversion</primary>
+ </indexterm>
+
<refnamediv>
<refname>svnversion</refname>
<refpurpose>Summarize the local revision(s) of a working
Modified: trunk/src/ru/sync.py
==============================================================================
--- trunk/src/ru/sync.py (original)
+++ trunk/src/ru/sync.py Fri Jun 29 13:24:49 2007
@@ -99,7 +99,7 @@
elif o == '-u':
return update_status_file()
os.popen('mkdir book'+os.sep+'working')
- os.system('cp book/*xml book/working')
+ os.system('cp book/*.xml book/working')
cmd = string.Template(
'svn $a -r $r1:$r2 http://svn.red-bean.com/svnbook/trunk/src/en/book/$t')
print ('########################################################################')
More information about the svnbook-dev
mailing list