[svnbook commit] r1738 - trunk/src/zh/book
rocksun
svnbook-dev at red-bean.com
Sun Oct 16 23:03:16 CDT 2005
Author: rocksun
Date: Sun Oct 16 23:03:14 2005
New Revision: 1738
Modified:
trunk/src/zh/book/ch05.xml
Log:
* zh/book/ch05.xml modified by Jerry
Modified: trunk/src/zh/book/ch05.xml
==============================================================================
--- trunk/src/zh/book/ch05.xml (original)
+++ trunk/src/zh/book/ch05.xml Sun Oct 16 23:03:14 2005
@@ -1,1431 +1,1073 @@
-<chapter id="svn-ch-5">
-<title>Repository Administration</title>
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="svn-ch-5">
+ <title>资料库管理</title>
<simplesect>
+ <para>Subversion的资料库是任意数量项目受版本控制数据的中央仓库。正因如此,它成为管理员关注的焦点。资料库一般并不需要太多的照顾,但为了避免一些潜在的问题和解决一些实际问题,理解怎样适当的配置和维护还是很必要。</para>
- <para>The Subversion repository is the central storehouse of
- versioned data for any number of projects. As such, it becomes
- an obvious candidate for all the love and attention an
- administrator can offer. While the repository is generally a
- low-maintenance item, it is important to understand how to
- properly configure and care for it so that potential problems
- are avoided, and actual problems are safely resolved.</para>
-
- <para>In this chapter, we'll discuss how to create and configure
- a Subversion repository. We'll also talk about repository
- maintenance, including the use of the <command>svnlook</command>
- and <command>svnadmin</command> tools (which are provided with
- Subversion). We'll address some common questions and mistakes,
- and give some suggestions on how to arrange the data in the
- repository.</para>
-
- <para>If you plan to access a Subversion repository only in the
- role of a user whose data is under version control (that is, via
- a Subversion client), you can skip this chapter altogether.
- However, if you are, or wish to become, a Subversion repository
- administrator,
- <footnote>
- <para>This may sound really prestigious and lofty, but we're
- just talking about anyone who is interested in that
- mysterious realm beyond the working copy where everyone's
- data hangs out.</para>
- </footnote>
- you should definitely pay attention to this chapter.</para>
+ <para>在这一章里,我们将讨论如何建立和配置一个Subversion资料库,还会讨论资料库的维护,包括<command>svnlook</command>和<command>svnadmin</command>工具的使用(它们都包含在Subversion中)。我们将说明一些通常的问题和错误,并提供一些安排资料库数据的建议。</para>
+ <para>如果您只是以普通用户的身份访问资料库对数据进行版本控制(就是说通过Subversion客户端),您完全可以跳过本章。但是如果您已经是或打算成为Subversion资料库的管理员,您一定要关注一下本章的内容。<footnote>
+ <para>这些可能听起来很高深, 但我们所说的只是针对管理别人工作数据这块神秘领域感兴趣的人。</para>
+ </footnote></para>
</simplesect>
<!-- ******************************************************************* -->
- <!-- *** SECTION 1: REPOSITORY BASICS *** -->
+
+ <!-- *** 第一部分: 资料库基本知识 *** -->
+
<!-- ******************************************************************* -->
+
<sect1 id="svn-ch-5-sect-1">
- <title>Repository Basics</title>
+ <title>资料库基本知识</title>
- <para>Before jumping into the broader topic of repository
- administration, let's further define what a repository is. How
- does it look? How does it feel? Does it take its tea hot or
- iced, sweetened, and with lemon? As an administrator, you'll be
- expected to understand the composition of a repository both from
- a logical perspective—dealing with how data is represented
- inside the repository—and from a physical nuts-and-bolts
- perspective—how a repository looks and acts with respect
- to non-Subversion tools. The following section covers some of
- these basic concepts at a very high level.</para>
+ <para>在进入资料库管理这块宽广的领域之前,让我们进一步确定一下资料库的定义。它看起来什么样?让人有什么感觉?它喜欢喝热茶还是冰的?加糖吗?加柠檬吗?作为一名管理员,你应该既从逻辑表现-数据在资料库中如何展示,又从物理具体细节-资料库如何响应一个非Subversion的工具,来理解资料库的组成。下面部分从一个比较高的层面覆盖了这些基本概念。</para>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-1.1">
- <title>Understanding Transactions and Revisions</title>
-
- <para>Conceptually speaking, a Subversion repository is a
- sequence of directory trees. Each tree is a snapshot of how
- the files and directories versioned in your repository looked
- at some point in time. These snapshots are created as a
- result of client operations, and are called revisions.</para>
-
- <para>Every revision begins life as a transaction tree. When
- doing a commit, a client builds a Subversion transaction that
- mirrors their local changes (plus any additional changes that
- might have been made to the repository since the beginning of
- the client's commit process), and then instructs the
- repository to store that tree as the next snapshot in the
- sequence. If the commit succeeds, the transaction is
- effectively promoted into a new revision tree, and is assigned
- a new revision number. If the commit fails for some reason,
- the transaction is destroyed and the client is informed of the
- failure.</para>
-
- <para>Updates work in a similar way. The client builds a
- temporary transaction tree that mirrors the state of the
- working copy. The repository then compares that transaction
- tree with the revision tree at the requested revision (usually
- the most recent, or <quote>youngest</quote> tree), and sends
- back information that informs the client about what changes
- are needed to transform their working copy into a replica of
- that revision tree. After the update completes, the temporary
- transaction is deleted.</para>
-
- <para>The use of transaction trees is the only way to make
- permanent changes to a repository's versioned filesystem.
- However, it's important to understand that the lifetime of a
- transaction is completely flexible. In the case of updates,
- transactions are temporary trees that are immediately
- destroyed. In the case of commits, transactions are
- transformed into permanent revisions (or removed if the commit
- fails). In the case of an error or bug, it's possible that a
- transaction can be accidentally left lying around in the
- repository (not really affecting anything, but still taking up
- space).</para>
-
- <para>In theory, someday whole workflow applications might
- revolve around more fine-grained control of transaction
- lifetime. It is feasible to imagine a system whereby each
- transaction slated to become a revision is left in stasis well
- after the client finishes describing its changes to
- repository. This would enable each new commit to be reviewed
- by someone else, perhaps a manager or engineering QA team, who
- can choose to promote the transaction into a revision, or
- abort it.</para>
-
+ <title>了解事务和修订版</title>
+
+ <para>从概念上来说,Subversion的资料库就是一串目录树。每一个目录树,就是资料库的文件和目录在某一时间点的快照。这些快照是客户端使用者操作的结果,被成为修订版。</para>
+
+ <para>每一个修订版都是以事务树开始其生命周期。做提交操作时,客户端建立一个一个Subversion事务,映射本地的变更(加上客户端提交操作后任何对资料库的更改),然后通知资料库将该树存储为下一个快照。如果提交成功,这个事务就会成为新的修订版树,并被赋予新的修订版号。如果因为某些原因提交失败,事务会被销毁,客户端将被通知这个事务失败。</para>
+
+ <para>更新的动作也类似这样。客户端建立一个临时的事务树,映射工作文件的状态。然后资料库比较事务树和被请求的修订版树(通常是最新的,也就是最“年轻”的修订版树),然后发回消息通知客户端哪些变更需要将拷贝发送到修订版树。更新完成后,临时事务将被删除。</para>
+
+ <para>事务树的使用,是对资料库中版本控制文件系统产生永久变更的唯一方法。一个事务的生命周期非常灵活,了解这一点很重要。在更新的情况下,事务只是马上会被销毁的临时树。在提交的情况下,事务会变成固定的修订版(如果失败的情况下,则会被删除)。在出现错误或臭虫的情况下,事务可能会被留在资料库中(不会影响任何东西,但是会占据空间)。</para>
+
+ <para>理论上,某天整个流程能够发展到对事务的流程控制更加细密。可以想象一个系统,在客户端完成操作,将要保存到资料库中时,每个加到它的事务都变成一个修订版。这将会使每一个新的提交都可以被别人查看到,也许是主管,也许是质量保证小组,他们可以决定是要接收这个事务成为修订版,还是放弃它。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-1.2">
- <title>Unversioned Properties</title>
+ <title>未受版本控制的属性</title>
+
+ <para>事务和修订版在Subversion资料库中可以附加属性。这些属性通常是属性名和属性值的映射,被用来存储与对应档案树有关的信息。这些属性名和属性值跟你的其他数据一样,被存储在资料库文件系统中。</para>
- <para>Transactions and revisions in the Subversion repository
- can have properties attached to them. These properties are
- generic key-to-value mappings, and are generally used to store
- information about the tree to which they are attached. The
- names and values of these properties are stored in the
- repository's filesystem, along with the rest of your tree
- data.</para>
-
- <para>Revision and transaction properties are useful for
- associating information with a tree that is not strictly
- related to the files and directories in that tree—the
- kind of information that isn't managed by client working
- copies. For example, when a new commit transaction is created
- in the repository, Subversion adds a property to that
- transaction named <literal>svn:date</literal>—a
- datestamp representing the time that the transaction was
- created. By the time the commit process is finished, and the
- transaction is promoted to a permanent revision, the tree has
- also been given a property to store the username of the
- revision's author (<literal>svn:author</literal>) and a
- property to store the log message attached to that revision
- (<literal>svn:log</literal>).</para>
-
- <para>Revision and transaction properties are
- <firstterm>unversioned properties</firstterm>—as they
- are modified, their previous values are permanently discarded.
- Also, while revision trees themselves are immutable, the
- properties attached to those trees are not. You can add,
- remove, and modify revision properties at any time in the
- future. If you commit a new revision and later realize that
- you had some misinformation or spelling error in your log
- message, you can simply replace the value of the
- <literal>svn:log</literal> property with a new, corrected log
- message.</para>
+ <para>修订版和事务的属性对于跟一个资料树相关,但不是完全与这些目录和文件相关的性质很有用-即并不被客户端工作拷贝所管理的属性。举例来说,当一个新的提交事务在资料库中被创建时,Subversion给这个事务添加一个叫做<literal>svn:date</literal>的属性—一个表示事务何时被创建的时间戳。当提交进程结束,该事务成为一个固定的版本,这个档案树被赋予一个用来存储这个版本作者的用户名属性(<literal>svn:author</literal>)和一个用来存储与这个修订版关联的日志信息的属性(<literal>svn:log</literal>)。</para>
+ <para>修订版和事务的属性都是未受版本控制的-因为当它们被修改时,先前的值就被完全舍弃了。修订版树自身是不能变更的,与之关联的属性可以修改。你可在日后添加、删除、修改修订版的属性。如果你提交一个新的修订版之后意识到遗漏了一些信息或在日志中有拼写错误,你可以直接以正确的信息覆盖<literal>svn:log</literal>的值。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-1.3">
- <title>Repository Data-Stores</title>
+ <title>资料库数据存储</title>
+
+ <para>在Subversion1.1中,有两种方式在资料库中存储数据。一种是在BerkeleyDB数据库中存储数据;另一种是使用通常的格式,在文件中存储。因为Subversion的开发者称资料库为“版本化的文件系统”,他们接受了称后一种存储方式为FSFS,即使用本地操作系统文件系统来存储数据的版本化文件系统的习惯。</para>
- <para>As of Subversion 1.1, there are two options for storing
- data in a Subversion repository. One type of repository
- stores everything in a Berkeley DB database; the other kind
- stores data in ordinary flat files, using a custom
- format. Because Subversion developers often refer to a
- repository as <quote>The [Versioned] Filesystem</quote>, they have
- adopted the habit of referring to the latter type of repository as
- <firstterm>FSFS</firstterm>: that is, it's a versioned
- filesystem implementation that uses the native OS filesystem
- to store data.</para>
-
- <para>When a repository is created, an administrator must decide
- whether it will use Berkeley DB or FSFS. There are advantages
- and disadvantages to each, which we'll describe in a bit.
- Neither back-end is more <quote>official</quote> than another,
- and programs which access the repository are insulated from
- this implementation detail. Programs have no idea how a
- repository is storing data; they only see revision and
- transaction trees through the repository API.</para>
-
- <para>Here is a table that gives a comparative overview of
- Berkeley DB and FSFS repositories. The next sections go into
- detail.</para>
+ <para>建立一个资料库时,管理员必须决定使用BerkeleyDB还是FSFS。他们各有优缺点,我们将描述一下。它们任何一个都不比另一个更正式,访问资料库的程序与采用哪一种实现方式无关。访问程序并不知道资料库如何存储数据,它们只是从资料库的API读取到修订版和事务树。</para>
+
+ <para>下面的表从总体上比较了 Berkeley DB 和 FSFS 资料库。 下一部分将会详细讲述细节。</para>
<table id="svn-ch-5-table-1">
- <title>Repository Data-Store Comparison</title>
+ <title>资料库数据存储对照表</title>
+
<tgroup cols="3">
<thead>
<row>
- <entry>Feature</entry>
+ <entry>特性</entry>
+
<entry>Berkeley DB</entry>
+
<entry>FSFS</entry>
</row>
</thead>
+
<tbody>
<row>
- <entry>Sensitivity to interruptions</entry>
-
- <entry>very; crashes and permission problems can leave the
- database <quote>wedged</quote>, requiring journaled
- recovery procedures.</entry>
-
- <entry>quite insensitive.</entry>
+ <entry>对操作中断的敏感</entry>
+
+ <entry>很敏感;crashes and permission problems can leave the
+ database <quote>wedged</quote>, requiring journaled recovery
+ procedures。</entry>
+
+ <entry>不敏感。</entry>
</row>
-
+
<row>
- <entry>Usable from a read-only mount</entry>
-
- <entry>no</entry>
-
- <entry>yes</entry>
+ <entry>可只读加载</entry>
+
+ <entry>不能</entry>
+
+ <entry>可以</entry>
</row>
-
+
<row>
- <entry>Platform-independent storage</entry>
-
- <entry>no</entry>
-
- <entry>yes</entry>
+ <entry>存储平台无关</entry>
+
+ <entry>不能</entry>
+
+ <entry>可以</entry>
</row>
-
+
<row>
- <entry>Usable over network filesystems</entry>
-
- <entry>no</entry>
-
- <entry>yes</entry>
+ <entry>可从网络文件系统访问</entry>
+
+ <entry>不能</entry>
+
+ <entry>可以</entry>
</row>
-
+
<row>
- <entry>Repository size</entry>
-
- <entry>slightly larger</entry>
-
- <entry>slightly smaller</entry>
+ <entry>资料库大小</entry>
+
+ <entry>稍大</entry>
+
+ <entry>稍小</entry>
</row>
<row>
- <entry>Scalability: number of revision trees</entry>
-
- <entry>database; no problems</entry>
-
+ <entry>可量测性: 修订版树数量限制</entry>
+
+ <entry>数据库; 没有限制</entry>
+
<entry>some older native filesystems don't scale well with
- thousands of entries in a single directory.</entry>
+ thousands of entries in a single directory。</entry>
</row>
<row>
- <entry>Scalability: directories with many files</entry>
-
- <entry>slower</entry>
-
- <entry>faster</entry>
+ <entry>可量测性: directories with many files</entry>
+
+ <entry>较慢</entry>
+
+ <entry>较快</entry>
</row>
-
+
<row>
- <entry>Speed: checking out latest code</entry>
-
- <entry>faster</entry>
-
- <entry>slower</entry>
+ <entry>速度:检出最新的代码</entry>
+
+ <entry>较快</entry>
+
+ <entry>较慢</entry>
</row>
-
+
<row>
- <entry>Speed: large commits</entry>
-
- <entry>slower, but work is spread throughout commit</entry>
-
- <entry>faster, but finalization delay may cause client
- timeouts</entry>
+ <entry>速度: 大的提交</entry>
+
+ <entry>较慢, but work is spread throughout commit</entry>
+
+ <entry>较快, but finalization delay may cause client
+ timeouts</entry>
</row>
-
+
<row>
- <entry>Group permissions handling</entry>
-
- <entry>sensitive to user umask problems; best if accessed
- by only one user.</entry>
-
+ <entry>组访问权处理</entry>
+
+ <entry>sensitive to user umask problems; best if accessed by
+ only one user。</entry>
+
<entry>works around umask problems</entry>
</row>
<row>
- <entry>Code maturity</entry>
-
- <entry>in use since 2001</entry>
-
- <entry>in use since 2004</entry>
- </row>
+ <entry>功能成熟时间</entry>
+
+ <entry>2001年开始使用</entry>
+ <entry>2004年开始使用</entry>
+ </row>
</tbody>
- </tgroup>
+ </tgroup>
</table>
-
- <!-- ***************************************************************** -->
+
+ <!-- *****************************************************************-->
+
<sect3 id="svn-ch-5-sect-1.3.1">
<title>Berkeley DB</title>
-
- <para>When the initial design phase of Subversion was in
- progress, the developers decided to use Berkeley DB for a
- variety of reasons, including its open-source license,
- transaction support, reliability, performance, API
- simplicity, thread-safety, support for cursors, and so
- on.</para>
-
- <para>Berkeley DB provides real transaction
- support—perhaps its most powerful feature. Multiple
- processes accessing your Subversion repositories don't have
- to worry about accidentally clobbering each other's data.
- The isolation provided by the transaction system is such
- that for any given operation, the Subversion repository code
- sees a static view of the database—not a database that
- is constantly changing at the hand of some other
- process—and can make decisions based on that view. If
- the decision made happens to conflict with what another
- process is doing, the entire operation is rolled back as if
- it never happened, and Subversion gracefully retries the
- operation against a new, updated (and yet still static) view
- of the database.</para>
-
- <para>Another great feature of Berkeley DB is <firstterm>hot
- backups</firstterm>—the ability to backup the database
- environment without taking it <quote>offline</quote>. We'll
- discuss how to backup your repository in <xref
- linkend="svn-ch-5-sect-3.6"/>, but the benefits of being
- able to make fully functional copies of your repositories
- without any downtime should be obvious.</para>
-
- <para>Berkeley DB is also a very reliable database system.
- Subversion uses Berkeley DB's logging facilities, which
- means that the database first writes to on-disk log files a
- description of any modifications it is about to make, and
- then makes the modification itself. This is to ensure that
- if anything goes wrong, the database system can back up to
- a previous <firstterm>checkpoint</firstterm>—a
- location in the log files known not to be corrupt—and
- replay transactions until the data is restored to a usable
- state. See <xref linkend="svn-ch-5-sect-3.3"/> for more
- about Berkeley DB log files.</para>
-
- <para>But every rose has its thorn, and so we must note some
- known limitations of Berkeley DB. First, Berkeley DB
- environments are not portable. You cannot simply copy a
- Subversion repository that was created on a Unix system onto
- a Windows system and expect it to work. While much of the
- Berkeley DB database format is architecture independent,
- there are other aspects of the environment that are not.
- Secondly, Subversion uses Berkeley DB in a way that will not
- operate on Windows 95/98 systems—if you need to house
- a repository on a Windows machine, stick with Windows 2000
- or Windows XP. Also, you should never keep a Berkeley DB
- repository on a network share. While Berkeley DB promises
- to behave correctly on network shares that meet a particular
- set of specifications, almost no known shares actually meet
- all those specifications.</para>
-
- <para>Finally, because Berkeley DB is a library linked
- directly into Subversion, it's more sensitive to
- interruptions than a typical relational database system.
- Most SQL systems, for example, have a dedicated server
- process that mediates all access to tables. If a program
- accessing the database crashes for some reason, the database
- daemon notices the lost connection and clean up any mess
- left behind. And because the database daemon is the only
- process accessing the tables, applications don't need to
- worry about permission conflicts. These things are not the
- case with Berkeley DB, however. Subversion (and programs
- using Subversion libraries) access the database tables
- directly, which means that a program crash can leave the
- database in a temporarily inconsistent, inaccessible state.
- When this happens, an administrator needs to ask Berkeley DB
- to restore to a checkpoint, which is a bit of an annoyance.
- Other things can cause a repository to <quote>wedge</quote>
- besides crashed processes, such as programs conflicting over
- ownership and permissions on the database files. So while a
- BerkeleyDB repository is quite fast and scalable, it's best
- used by a single server process running as one
- user—such as Apache's <command>httpd</command> or
- <command>svnserve</command> (see <xref
- linkend="svn-ch-6"/>)—rather than accessing it as
- many different users via <literal>file:///</literal> or
- <literal>svn+ssh://</literal> URLs. If using a Berkeley DB
- repository directly as multiple users, be sure to read <xref
- linkend="svn-ch-6-sect-5"/>.</para>
+ <para>在Subversion的初始设计阶段,开发者因为多种原因而决定采用Berkeley
+ DB,比如它的开源协议、事务支持、可靠性、性能、简单的API、线程安全、支持游标等。</para>
+
+ <para>BerkeleyDB提供了真正的事务支持-这或许是它最强大的特性。访问你的Subversion资料库的多个进程不必担心偶尔会破坏其他进程的数据。事务系统提供的隔离对于任何给定的操作,Subversion资料库代码看到的只是数据库的静态剪影-而不是一个受其他进程影响不断变化的情况-并能够根据该静态剪影作出操作决定。如果该操作决定正好同其他进程所做操作冲突,整个操作会会滚,就像什么都没有发生一样。然后Subversion优雅的使用一个更新的静态剪影重新开始操作。</para>
+
+ <para>BerkeleyDB另一个强大的特性是热备份-不必“下线”就可以备份数据库环境的能力。我们将会在<xref
+ linkend="svn-ch-5-sect-3.6" />讨论如何备份你的资料库,能够不停止系统对资料库做全面备份的好处是显而易见的。</para>
+
+ <para>BerkeleyDB同时是一个可信赖的数据库系统。Subversion使用BerkeleyDB的日志工具,这意味着数据库先在磁盘上写一个日志文件,描述它将要做的修改,然后再做这些修改。这是为了确保如果哪里除了差错,数据库系统能回复到先前的检出点-一个在日志文件中已知的不会冲突的位置,重新开始事务直到数据存储成为一个可用的状态。更多关于BerkeleyDB日志文件的信息请查看<xref
+ linkend="svn-ch-5-sect-3.3" />。</para>
+
+ <para>每朵玫瑰都有刺,我们也必须记录一些BerkeleyDB已知的缺陷。首先,BerkeleyDB环境不是跨平台的。你不能简单的拷贝一个创建在Unix上的Subversion资料库到一个Windows系统,也无法期望创建在Unix系统上的资料库能顺利移植到Windows系统正常运行。尽管BerkeleyDB数据库格式架构设计独立,有一些其他环境方面没有独立出来。其次,Subversion使用BerkeleyDB不能在95/98系统上运行-如果你需要将资料库建在一个Windows机器上,请装到Windows2000或WindowsXP上。另外,不要在网络上共享BerkeleyDB资料库。尽管BerkeleyDB承诺如果按照一套特定规范的话,可以在网络共享上正常运行,但实际上已知的共享类型几乎都不满足这套规范。</para>
+
+ <para>最后,因为BerkeleyDB是以连接库的形式被Subversion使用,它对于中断比典型的关系型数据库系统更为敏感。大多数SQL系统,举例来说,有一个主服务进程来协调对数据库表的访问。如果一个访问数据库的程序因为某种原因出现问题,数据库守护进程察觉到连接中断会做一些清理。因为数据库守护进程是唯一访问数据库表的进程,应用程序不需要担心访问许可的冲突。但是,这些情况与BerkeleyDB不同。Subversion(和使用Subversion库的程序)直接访问数据库的表,这意味着如果有一个程序崩溃,就会使数据库处于一个暂时的不一致、不可访问的状态。当这种情况发生时,管理员需要让BerkeleyDB回复到一个检查点,这的确有点讨厌。除了崩溃的进程,还有一些情况能让资料库出现异常,比如程序在所有权上发生冲突或者数据库文件的访问权限。BerkeleyDB资料库非常快,还可以升级,不过最好使用一个单独的服务进程,通过一个用户来访问-比如Apache的<command>httpd</command>或<command>svnserve</command>(参见<xref
+ linkend="svn-ch-6" />)—而不是多用户通过<literal>file:///</literal>或<literal>svn+ssh://</literal>URL的方式多用户访问。如果将BerkeleyDB资料库直接用作多用户访问,请先阅读<xref
+ linkend="svn-ch-6-sect-5" />。</para>
</sect3>
-
- <!-- ***************************************************************** -->
+
+ <!-- ***************************************************************** -->
+
<sect3 id="svn-ch-5-sect-1.3.2">
<title>FSFS</title>
- <para>In mid-2004, a second type of repository storage system
- came into being: one which doesn't use a database at all.
- An FSFS repository stores a revision tree in a single file,
- and so all of a repository's revisions can be found in a
- single subdirectory full of numbered files. Transactions
- are created in separate subdirectories. When complete, a
- single transaction file is created and moved to the
- revisions directory, thus guaranteeing that commits are
- atomic. And because a revision file is permanent and
- unchanging, the repository also can be backed up while
- <quote>hot</quote>, just like a Berkeley DB repository.</para>
-
- <para>The revision-file format represents a revision's
- directory structure, file contents, and deltas against files
- in other revision trees. Unlike a Berkeley DB database,
- this storage format is portable across different operating
- systems and isn't sensitive to CPU architecture. Because
- there's no journaling or shared-memory files being used, the
- repository can be safely accessed over a network filesystem
- and examined in a read-only environment. The lack of
- database overhead also means that the overall repository
- size is a bit smaller.</para>
-
- <para>FSFS has different performance characteristics too.
- When committing a directory with a huge number of files, FSFS
- uses an O(N) algorithm to append entries, while Berkeley DB
- uses an O(N^2) algorithm to rewrite the whole directory. On
- the other hand, FSFS writes the latest version of a file as
- a delta against an earlier version, which means that
- checking out the latest tree is a bit slower than fetching
- the fulltexts stored in a Berkeley DB HEAD revision. FSFS
- also has a longer delay when finalizing a commit, which
- could in extreme cases cause clients to time-out when
- waiting for a response.</para>
-
- <para>The most important distinction, however, is FSFS's
- inability to be <quote>wedged</quote> when something goes
- wrong. If a process using a Berkeley DB database runs into
- a permissions problem or suddenly crashes, the database is
- left unusable until an administrator recovers it. If the
- same scenarios happen to a process using an FSFS repository,
- the repository isn't affected at all. At worst, some
- transaction data is left behind.</para>
-
- <para>The only real argument against FSFS is its relative
- immaturity compared to Berkeley DB. It hasn't been used or
- stress-tested nearly as much, and so a lot of these
- assertions about speed and scalability are just that:
- assertions, based on good guesses. In theory, it promises a
- lower barrier to entry for new administrators and is less
- susceptible to problems. In practice, only time will
- tell.</para>
+ <para>在2004年中期,另一种资料库存储系统慢慢形成了:一种不需要数据库的存储系统。FSFS资料库在一个文件中存储修订版树,所以资料库中所有的修订版都在一个子文件夹中有限的几个文件里。事务在单独的子目录中被创建,创建完成后,一个单独的事务文件被创建并移动到修订版目录,这保证提交是原子性的。因为一个修订版文件是持久不可改变的,资料库也可以做到热备份,就象BerkeleyDB资料库一样。</para>
+
+ <para>修订版文件格式代表了一个修订版的目录结构,文件内容,和其他修订版树中相关信息。
+ 不像BerkeleyDB数据库,这种存储格式可跨平台并且与CPU架构无关。因为没有日志或用到共享内存的文件,数据库能被网络文件系统安全的</para>
+
+ <para>访问和检查只读环境。缺少数据库花消同时也意味着资料库的总体体积可以稍小一点。</para>
+
+ <para>FSFS也有一种不同的表现属性。当确定大量文件的存贮目录是,FSFS用O(N) 算法来填加入口,而
+ Berkeley数据库则用(N^2)算法来重写整个目录。另一方面,与较早版本相比FSFS将最近版本的文件当作delta写入,这也意味着与在头版本的</para>
+ <para>Berkeley数据库中获取整个文件相比检查最近的树会稍慢一点。当完成一个确认时,FSFS也会有一个更长的延迟,在某些极端情况下会导致</para>
+
+ <para>客护端在等待回应时超时。</para>
+
+ <para />
+
+ <para />
+
+ <para>最重要的区别是当出现错误时FSFS停滞不前。假如应用Berkeley处理时发生许可错误或突然崩溃系统,数据库会无法使用直到管理员</para>
+
+ <para>恢复。假如在应用FSFS资料库发生同样的情况,资料库不会受到任何干扰。在最坏情况下也仅仅是一些处理信息被丢弃。</para>
+
+ <para>唯一真正对FSFS不利的是它与Berkeley数据库相比相对不可靠。它没有接受用户的足够多的检验。仅在理论来说,它减少了新管理者的负担,</para>
+
+ <para>以及较少有疑问的问题。在实践中,也只有时间才能在评判。</para>
+
+ <para />
</sect3>
</sect2>
</sect1>
<!-- ******************************************************************* -->
- <!-- *** SECTION 2: REPOSITORY CREATION AND CONFIGURATION *** -->
+
+ <!-- *** 第二部分: 资料库创建和配置 *** -->
+
<!-- ******************************************************************* -->
+
<sect1 id="svn-ch-5-sect-2">
- <title>Repository Creation and Configuration</title>
+ <title>资料库的创建和配置</title>
+
+ <para>创建一个 Subversion 资料库出乎寻常的简单。 Subversion
+ 提供的<command>svnadmin</command> 工具,有一个执行这个功能的子命令。要建立一个新的资料库,只需要运行:</para>
- <para>Creating a Subversion repository is an incredibly simple
- task. The <command>svnadmin</command> utility, provided with
- Subversion, has a subcommand for doing just that. To create a
- new repository, just run:</para>
-
<screen>
$ svnadmin create /path/to/repos
</screen>
-
- <para>This creates a new repository in the directory
- <filename>/path/to/repos</filename>. This new repository begins
- life at revision 0, which is defined to consist of nothing but
- the top-level root (<filename>/</filename>) filesystem
- directory. Initially, revision 0 also has a single revision
- property, <literal>svn:date</literal>, set to the time at which
- the repository was created.</para>
-
- <para>In Subversion 1.1, a repository is created with a Berkeley
- DB back-end by default. This behavior may change in future
- releases. Regardless, the type can be explicitly chosen with
- the <option>--fs-type</option> argument:</para>
+
+ <para>这个命令在目录<filename>/path/to/repos</filename>创建了一个新的资料库。这个新的资料库会以修订版版本0开始其生命周期,里面除了最上层的根目录(<filename>/</filename>),什么都没有。刚开始,修订版0有一个修订版</para>
+
+ <para>属性<literal>svn:date</literal>,被设置为资料库创建的时间。</para>
+
+ <para>在 Subversion 1.1中,资料库默认使用Berkeley
+ DB后端存储方式来创建。在以后的发行版中这个行为会被改变。不管怎样,存储类型可以使用<option>--fs-type</option>
+ 参数显视的选择。:</para>
<screen>
$ svnadmin create --fs-type fsfs /path/to/repos
$ svnadmin create --fs-type bdb /path/to/other/repos
</screen>
-
<warning>
- <para>Do not create a Berkeley DB repository on a network
- share—it <emphasis>cannot</emphasis> exist on a remote
- filesystem such as NFS, AFS, or Windows SMB. Berkeley DB
- requires that the underlying filesystem implement strict POSIX
- locking semantics, and more importantly, the ability to map
- files directly into process memory. Almost no network
- filesystems provide these features. If you attempt to use
- Berkeley DB on a network share, the results are
- unpredictable—you may see mysterious errors right away,
- or it may be months before you discover that your repository
- database is subtly corrupted.</para>
-
- <para>If you need multiple computers to access the repository,
- you create an FSFS repository on the network share, not a
- Berkeley DB repository. Or better yet, set up a real server
- process (such as Apache or <command>svnserve</command>), store
- the repository on a local filesystem which the server can
- access, and make the repository available over a network.
- <xref linkend="svn-ch-6"/> covers this process in
- detail.</para>
+ <para>不要在网络共享上创建Berkeley DB资料库—它不能存在于诸如NFS, AFS, 或 Windows
+ SMB的远程文件系统中。Berkeley 数据要求底层文件系统实现严格的</para>
+
+ <para>POSIX语义锁定。几乎没有网络文件系统提供这些特征,假如你网络共享Berkeley数据库,结果是不可预知的——你当前发现的错误也许是几个月前的,你的资料库</para>
+
+ <para>也会相当脆弱。</para>
+
+ <para>假如你需要多台计算机来访问,你需要创造网络共享的FSFS资料库,而不是Berkeley数据库的资料库。或者更好的办法,你建立一个真正的服务方式(诸如Apache
+ 或
+ <command>svnserve),把资料库放在</command>服务器能访问到的本地文件系统中,以便能通过网络访问。详情请参看<xref
+ linkend="svn-ch-6" /></para>
</warning>
-
- <para>You may have noticed that the path argument to
- <command>svnadmin</command> was just a regular filesystem path
- and not a URL like the <command>svn</command> client program
- uses when referring to repositories. Both
- <command>svnadmin</command> and <command>svnlook</command> are
- considered server-side utilities—they are used on the
- machine where the repository resides to examine or modify
- aspects of the repository, and are in fact unable to perform
- tasks across a network. A common mistake made by Subversion
- newcomers is trying to pass URLs (even <quote>local</quote>
- <literal>file:</literal> ones) to these two programs.</para>
-
- <para>So, after you've run the <command>svnadmin create</command>
- command, you have a shiny new Subversion repository in its own
- directory. Let's take a peek at what is actually created inside
- that subdirectory.</para>
-
+
+ <para>你可能已经注意到了,<command>svnadmin</command>命令的路径参数只是一个规则的文件系统路径,而不是一个<command>svn</command>客户端程序访问资料库时使用的URL。<command>svnadmin</command>和<command>svnlook</command>都被认为是服务器端工具-</para>
+
+ <para>它们使用在资料库所在的机器上,被用来检查或修改资料库,不能通过网络来执行任务。一个Subversion的新手通常会犯的错误,就是试图将URL(甚至<quote>本地</quote><literal>file:</literal>路径)传给这两个程序。</para>
+
+ <para>所以,当你运行<command>svnadmin create</command>
+ 命令后,就在创建目录中有了一个全新的Subversion资料库。 让我们看一下在目录中实际都创建了什么东西。</para>
+
<screen>
$ ls repos
-conf/ dav/ db/ format hooks/ locks/ README.txt
+conf/ dav/ db/ format hooks/ locks/ README。txt
</screen>
-
- <para>With the exception of the <filename>README.txt</filename> and
- <filename>format</filename> files,
- the repository directory is a collection of subdirectories. As
- in other areas of the Subversion design, modularity is given
- high regard, and hierarchical organization is preferred to
- cluttered chaos. Here is a brief description of all of
- the items you see in your new repository directory:</para>
+
+ <para>除了<filename>README.txt</filename> 和 <filename>format</filename>
+ 文件,资料库目录由一群子目录组成。就像Subversion其他部分的设计一样,
+ 模块化是一个很重要的原则,而且层次化的组织要比杂乱无章好。下面是对新的资料库目录中,各个项目的简要介绍:</para>
<variablelist>
<varlistentry>
<term>conf</term>
+
<listitem>
- <para>A directory containing repository configuration files.</para>
+ <para>一个存储资料库配置文件的目录。</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>dav</term>
+
<listitem>
- <para>A directory provided to Apache and mod_dav_svn for
- their private housekeeping data.</para>
+ <para>提供给Apache和mod_dav_svn的目录,让它们存储自己的数据。</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>db</term>
+
<listitem>
- <para>Where all of your versioned data resides. This
- directory is either a Berkeley DB environment (full of DB
- tables and other things), or is an FSFS environment
- containing revision files.</para>
+ <para>你所有的受版本控制数据的所在之处。这个目录或者是个Berkeley DB
+ 环境(满是数据表和其他东西)或者是一个包含修订版文件的FSFS环境。</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>format</term>
+
<listitem>
- <para>A file whose contents are a single integer value that
- dictates the version number of the repository layout.</para>
+ <para>一个包含一个整数的文件,用来表示资料库配置的版本号码。</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>hooks</term>
+
<listitem>
- <para>A directory full of hook script templates (and hook
- scripts themselves, once you've installed some).</para>
+ <para>一个存储hook脚本模版的目录(还有 hook 脚本本身, 如果你安装了的话)。</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>locks</term>
+
<listitem>
- <para>A directory for Subversion's repository locking
- data, used for tracking accessors to the repository.</para>
+ <para>一个存储Subversion资料库锁定资料的目录,被用来追踪对资料库的访问。</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>README.txt</term>
+
<listitem>
- <para>A file which merely informs its readers that they
- are looking at a Subversion repository.</para>
+ <para>这个文件只是用来告诉它的阅读者,他现在看的是 Subversion 的资料库。</para>
</listitem>
</varlistentry>
</variablelist>
-
- <para>In general, you shouldn't tamper with your repository
- <quote>by hand</quote>. The <command>svnadmin</command> tool
- should be sufficient for any changes necessary to your
- repository, or you can look to third-party tools (such as
- Berkeley DB's tool suite) for tweaking relevant subsections of
- the repository. Some exceptions exist, though, and we'll cover
- those here.</para>
+
+ <para>一般来说,你不需要手动干预资料库。<command>svnadmin</command>工具应该足以用来处理对资料库的任何修改,或者你也可以使用第三方工具(比如BerkeleyDB的工具包)来调整部分资料库。不过还是会有些例外情况,我们会在这里提到。</para>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-2.1">
- <title>Hook Scripts</title>
+ <title>Hook 脚本</title>
+
+ <para>所谓hook的<firstterm>就是与一些资料库事件相关的程序,它有新 revision
+ 所创,或是无形式属性的变更。每个hook都携带有足够多的信息,说明那是什么事件,操作的对象,和触发事件的用户名。通过hook的输出或返回状态,hook程序能继续运行,停止或以某种方式挂起。</firstterm></para>
+
+ <para>
+ <firstterm>默认情况下,hook的子目录中包含各种资料库hook模板。</firstterm>
+ </para>
- <para>A <firstterm>hook</firstterm> is a program triggered by
- some repository event, such as the creation of a new revision
- or the modification of an unversioned property. Each hook is
- handed enough information to tell what that event is, what
- target(s) it's operating on, and the username of the person
- who triggered the event. Depending on the hook's output or
- return status, the hook program may continue the action, stop
- it, or suspend it in some way.</para>
-
- <para>The <filename>hooks</filename> subdirectory is, by
- default, filled with templates for various repository
- hooks.</para>
-
<screen>
$ ls repos/hooks/
-post-commit.tmpl pre-revprop-change.tmpl
-post-revprop-change.tmpl start-commit.tmpl
-pre-commit.tmpl
-</screen>
-
- <para>There is one template for each hook that the Subversion
- repository implements, and by examining the contents of those
- template scripts, you can see what triggers each such script
- to run and what data is passed to that script. Also present
- in many of these templates are examples of how one might use
- that script, in conjunction with other Subversion-supplied
- programs, to perform common useful tasks. To actually install
- a working hook, you need only place some executable program or
- script into the <filename>repos/hooks</filename> directory
- which can be executed as the name (like
- <command>start-commit</command> or
- <command>post-commit</command>) of the hook.</para>
-
- <para>On Unix platforms, this means supplying a script or
- program (which could be a shell script, a Python program, a
- compiled C binary, or any number of other things) named
- exactly like the name of the hook. Of course, the template
- files are present for more than just informational
- purposes—the easiest way to install a hook on Unix
- platforms is to simply copy the appropriate template file to a
- new file that lacks the <literal>.tmpl</literal> extension,
- customize the hook's contents, and ensure that the script is
- executable. Windows, however, uses file extensions to
- determine whether or not a program is executable, so you would
- need to supply a program whose basename is the name of the
- hook, and whose extension is one of the special extensions
- recognized by Windows for executable programs, such as
- <filename>.exe</filename> or <filename>.com</filename> for
- programs, and <filename>.bat</filename> for batch
- files.</para>
-
- <tip>
- <para>For security reasons, the Subversion repository executes
- hook scripts with an empty environment—that is, no
- environment variables are set at all, not even
- <literal>$PATH</literal> or <literal>%PATH%</literal>.
- Because of this, a lot of administrators are baffled when
- their hook script runs fine by hand, but doesn't work when run
- by Subversion. Be sure to explicitly set environment
- variables in your hook and/or use absolute paths to
- programs.</para>
- </tip>
+post-commit。tmpl pre-revprop-change。tmpl
+post-revprop-change。tmpl start-commit。tmpl
+pre-commit。tmpl
+</screen>
+
+ <para />
+
+ <para>对于每个hook的都有一个模板,该模版由Subversion资源库实现,由模版的脚本检查其内容,这样,你能看到脚本运行时所触发的事件及</para>
+
+ <para>传给脚本的数据。同时,一些模版当于Subversion所提供的程序合用,来完成有用的任务,也提供了模版如何使用脚本的例子。要实际安装一个可用的hook你需要在<filename>repos/hooks</filename></para>
+
+ <para>目录下安装一些与hook同名(如 <command>start-commit</command> or
+ <command>post-commit</command>)的能运行的程序或脚本。</para>
- <para>Currently there are five hooks implemented by the
- Subversion repository:</para>
+ <para>在Unix平台上,着是指提供一个与hook同名的脚本或程序(或者是个shell 脚本,Python 程序,
+ 编译过的c语言二进制文件, 或其东西) 。当然,脚本文件提供的信息不仅仅用来在Unix
+ 平台上简单的安装hook,或是把合适模版复制到正好缺少的该模版文件的模版文件中。tmpl的扩充,hook的客户化,都要确定脚本是可运行的。
+ Windows用文件的扩展名来决定一个程序是否可运行,所以你要使程序的基本名与hook同名,同时,它的扩展名是Windows系统所能辨认的,诸如<filename>exe</filename>
+ 或<filename>com</filename> 或<filename>批处理的bat。</filename></para>
+
+ <para>Tip 由于安全原因,Subversion资源库在一个“空”环境中执行hook脚本,这里所说的”空“是指没有任何环境变量,甚至
+ <literal>$PATH</literal> or <literal>%PATH%。</literal></para>
+
+ <para>由于这个原因,令很多管理者很困惑的是,他们的
+ hook脚本手工运行是很好,客在Subversion中却不能运行。要注意,必须在你的hook设置环境变量或为你的程序指定好绝对路径。</para>
+
+ <para>目前Subversion有五种已实现了的hook</para>
<variablelist>
<varlistentry>
- <term><filename>start-commit</filename></term>
+ <term>
+ <filename>start-commit</filename>
+ </term>
+
<listitem>
- <para>This is run before the commit transaction is even
- created. It is typically used to decide if the user has
- commit privileges at all. The repository passes two
- arguments to this program: the path to the repository,
- and username which is attempting the commit. If the
- program returns a non-zero exit value, the commit is
- stopped before the transaction is even created. If the
- hook program writes data to stderr, it will be
- marshalled back to the client.</para>
+ <para>它在commit
+ transaction产生前已运行。它通常用来决定用户进行了特权操作。资料库传给该程序两个变量:到资料库的路径,和要进行操作的用户名。假如程序返回一个非零</para>
+
+ <para>的exit value,在 transaction产生前停止该commit。假如hook
+ 程序要在stderr中写入数据,它将排队送至客户端。</para>
+
+ <para />
</listitem>
</varlistentry>
-
+
<varlistentry>
- <term><filename>pre-commit</filename></term>
+ <term>
+ <filename>pre-commit
+ 它在transaction完成但在commite前运行。通常,该hook用来保护那些由于内容或是地址不允许访问的commits(例如,你的site也许要求对一个确定的分支</filename>
+ </term>
+
<listitem>
- <para>This is run when the transaction is complete, but
- before it is committed. Typically, this hook is used to
- protect against commits that are disallowed due to
- content or location (for example, your site might
- require that all commits to a certain branch include a
- ticket number from the bug tracker, or that the incoming
- log message is non-empty). The repository passes two
- arguments to this program: the path to the repository,
- and the name of the transaction being committed. If the
- program returns a non-zero exit value, the commit is
- aborted and the transaction is removed. If the hook
- program writes data to stderr, it will be marshalled
- back to the client.</para>
-
- <para>The Subversion distribution includes some access
- control scripts (located in the
- <filename>tools/hook-scripts</filename> directory of the
- Subversion source tree) that can be called from
- <command>pre-commit</command> to implement fine-grained
- write-access control. Another option is to use the
- <command>mod_authz_svn</command> Apache httpd module,
- which provides both read and write access control on
- individual directories (see <xref
- linkend="svn-ch-6-sect-4.4.2"/>). In a future version
- of Subversion, we plan to implement access control lists
- (ACLs) directly in the filesystem.</para>
+ <para>的commits要包含从bug tracker中得到的icket number,或者ncoming
+ log是非空的)资料库传给程序两个变量:到资料库的路径和要进行操作的用户名。假如程序返回一个非零的exitvalue,commit应当取消,transaction应被删除。</para>
+
+ <para>假如hook 程序要在stderr中写入数据,它将排队送至客户端。</para>
+
+ <para>分布式Subversion有一些控制脚本(在Subversion的source
+ tree的tools/hook-scripts目录中)来在pre-commit中实现pre-commit。另外还有<command>mod_authz_svn</command>
+ Apache httpd可选模式,这可用来对个人目录进行读或写的控制。(详见<xref
+ linkend="svn-ch-6-sect-4.4.2" />)。在以后的Subversion中,我们可以实现在文件系统中直接的access
+ control。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><filename>post-commit</filename></term>
+ <term>
+ <filename>post-commit</filename>
+ </term>
+
<listitem>
- <para>This is run after the transaction is committed, and
- a new revision is created. Most people use this hook to
- send out descriptive emails about the commit or to make
- a backup of the repository. The repository passes two
- arguments to this program: the path to the repository,
- and the new revision number that was created. The exit
- code of the program is ignored.</para>
-
- <para>The Subversion distribution includes
- <command>mailer.py</command> and
- <command>commit-email.pl</command> scripts (located in
- the <filename>tools/hook-scripts/</filename> directory
- of the Subversion source tree) that can be used to send
- email with (and/or append to a log file) a description
- of a given commit. This mail contains a list of the
- paths that were changed, the log message attached to the
- commit, the author and date of the commit, as well as a
- GNU diff-style display of the changes made to the
- various versioned files as part of the commit.</para>
-
- <para>Another useful tool provided by Subversion is the
- <command>hot-backup.py</command> script (located in the
- <filename>tools/backup/</filename> directory of the
- Subversion source tree). This script performs hot
- backups of your Subversion repository (a feature
- supported by the Berkeley DB database back-end), and can
- be used to make a per-commit snapshot of your repository
- for archival or emergency recovery purposes.</para>
+ <para>它在ransaction完成后
+ transaction后运行,创建一个新的revision。大多数人用这个hook来发送关于运行的描述性emails,或者作为资源库的惫份。资源库资料库传给程序两个变量:到资料库</para>
+
+ <para>的路径和被创建的new revision
+ number。退出程序会被忽略。分布式Subversion包括<command>mailer,<command>py</command>
+ 和 <command>commit-email。<command>pl</command> 脚本(存于Subversion
+ source
+ tree中的tools/hook-scripts/目录中)可被用于发送给定操作的描述性email。这种mail包含</command></command>变化的路径清单,有关操作的信息日志,操作的日期和作者。</para>
+
+ <para>Subversion提供的另一个有用的工具是hot-backup。<command>py</command>
+ 脚本(在Subversion source
+ tree中的tools/backup/目录中)。这种脚本做为Subversion资料库的hot
+ backups使用,可被用来作为资料库的per-commit snapshot。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><filename>pre-revprop-change</filename></term>
+ <term>
+ <filename>pre-revprop-change</filename>
+ </term>
+
<listitem>
- <para>Because Subversion's revision properties are not
- versioned, making modifications to such a property (for
- example, the <literal>svn:log</literal> commit message
- property) will overwrite the previous value of that
- property forever. Since data can be potentially lost
- here, Subversion supplies this hook (and its
- counterpart, <filename>post-revprop-change</filename>)
- so that repository administrators can keep records of
- changes to these items using some external means if
- they so desire. As a precaution against losing
- unversioned property data, Subversion clients will not
- be allowed to remotely modify revision properties at all
- unless this hook is implemented for your repository.</para>
-
- <para>This hook runs just before such a modification is
- made to the repository. The repository passes four
- arguments to this hook: the path to the repository, the
- revision on which the to-be-modified property exists, the
- authenticated username of the person making the change,
- and the name of the property itself.</para>
+ <para />
+
+ <para>因为Subversion的revision不是versioned,这一属性的修改(例如,<literal>svn“执行信息日志属性)将会重写以前的属性值。因为数据在此可能丢失,Subversion提供了</literal></para>
+
+ <para><literal>这种hook(及它的类似物,post-revprop-change),资源库管理者可用一些外部方法保持变化记录。</literal>作为一种丢失unversioned属性数据的预先警告,Subversion</para>
+
+ <para>客户端不能远程修改revision属性,除非为你的资源库实现这个hook。</para>
+
+ <para>这个hook只在对资源库修改时才运行。资源库给hook传递四个参数:到资源库的路径,要修改的属性存在的revision,经过校验的生成变化的用户名,和属性自身的名字。</para>
+
+ <para />
</listitem>
</varlistentry>
<varlistentry>
- <term><filename>post-revprop-change</filename></term>
+ <term>
+ <filename>post-revprop-change</filename>
+ </term>
+
<listitem>
- <para>As mentioned earlier, this hook is the counterpart
- of the <filename>pre-revprop-change</filename> hook. In
- fact, for the sake of paranoia this script will not run
- unless the <filename>pre-revprop-change</filename> hook
- exists. When both of these hooks are present, the
- <filename>post-revprop-change</filename> hook runs just
- after a revision property has been changed, and is
- typically used to send an email containing the new value
- of the changed property. The repository passes four
- arguments to this hook: the path to the repository, the
- revision on which the property exists, the authenticated
- username of the person making the change, and the name of
- the property itself.</para>
-
- <para>The Subversion distribution includes a
- <command>propchange-email.pl</command> script (located
- in the <filename>tools/hook-scripts/</filename>
- directory of the Subversion source tree) that can be
- used to send email with (and/or append to a log file)
- the details of a revision property change. This mail
- contains the revision and name of the changed property,
- the user who made the change, and the new property
- value.</para>
+ <para>它是一个早期版本的方法,这个 hook是<filename>pre-revprop-change</filename>
+ hook的类似物。事实上,出于某种偏执这个脚本并不运行,除非存在<filename>pre-revprop-change</filename>
+ hook。当这两个hook都存在时,<filename>post-revprop-changehook只在revision资料库被改变时才运行,它通常被用来发送包含变化了的新参数的email。资料库传递</filename></para>
+
+ <para>四个参数给该hook:到资料库的路径,属性存在的
+ revision,经过校验的产生变化的用户名,和属性自身的名字。</para>
+
+ <para>分布式Subversion包含<command>propchange-email。<command>py</command>
+ 脚本(在Subversion
+ sourcetree中的tools/backup/目录中)被用来发送于revision的属性变</command></para>
+
+ <para>
+ <command>化细节有关的email。这种email包含revision和发生变化的属性名,产生变化的用户名,新属性值。</command>
+ </para>
+
+ <para />
</listitem>
</varlistentry>
</variablelist>
<warning>
- <para>Do not attempt to modify the transaction using hook
- scripts. A common example of this would be to automatically
- set properties such as <literal>svn:eol-style</literal> or
- <literal>svn:mime-type</literal> during the commit. While
- this might seem like a good idea, it causes problems. The
- main problem is that the client does not know about the
- change made by the hook script, and there is no way to
- inform the client that it is out-of-date. This
- inconsistency can lead to surprising and unexpected
- behavior.</para>
-
- <para>Instead of attempting to modify the transaction, it is
- much better to <emphasis>check</emphasis> the transaction in
- the <filename>pre-commit</filename> hook and reject the
- commit if it does not meet the desired requirements.</para>
- </warning>
+ <para />
+
+ <para>不要尝试用hook脚本修改transaction。一个通常的例子就是这可能会在运行式自动设置诸如<literal>svn:eol-style</literal>
+ 或
+ <literal>svn:mime-type</literal>属性。这看起来是个好主意,但它会引起问题。主要的问题是客户并不知道由hook脚本改变的变化,同时没有没有办法通告客户它的数据是过时的。</para>
+
+ <para>这种不连续会导致出人意料和不能预测的行为。</para>
- <para>Subversion will attempt to execute hooks as the same user
- who owns the process which is accessing the Subversion
- repository. In most cases, the repository is being accessed
- via Apache HTTP server and mod_dav_svn, so this user is the
- same user that Apache runs as. The hooks themselves will need
- to be configured with OS-level permissions that allow that
- user to execute them. Also, this means that any file or
- programs (including the Subversion repository itself) accessed
- directly or indirectly by the hook will be accessed as the
- same user. In other words, be alert to potential
- permission-related problems that could prevent the hook from
- performing the tasks you've written it to perform.</para>
+ <para>检查<filename>pre-commit</filename>
+ hook的transaction及假如它不满足要求,通告它,是一种取代修改transaction更好的办法。</para>
+ <para>Subversion会执行hooks</para>
+ </warning>
+
+ <para>Subversion will attempt to execute hooks as the same user who owns
+ the process which is accessing the Subversion repository。 In most cases,
+ the repository is being accessed via Apache HTTP server and mod_dav_svn,
+ so this user is the same user that Apache runs as。 The hooks themselves
+ will need to be configured with OS-level permissions that allow that
+ user to execute them。 Also, this means that any file or programs
+ (including the Subversion repository itself) accessed directly or
+ indirectly by the hook will be accessed as the same user。 In other
+ words, be alert to potential permission-related problems that could
+ prevent the hook from performing the tasks you've written it to
+ perform。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-2.2">
- <title>Berkeley DB Configuration</title>
+ <title>Berkeley DB 设置</title>
+
+ <para>Berkeley DB 环境是一个或多个数据库、日志文件、 域文件和配置文件的封装。Berkeley DB
+ 环境有它自己预设的设定值,像是任何时间可使用的锁定数目、 日志文件的大小等。 Subversion程序会为Berkeley DB
+ 配置选项设定默认的值。 不过,有时你的特定资料库需要特定的数据集合和访问类型,可能需要不同的配置选项。</para>
- <para>A Berkeley DB environment is an encapsulation of one or
- more databases, log files, region files and configuration
- files. The Berkeley DB environment has its own set of default
- configuration values for things like the number of locks
- allowed to be taken out at any given time, or the maximum size
- of the journaling log files, etc. Subversion's filesystem
- code additionally chooses default values for some of the
- Berkeley DB configuration options. However, sometimes your
- particular repository, with its unique collection of data and
- access patterns, might require a different set of
- configuration option values.</para>
-
- <para>The folks at Sleepycat (the producers of Berkeley DB)
- understand that different databases have different
- requirements, and so they have provided a mechanism for
- overriding at runtime many of the configuration values for the
- Berkeley DB environment. Berkeley checks for the presence of
- a file named <filename>DB_CONFIG</filename> in each
- environment directory, and parses the options found in that
- file for use with that particular Berkeley environment.</para>
-
- <para>The Berkeley configuration file for your repository is
- located in the <filename>db</filename> environment directory,
- at <filename>repos/db/DB_CONFIG</filename>. Subversion itself
- creates this file when it creates the rest of the repository.
- The file initially contains some default options, as well as
- pointers to the Berkeley DB online documentation so you can
- read about what those options do. Of course, you are free to
- add any of the supported Berkeley DB options to your
- <filename>DB_CONFIG</filename> file. Just be aware that while
- Subversion never attempts to read or interpret the contents of
- the file, and makes no use of the option settings in it,
- you'll want to avoid any configuration changes that may cause
- Berkeley DB to behave in a fashion that is unexpected by the
- rest of the Subversion code. Also, changes made to
- <filename>DB_CONFIG</filename> won't take effect until you
- recover the database environment (using <command>svnadmin
- recover</command>).</para>
+ <para>Sleepycat(BerkeleyDB的制造厂商)的人员清楚不同的资料库有不同的需求,所以他们提供了运行时为BerkeleyDB环境重载配置值的功能。Berkeley在每一个环境目录中检查是否存在一个名叫<filename>DB_CONFIG</filename>的文件,然后解析其中的为某个Berkeley环境所用的选项。</para>
+
+ <para>你的资料库的Berkeley配置文件位于<filename>db</filename>目录,
+ <filename>repos/db/DB_CONFIG</filename>。 Subversion
+ 在创建资料库时自己创建了这个文件。这个文件初始化包含一些默认选项,也包含了Berkeley
+ DB在线文档的参照,使你能够了解这些选项是做什么的。当然,你也可以为你的DB_CONFIG文件添加任何Berkeley DB
+ 支持的选项。应当注意,当Subversion不能访问文件或设置没有生效时,不应更改任何配置,因为那会引起Berkeley数据库以一种预料不到的方式执行剩下的程序。更改</para>
+
+ <para><filename>DB_CONFIG</filename>并不会产生任何作用,除非你恢复数据库环境(用
+ <command>svnadmin recover</command>)。</para>
+
+ <para />
</sect2>
</sect1>
<!-- ******************************************************************* -->
- <!-- *** SECTION 3: REPOSITORY MAINTENANCE *** -->
+
+ <!-- *** SECTION 3: 资料库维护 *** -->
+
<!-- ******************************************************************* -->
<sect1 id="svn-ch-5-sect-3">
- <title>Repository Maintenance</title>
+ <title>资料库维护</title>
- <para>Maintaining a Subversion repository can be a daunting task,
- mostly due to the complexities inherent in systems which have a
- database backend. Doing the task well is all about knowing the
- tools—what they are, when to use them, and how to use
- them. This section will introduce you to the repository
- administration tools provided by Subversion, and how to wield
- them to accomplish tasks such as repository migrations,
- upgrades, backups and cleanups.</para>
+ <para>维护一个Subversion资料库是一项令人沮丧的工作,主要因为有数据库后端与生俱来的复杂性。做好这项工作需要知道一些工具-它们是什么,什么时候用以及如何使用。这一节将会向你介绍Subversion带的资料库管理工具,以及如何使用它们来完成诸如资料库移植、升级、备份和整理。</para>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-3.1">
- <title>An Administrator's Toolkit</title>
+ <title>管理员的工具箱</title>
- <para>Subversion provides a handful of utilities useful for
- creating, inspecting, modifying and repairing your repository.
- Let's look more closely at each of those tools. Afterward,
- we'll briefly examine some of the utilities included in the
- Berkeley DB distribution that provide functionality specific
- to your repository's database backend not otherwise provided
- by Subversion's own tools.</para>
+ <para>Subversion提供了一些对创建、查看、修改和修复资料库有用的工具。让我们详细了解一下这些工具。然后,我们再看一下在仅在BerkeleyDB发行版中提供的针对资料数据库的工具。</para>
<sect3 id="svn-ch-5-sect-3.1.1">
<title>svnlook</title>
-
- <para><command>svnlook</command> is a tool provided by
- Subversion for examining the various revisions and
- transactions in a repository. No part of this program
- attempts to change the repository—it's a
- <quote>read-only</quote> tool. <command>svnlook</command>
- is typically used by the repository hooks for reporting the
- changes that are about to be committed (in the case of the
- <command>pre-commit</command> hook) or that were just
- committed (in the case of the <command>post-commit</command>
- hook) to the repository. A repository administrator may use
- this tool for diagnostic purposes.</para>
-
- <para><command>svnlook</command> has a straightforward
- syntax:</para>
-
+
+ <para><command>svnlook</command>是Subversion提供的用来查看资料库中不同的修订版和事务。这个程序不会修改资料库内容-这是个“只读”的工具。<command>svnlook</command>通常用在资料库挂钩程序中,用来记录资料库即将提交的变更(<command>用在pre-commit挂钩时)</command>或者已经提交的(用在<command>post-commit</command>挂钩时)。资料库管理员可以将这个工具用于诊断。</para>
+
+ <para><command>svnlook</command> 的语法很直接:</para>
+
<screen>
$ svnlook help
-general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
+general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS 。。。]
Note: any subcommand which takes the '--revision' and '--transaction'
- options will, if invoked without one of those options, act on
- the repository's youngest revision.
-Type "svnlook help <subcommand>" for help on a specific subcommand.
-…
-</screen>
-
- <para>Nearly every one of <command>svnlook</command>'s
- subcommands can operate on either a revision or a
- transaction tree, printing information about the tree
- itself, or how it differs from the previous revision of the
- repository. You use the <option>--revision</option> and
- <option>--transaction</option> options to specify which
- revision or transaction, respectively, to examine. Note
- that while revision numbers appear as natural numbers,
- transaction names are alphanumeric strings. Keep in mind
- that the filesystem only allows browsing of uncommitted
- transactions (transactions that have not resulted in a new
- revision). Most repositories will have no such
- transactions, because transactions are usually either
- committed (which disqualifies them from viewing) or aborted
- and removed.</para>
-
- <para>In the absence of both the <option>--revision</option>
- and <option>--transaction</option> options,
- <command>svnlook</command> will examine the youngest (or
- <quote>HEAD</quote>) revision in the repository. So the
- following two commands do exactly the same thing when 19 is
- the youngest revision in the repository located at
- <filename>/path/to/repos</filename>:</para>
+ options will, if invoked without one of those options, act on
+ the repository's youngest revision。
+Type "svnlook help <subcommand>" for help on a specific subcommand。
+…
+</screen>
+
+ <para>几乎<command>svnlook</command>的每一个子命令都能操作修订版或事务树,显示资料树的信息,或是它与资料库中上一个修订版的不同。你可以用
+ <option>--revision</option> 和 <option>--transaction</option>
+ 选项指定要查看的修订版或事务。注意,虽然修订版号看起来像自然数,但是事务名称是包含英文字母与数字的字符串。请记住文件系统只允许浏览未提交的事务(还没有形成一个新的修订版的事务)。多数资料库没有这种事务,因为事务通常或者被提交了(这样便不能被查看),或者被中止然后删除。</para>
+
+ <para>如果没有<option>--revision</option>和<option>--transaction</option>选项,<command>svnlook</command>会查看资料库中最年轻的修订版(或“HEAD”)。所以下边的两个命令执行结果完全相同,当位于<filename>/path/to/repos</filename>的资料库中,19是最年轻的修订版的时候:</para>
<screen>
$ svnlook info /path/to/repos
$ svnlook info /path/to/repos --revision 19
</screen>
- <para>The only exception to these rules about subcommands is
- the <command>svnlook youngest</command> subcommand, which
- takes no options, and simply prints out the
- <literal>HEAD</literal> revision number.</para>
+ <para>这些子命令的唯一例外,是<command>svnlook
+ youngest</command>命令,它不需要选项,只会显示出<literal>HEAD</literal>修订版号。</para>
<screen>
$ svnlook youngest /path/to/repos
19
</screen>
-
- <para>Output from <command>svnlook</command> is designed to be
- both human- and machine-parsable. Take as an example the output
- of the <literal>info</literal> subcommand:</para>
+
+ <para><command>svnlook</command>的输出被设计为人和机器都易理解。拿<literal>info</literal>子命令举例来说:</para>
<screen>
$ svnlook info /path/to/repos
sally
-2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)
+2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)
27
Added the usual
-Greek tree.
+Greek tree。
</screen>
- <para>The output of the <literal>info</literal> subcommand is
- defined as:</para>
+ <para>info子命令的输出定义如下:</para>
<orderedlist>
<listitem>
- <para>The author, followed by a newline.</para>
+ <para>作者,后接换行。</para>
</listitem>
+
<listitem>
- <para>The date, followed by a newline.</para>
+ <para>日期,后接换行。</para>
</listitem>
+
<listitem>
- <para>The number of characters in the log message,
- followed by a newline.</para>
+ <para>日志消息的字数,后接换行。</para>
</listitem>
+
<listitem>
- <para>The log message itself, followed by a newline.</para>
+ <para>日志消息, 后接换行。</para>
</listitem>
</orderedlist>
- <para>This output is human-readable, meaning items like the
- datestamp are displayed using a textual representation
- instead of something more obscure (such as the number of
- nanoseconds since the Tasty Freeze guy drove by). But this
- output is also machine-parsable—because the log
- message can contain multiple lines and be unbounded in
- length, <command>svnlook</command> provides the length of
- that message before the message itself. This allows scripts
- and other wrappers around this command to make intelligent
- decisions about the log message, such as how much memory to
- allocate for the message, or at least how many bytes to skip
- in the event that this output is not the last bit of data in
- the stream.</para>
-
- <para>Another common use of <command>svnlook</command> is to
- actually view the contents of a revision or transaction
- tree. The <command>svnlook tree</command> command displays
- the directories and files in the requested tree. If you
- supply the <option>--show-ids</option> option, it will also
- show the filesystem node revision IDs for each of those
- paths (which is generally of more use to developers than to
- users).</para>
+ <para>这种输出是人可阅读的,像是时间戳这种有意义的条目,使用文本表示,而不是其他比较晦涩的方式。这种输出也是机器可读的-因为日志信息可以有多行,没有长度的限制,<command>svnlook</command>在日志消息之前提供了消息的长度。这使得脚本或者其他对这个命令进行的封装提供了更强的功能,比如日志消息使用了多少内存,或在这个输出成为最后一个字节之前应该忽略多少字节。</para>
+
+ <para>另一个<command>svnlook</command>常见的用法是查看修订版树或事务树的内容。
+ <command>svnlook tree</command> 命令显示在请求的树中的目录和文件。如果你提供了
+ <option>--show-ids</option> 选项,
+ 它还会显示每个路径的文件系统节点修订版ID(这一点对开发者往往很有用)。</para>
<screen>
$ svnlook tree /path/to/repos --show-ids
-/ <0.0.1>
- A/ <2.0.1>
- B/ <4.0.1>
- lambda <5.0.1>
- E/ <6.0.1>
- alpha <7.0.1>
- beta <8.0.1>
- F/ <9.0.1>
- mu <3.0.1>
- C/ <a.0.1>
- D/ <b.0.1>
- gamma <c.0.1>
- G/ <d.0.1>
- pi <e.0.1>
- rho <f.0.1>
- tau <g.0.1>
- H/ <h.0.1>
- chi <i.0.1>
- omega <k.0.1>
- psi <j.0.1>
- iota <1.0.1>
-</screen>
-
- <para>Once you've seen the layout of directories and files in
- your tree, you can use commands like <command>svnlook
- cat</command>, <command>svnlook propget</command>, and
- <command>svnlook proplist</command> to dig into the details
- of those files and directories.</para>
-
- <para><command>svnlook</command> can perform a variety of
- other queries, displaying subsets of bits of information
- we've mentioned previously, reporting which paths were
- modified in a given revision or transaction, showing textual
- and property differences made to files and directories, and
- so on. The following is a brief description of the current
- list of subcommands accepted by <command>svnlook</command>,
- and the output of those subcommands:</para>
+/ <0。0。1>
+ A/ <2。0。1>
+ B/ <4。0。1>
+ lambda <5。0。1>
+ E/ <6。0。1>
+ alpha <7。0。1>
+ beta <8。0。1>
+ F/ <9。0。1>
+ mu <3。0。1>
+ C/ <a。0。1>
+ D/ <b。0。1>
+ gamma <c。0。1>
+ G/ <d。0。1>
+ pi <e。0。1>
+ rho <f。0。1>
+ tau <g。0。1>
+ H/ <h。0。1>
+ chi <i。0。1>
+ omega <k。0。1>
+ psi <j。0。1>
+ iota <1。0。1>
+</screen>
+
+ <para>如果你看过树中目录和文件的布局,你可以使用<command>svnlook cat</command>,
+ <command>svnlook propget</command>, 和 <command>svnlook
+ proplist</command> 命令来查看这些目录和文件的细节。</para>
+
+ <para><command>svnlook</command>
+ 还可以做很多别的查询,显示我们先前提到的信息的一些子集,报告指定的修订版或事务中哪些路径曾经被修改过,显示对文件和目录做过的文本和属性的修改,等等。下面是<command>svnlook</command>命令能接受的子命令的介绍,以及这些子命令的输出:</para>
<variablelist>
<varlistentry>
- <term><literal>author</literal></term>
+ <term>
+ <literal>author</literal>
+ </term>
+
<listitem>
- <para>Print the tree's author.</para>
+ <para>显示该树的作者。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>cat</literal></term>
+ <term>
+ <literal>cat</literal>
+ </term>
+
<listitem>
- <para>Print the contents of a file in the tree.</para>
+ <para>显示树中某文件的内容。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>changed</literal></term>
+ <term>
+ <literal>changed</literal>
+ </term>
+
<listitem>
- <para>List all files and directories that changed in the
- tree.</para>
+ <para>显示树中被修改过的所有文件和目录。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>date</literal></term>
+ <term>
+ <literal>date</literal>
+ </term>
+
<listitem>
- <para>Print the tree's datestamp.</para>
+ <para>显示该树的时间戳。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>diff</literal></term>
+ <term>
+ <literal>diff</literal>
+ </term>
+
<listitem>
- <para>Print unified diffs of changed files.</para>
+ <para>显示被修改文件的统一差异格式。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>dirs-changed</literal></term>
+ <term>
+ <literal>dirs-changed</literal>
+ </term>
+
<listitem>
- <para>List the directories in the tree that were
- themselves changed, or whose file children were
- changed.</para>
+ <para>显示树中本身被修改或者其中文件被修改的目录。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>history</literal></term>
+ <term>
+ <literal>history</literal>
+ </term>
+
<listitem>
- <para>Display interesting points in the history of a
- versioned path (places where modifications or copies
- occurred).</para>
+ <para>显示Display interesting points in the history of a versioned
+ path (places where modifications or copies occurred)。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>info</literal></term>
+ <term>
+ <literal>info</literal>
+ </term>
+
<listitem>
- <para>Print the tree's author, datestamp, log message
- character count, and log message.</para>
+ <para>显示树的作者、时间戳、日志字数和日志信息。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>log</literal></term>
+ <term>
+ <literal>log</literal>
+ </term>
+
<listitem>
- <para>Print the tree's log message.</para>
+ <para>显示树的日志信息。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>propget</literal></term>
+ <term>
+ <literal>propget</literal>
+ </term>
+
<listitem>
- <para>Print the value of a property on a path in the
- tree.</para>
+ <para>显示树中属性的值。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>proplist</literal></term>
+ <term>
+ <literal>proplist</literal>
+ </term>
+
<listitem>
- <para>Print the names and values of properties set on paths
- in the tree.</para>
+ <para>显示树中属性集合的名字与值。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>tree</literal></term>
+ <term>
+ <literal>tree</literal>
+ </term>
+
<listitem>
- <para>Print the tree listing, optionally revealing the
- filesystem node revision IDs associated with each
- path.</para>
+ <para>显示树列表,可选的显示与路径有关的文件系统节点的revision IDs。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>uuid</literal></term>
+ <term>
+ <literal>uuid</literal>
+ </term>
+
<listitem>
- <para>Print the repository's UUID—
- <emphasis>U</emphasis>niversal <emphasis>U</emphasis>nique
- <emphasis>ID</emphasis>entifier.</para>
+ <para>显示资料库的UUID--统一资源标志。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>youngest</literal></term>
+ <term>
+ <literal>youngest</literal>
+ </term>
+
<listitem>
- <para>Print the youngest revision number.</para>
+ <para>显示最年轻的修订版号。</para>
</listitem>
</varlistentry>
</variablelist>
-
</sect3>
<sect3 id="svn-ch-5-sect-3.1.2">
<title>svnadmin</title>
- <para>The <command>svnadmin</command> program is the
- repository administrator's best friend. Besides providing
- the ability to create Subversion repositories, this program
- allows you to perform several maintenance operations on
- those repositories. The syntax of
- <command>svnadmin</command> is similar to that of
- <command>svnlook</command>:</para>
+ <para><command>svnadmin</command> 程序是资料库管理员最好的朋友。
+ 除了提供创建Subversion资料库的功能,这个程序使你可以维护这些资料库。<command>svnadmin</command>
+ 的语法跟 <command>svnlook</command>类似:</para>
<screen>
$ svnadmin help
-general usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
-Type "svnadmin help <subcommand>" for help on a specific subcommand.
+general usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS 。。。]
+Type "svnadmin help <subcommand>" for help on a specific subcommand。
Available subcommands:
create
deltify
dump
- help (?, h)
-…
+ help (?, h)
+…
</screen>
- <para>We've already mentioned <command>svnadmin</command>'s
- <literal>create</literal> subcommand (see <xref
- linkend="svn-ch-5-sect-2"/>). Most of the others we will
- cover in more detail later in this chapter. For now, let's
- just take a quick glance at what each of the available
- subcommands offers.</para>
+ <para>我们已经提过 <command>svnadmin</command> 的<literal>create</literal>
+ 子命令 (参照 <xref linkend="svn-ch-5-sect-2" />)。
+ 本章中我们会详细讲解大多数其他的命令。现在,我们来简单的看一下每个可用的子命令提供了什么功能。</para>
<variablelist>
<varlistentry>
- <term><literal>create</literal></term>
+ <term>
+ <literal>create</literal>
+ </term>
+
<listitem>
- <para>Create a new Subversion repository.</para>
+ <para>创建一个新的Subversion资料库。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>deltify</literal></term>
+ <term>
+ <literal>deltify</literal>
+ </term>
+
<listitem>
- <para>Run over a specified revision range, performing
- predecessor deltification on the paths changed in
- those revisions. If no revisions are specified, this
- command will simply deltify the
- <literal>HEAD</literal> revision.</para>
+ <para>在指定的修订版范围内,对其中修改过的路径做deltification操作。如果没有指定修订版,这条命令会修改HEAD修订版。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>dump</literal></term>
+ <term>
+ <literal>dump</literal>
+ </term>
+
<listitem>
- <para>Dump the contents of the repository, bounded by a
- given set of revisions, using a portable dump format.</para>
+ <para>dump由给定的revisions集限定的资料库的轻便格式化内容。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>hotcopy</literal></term>
+ <term>
+ <literal>hotcopy</literal>
+ </term>
+
<listitem>
- <para>Make a hot copy of a repository. You can run
- this command at any time and make a safe copy of the
- repository, regardless if other processes are using
- the repository.</para>
+ <para>对资料库做hot copy。用这个方法你能任何时候安全的备份资料库而不许考虑是否资料库正在使用。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>list-dblogs</literal></term>
+ <term>
+ <literal>list-dblogs</literal>
+ </term>
+
<listitem>
- <para>(Berkeley DB repositories only.) List the paths
- of Berkeley DB log files associated with the
- repository. This list includes all log
- files—those still in use by Subversion, as well
- as those no longer in use.</para>
+ <para>(Berkeley 数据库的资料库专有)
+ 列出Berkeley数据库中与资料库有关的日志文件清单。这个清单包括所有的日志文件--现在仍然被资料库使用的和不在使用的。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>list-unused-dblogs</literal></term>
+ <term>
+ <literal>list-unused-dblogs</literal>
+ </term>
+
<listitem>
- <para>(Berkeley DB repositories only.) List the paths
- of Berkeley DB log files associated with, but no
- longer used by, the repository. You may safely remove
- these log files from the repository layout, possibly
- archiving them for use in the event that you ever need
- to perform a catastrophic recovery of the
- repository.</para>
+ <para>(Berkeley 数据库的资料库专有)列出Berkeley
+ 数据库资料库有关的不在使用日志文件路径清单。你能安全的从资料库中删除那些日志文件,也可能将它们存档以用来灾难事件后资料库的恢复。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>load</literal></term>
+ <term>
+ <literal>load</literal>
+ </term>
+
<listitem>
- <para>Load a set of revisions into a repository from a
- stream of data that uses the same portable dump format
- generated by the <literal>dump</literal> subcommand.</para>
+ <para>从dump子命令中产生的轻快格式化的数据流中下载一系列revisions装入资料库。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>lstxns</literal></term>
+ <term>
+ <literal>lstxns</literal>
+ </term>
+
<listitem>
- <para>List the names of uncommitted Subversion
- transactions that currently exist in the repository.</para>
+ <para>列出刚刚退出资料库的没有执行的Subversion transactions清单。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>recover</literal></term>
+ <term>
+ <literal>recover</literal>
+ </term>
+
<listitem>
- <para>Perform recovery steps on a repository that is in
- need of such, generally after a fatal error has
- occurred that prevented a process from cleanly
- shutting down its communication with the repository.</para>
+ <para>恢复资料库,通常载资料库发生致命错误时实行,以预防对Subversion transactions的cleanly
+ shutting down。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>rmtxns</literal></term>
+ <term>
+ <literal>rmtxns</literal>
+ </term>
+
<listitem>
- <para>Cleanly remove Subversion transactions from the
- repository (conveniently fed by output from the
- <literal>lstxns</literal> subcommand).</para>
+ <para>从资料库中清除Subversion
+ transactions(<literal>在lstxns子命令后执行</literal>)。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>setlog</literal></term>
+ <term>
+ <literal>setlog</literal>
+ </term>
+
<listitem>
- <para>Replace the current value of the
- <literal>svn:log</literal> (commit log message)
- property on a given revision in the repository with a
- new value.</para>
+ <para>重置svn:log属性当前值。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>verify</literal></term>
+ <term>
+ <literal>verify</literal>
+ </term>
+
<listitem>
- <para>Verify the contents of the repository. This includes,
- among other things, checksum comparisons of the
- versioned data stored in the repository.</para>
+ <para>确认资料库的内容。包括校验和比较。</para>
</listitem>
</varlistentry>
</variablelist>
-
</sect3>
<sect3 id="svn-ch-5-sect-3.1.3">
<title>svndumpfilter</title>
- <para>Since Subversion stores everything in an opaque database
- system, attempting manual tweaks is unwise, if not quite
- difficult. And once data has been stored in your
- repository, Subversion generally doesn't provide an
- easy way to remove that data.
- <footnote>
- <para>That, by the way, is a <emphasis>feature</emphasis>,
- not a bug.</para>
- </footnote>
- But inevitably, there will be times when you would like to
- manipulate the history of your repository. You might need
- to strip out all instances of a file that was accidentally
- added to the repository (and shouldn't be there for whatever
- reason). Or, perhaps you have multiple projects sharing a
- single repository, and you decide to split them up into
- their own repositories. To accomplish tasks like this,
- administrators need a more manageable and malleable
- representation of the data in their repositories—the
- Subversion repository dump format.</para>
-
- <para>The Subversion repository dump format is a
- human-readable representation of the changes that you've
- made to your versioned data over time. You use the
- <command>svnadmin dump</command> command to generate the
- dump data, and <command>svnadmin load</command> to populate
- a new repository with it (see <xref
- linkend="svn-ch-5-sect-3.5"/>). The great thing about the
- human-readability aspect of the dump format is that, if you
- aren't careless about it, you can manually inspect and
- modify it. Of course, the downside is that if you have two
- years' worth of repository activity encapsulated in what is
- likely to be a very large dump file, it could take you a
- long, long time to manually inspect and modify it.</para>
+ <para>Since Subversion stores everything in an opaque database system,
+ attempting manual tweaks is unwise, if not quite difficult。 And once
+ data has been stored in your repository, Subversion generally doesn't
+ provide an easy way to remove that data。 <footnote>
+ <para>That, by the way, is a <emphasis>feature</emphasis>, not a
+ bug。</para>
+ </footnote> But inevitably, there will be times when you would like
+ to manipulate the history of your repository。 You might need to strip
+ out all instances of a file that was accidentally added to the
+ repository (and shouldn't be there for whatever reason)。 Or, perhaps
+ you have multiple projects sharing a single repository, and you decide
+ to split them up into their own repositories。 To accomplish tasks like
+ this, administrators need a more manageable and malleable
+ representation of the data in their repositories—the Subversion
+ repository dump format。</para>
+
+ <para>The Subversion repository dump format is a human-readable
+ representation of the changes that you've made to your versioned data
+ over time。 You use the <command>svnadmin dump</command> command to
+ generate the dump data, and <command>svnadmin load</command> to
+ populate a new repository with it (see <xref
+ linkend="svn-ch-5-sect-3.5" />)。 The great thing about the
+ human-readability aspect of the dump format is that, if you aren't
+ careless about it, you can manually inspect and modify it。 Of course,
+ the downside is that if you have two years' worth of repository
+ activity encapsulated in what is likely to be a very large dump file,
+ it could take you a long, long time to manually inspect and modify
+ it。</para>
<para>While it won't be the most commonly used tool at the
- administrator's disposal, <command>svndumpfilter</command>
- provides a very particular brand of useful
- functionality—the ability to quickly and easily modify
- that dump data by acting as a path-based filter. Simply
- give it either a list of paths you wish to keep, or a list
- of paths you wish to not keep, then pipe your repository
- dump data through this filter. The result will be a
- modified stream of dump data that contains only the
- versioned paths you (explicitly or implicitly) requested.</para>
+ administrator's disposal, <command>svndumpfilter</command> provides a
+ very particular brand of useful functionality—the ability to quickly
+ and easily modify that dump data by acting as a path-based filter。
+ Simply give it either a list of paths you wish to keep, or a list of
+ paths you wish to not keep, then pipe your repository dump data
+ through this filter。 The result will be a modified stream of dump data
+ that contains only the versioned paths you (explicitly or implicitly)
+ requested。</para>
<para>The syntax of <command>svndumpfilter</command> is as
- follows:</para>
+ follows:</para>
<screen>
$ svndumpfilter help
-general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]
-Type "svndumpfilter help <subcommand>" for help on a specific subcommand.
+general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS 。。。]
+Type "svndumpfilter help <subcommand>" for help on a specific subcommand。
Available subcommands:
exclude
include
- help (?, h)
+ help (?, h)
</screen>
- <para>There are only two interesting subcommands. They allow
- you to make the choice between explicit or implicit
- inclusion of paths in the stream:</para>
+ <para>There are only two interesting subcommands。 They allow you to
+ make the choice between explicit or implicit inclusion of paths in the
+ stream:</para>
<variablelist>
<varlistentry>
- <term><literal>exclude</literal></term>
+ <term>
+ <literal>exclude</literal>
+ </term>
+
<listitem>
<para>Filter out a set of paths from the dump data
- stream.</para>
+ stream。</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>include</literal></term>
+ <term>
+ <literal>include</literal>
+ </term>
+
<listitem>
- <para>Allow only the requested set of paths to pass
- through the dump data stream.</para>
+ <para>Allow only the requested set of paths to pass through the
+ dump data stream。</para>
</listitem>
</varlistentry>
</variablelist>
<para>Let's look a realistic example of how you might use this
- program. We discuss elsewhere (see <xref
- linkend="svn-ch-5-sect-6.1"/>) the process of deciding how to
- choose a layout for the data in your
- repositories—using one repository per project or
- combining them, arranging stuff within your repository, and
- so on. But sometimes after new revisions start flying in,
- you rethink your layout and would like to make some changes.
- A common change is the decision to move multiple projects
- which are sharing a single repository into separate
- repositories for each project.</para>
+ program。 We discuss elsewhere (see <xref
+ linkend="svn-ch-5-sect-6.1" />) the process of deciding how to choose
+ a layout for the data in your repositories—using one repository per
+ project or combining them, arranging stuff within your repository, and
+ so on。 But sometimes after new revisions start flying in, you rethink
+ your layout and would like to make some changes。 A common change is
+ the decision to move multiple projects which are sharing a single
+ repository into separate repositories for each project。</para>
<para>Our imaginary repository contains three projects:
- <literal>calc</literal>, <literal>calendar</literal>, and
- <literal>spreadsheet</literal>. They have been living
- side-by-side in a layout like this:</para>
+ <literal>calc</literal>, <literal>calendar</literal>, and
+ <literal>spreadsheet</literal>。 They have been living side-by-side in
+ a layout like this:</para>
<screen>
/
@@ -1443,49 +1085,47 @@
tags/
</screen>
- <para>To get these three projects into their own repositories,
- we first dump the whole repository:</para>
+ <para>To get these three projects into their own repositories, we
+ first dump the whole repository:</para>
<screen>
$ svnadmin dump /path/to/repos > repos-dumpfile
-* Dumped revision 0.
-* Dumped revision 1.
-* Dumped revision 2.
-* Dumped revision 3.
-…
+* Dumped revision 0。
+* Dumped revision 1。
+* Dumped revision 2。
+* Dumped revision 3。
+…
$
</screen>
- <para>Next, run that dump file through the filter, each time
- including only one of our top-level directories, and
- resulting in three new dump files:</para>
+ <para>Next, run that dump file through the filter, each time including
+ only one of our top-level directories, and resulting in three new dump
+ files:</para>
<screen>
$ cat repos-dumpfile | svndumpfilter include calc > calc-dumpfile
-…
+…
$ cat repos-dumpfile | svndumpfilter include calendar > cal-dumpfile
-…
+…
$ cat repos-dumpfile | svndumpfilter include spreadsheet > ss-dumpfile
-…
+…
$
</screen>
- <para>At this point, you have to make a decision. Each of
- your dump files will create a valid repository,
- but will preserve the paths exactly as they were in the
- original repository. This means that even though you would
- have a repository solely for your <literal>calc</literal>
- project, that repository would still have a top-level
- directory named <filename>calc</filename>. If you want
- your <filename>trunk</filename>, <filename>tags</filename>,
- and <filename>branches</filename> directories to live in the
- root of your repository, you might wish to edit your
- dump files, tweaking the <literal>Node-path</literal> and
- <literal>Copyfrom-path</literal> headers to no longer have
- that first <filename>calc/</filename> path component. Also,
- you'll want to remove the section of dump data that creates
- the <filename>calc</filename> directory. It will look
- something like:</para>
+ <para>At this point, you have to make a decision。 Each of your dump
+ files will create a valid repository, but will preserve the paths
+ exactly as they were in the original repository。 This means that even
+ though you would have a repository solely for your
+ <literal>calc</literal> project, that repository would still have a
+ top-level directory named <filename>calc</filename>。 If you want your
+ <filename>trunk</filename>, <filename>tags</filename>, and
+ <filename>branches</filename> directories to live in the root of your
+ repository, you might wish to edit your dump files, tweaking the
+ <literal>Node-path</literal> and <literal>Copyfrom-path</literal>
+ headers to no longer have that first <filename>calc/</filename> path
+ component。 Also, you'll want to remove the section of dump data that
+ creates the <filename>calc</filename> directory。 It will look
+ something like:</para>
<screen>
Node-path: calc
@@ -1496,150 +1136,146 @@
</screen>
<warning>
- <para>If you do plan on manually editing the dump file to
- remove a top-level directory, make sure that your editor is
- not set to automatically convert end-lines to the native
- format (e.g. \r\n to \n) as the content will then not agree
- with the metadata and this will render the dump file
- useless.</para>
+ <para>If you do plan on manually editing the dump file to remove a
+ top-level directory, make sure that your editor is not set to
+ automatically convert end-lines to the native format (e。g。 \r\n to
+ \n) as the content will then not agree with the metadata and this
+ will render the dump file useless。</para>
</warning>
- <para>All that remains now is to create your three new
- repositories, and load each dump file into the right
- repository:</para>
+ <para>All that remains now is to create your three new repositories,
+ and load each dump file into the right repository:</para>
<screen>
$ svnadmin create calc; svnadmin load calc < calc-dumpfile
-<<< Started new transaction, based on original revision 1
- * adding path : Makefile ... done.
- * adding path : button.c ... done.
-…
+<<< Started new transaction, based on original revision 1
+ * adding path : Makefile 。。。 done。
+ * adding path : button。c 。。。 done。
+…
$ svnadmin create calendar; svnadmin load calendar < cal-dumpfile
-<<< Started new transaction, based on original revision 1
- * adding path : Makefile ... done.
- * adding path : cal.c ... done.
-…
+<<< Started new transaction, based on original revision 1
+ * adding path : Makefile 。。。 done。
+ * adding path : cal。c 。。。 done。
+…
$ svnadmin create spreadsheet; svnadmin load spreadsheet < ss-dumpfile
-<<< Started new transaction, based on original revision 1
- * adding path : Makefile ... done.
- * adding path : ss.c ... done.
-…
+<<< Started new transaction, based on original revision 1
+ * adding path : Makefile 。。。 done。
+ * adding path : ss。c 。。。 done。
+…
$
</screen>
- <para>Both of <command>svndumpfilter</command>'s subcommands
- accept options for deciding how to deal with
- <quote>empty</quote> revisions. If a given revision
- contained only changes to paths that were filtered out, that
- now-empty revision could be considered uninteresting or even
- unwanted. So to give the user control over what to do with
- those revisions, <command>svndumpfilter</command> provides
- the following command-line options:</para>
+ <para>Both of <command>svndumpfilter</command>'s subcommands accept
+ options for deciding how to deal with <quote>empty</quote> revisions。
+ If a given revision contained only changes to paths that were filtered
+ out, that now-empty revision could be considered uninteresting or even
+ unwanted。 So to give the user control over what to do with those
+ revisions, <command>svndumpfilter</command> provides the following
+ command-line options:</para>
<variablelist>
<varlistentry>
- <term><option>--drop-empty-revs</option></term>
+ <term>
+ <option>--drop-empty-revs</option>
+ </term>
+
<listitem>
- <para>Do not generate empty revisions at all—just
- omit them.</para>
+ <para>Do not generate empty revisions at all—just omit
+ them。</para>
</listitem>
</varlistentry>
+
<varlistentry>
- <term><option>--renumber-revs</option></term>
+ <term>
+ <option>--renumber-revs</option>
+ </term>
+
<listitem>
<para>If empty revisions are dropped (using the
- <option>--drop-empty-revs</option> option), change the
- revision numbers of the remaining revisions so that
- there are no gaps in the numeric sequence.</para>
+ <option>--drop-empty-revs</option> option), change the revision
+ numbers of the remaining revisions so that there are no gaps in
+ the numeric sequence。</para>
</listitem>
</varlistentry>
+
<varlistentry>
- <term><option>--preserve-revprops</option></term>
+ <term>
+ <option>--preserve-revprops</option>
+ </term>
+
<listitem>
- <para>If empty revisions are not dropped, preserve the
- revision properties (log message, author, date, custom
- properties, etc.) for those empty revisions.
- Otherwise, empty revisions will only contain the
- original datestamp, and a generated log message that
- indicates that this revision was emptied by
- <command>svndumpfilter</command>.</para>
+ <para>If empty revisions are not dropped, preserve the revision
+ properties (log message, author, date, custom properties, etc。)
+ for those empty revisions。 Otherwise, empty revisions will only
+ contain the original datestamp, and a generated log message that
+ indicates that this revision was emptied by
+ <command>svndumpfilter</command>。</para>
</listitem>
</varlistentry>
</variablelist>
-
- <para>While <command>svndumpfilter</command> can be very
- useful, and a huge timesaver, there are unfortunately a
- couple of gotchas. First, this utility is overly sensitive
- to path semantics. Pay attention to whether paths in your
- dump file are specified with or without leading slashes.
- You'll want to look at the <literal>Node-path</literal> and
- <literal>Copyfrom-path</literal> headers.</para>
+
+ <para>While <command>svndumpfilter</command> can be very useful, and a
+ huge timesaver, there are unfortunately a couple of gotchas。 First,
+ this utility is overly sensitive to path semantics。 Pay attention to
+ whether paths in your dump file are specified with or without leading
+ slashes。 You'll want to look at the <literal>Node-path</literal> and
+ <literal>Copyfrom-path</literal> headers。</para>
<screen>
-…
+…
Node-path: spreadsheet/Makefile
-…
+…
</screen>
- <para>If the paths have leading slashes, you should
- include leading slashes in the paths you pass to
- <command>svndumpfilter include</command> and
- <command>svndumpfilter exclude</command> (and if they don't,
- you shouldn't). Further, if your dump file has an inconsistent
- usage of leading slashes for some reason,
- <footnote>
- <para>While <command>svnadmin dump</command> has a
- consistent leading slash policy—to not include
- them—other programs which generate dump data might
- not be so consistent.</para>
- </footnote>
- you should probably normalize those paths so they all
- have, or lack, leading slashes.</para>
-
- <para>Also, copied paths can give you some trouble.
- Subversion supports copy operations in the repository, where
- a new path is created by copying some already existing path.
- It is possible that at some point in the lifetime of your
- repository, you might have copied a file or directory from
- some location that <command>svndumpfilter</command> is
- excluding, to a location that it is including. In order to
- make the dump data self-sufficient,
- <command>svndumpfilter</command> needs to still show the
- addition of the new path—including the contents of any
- files created by the copy—and not represent that
- addition as a copy from a source that won't exist in your
- filtered dump data stream. But because the Subversion
- repository dump format only shows what was changed in each
- revision, the contents of the copy source might not be
- readily available. If you suspect that you have any copies
- of this sort in your repository, you might want to rethink
- your set of included/excluded paths.</para>
-
+ <para>If the paths have leading slashes, you should include leading
+ slashes in the paths you pass to <command>svndumpfilter
+ include</command> and <command>svndumpfilter exclude</command> (and if
+ they don't, you shouldn't)。 Further, if your dump file has an
+ inconsistent usage of leading slashes for some reason, <footnote>
+ <para>While <command>svnadmin dump</command> has a consistent
+ leading slash policy—to not include them—other programs which
+ generate dump data might not be so consistent。</para>
+ </footnote> you should probably normalize those paths so they all
+ have, or lack, leading slashes。</para>
+
+ <para>Also, copied paths can give you some trouble。 Subversion
+ supports copy operations in the repository, where a new path is
+ created by copying some already existing path。 It is possible that at
+ some point in the lifetime of your repository, you might have copied a
+ file or directory from some location that
+ <command>svndumpfilter</command> is excluding, to a location that it
+ is including。 In order to make the dump data self-sufficient,
+ <command>svndumpfilter</command> needs to still show the addition of
+ the new path—including the contents of any files created by the
+ copy—and not represent that addition as a copy from a source that
+ won't exist in your filtered dump data stream。 But because the
+ Subversion repository dump format only shows what was changed in each
+ revision, the contents of the copy source might not be readily
+ available。 If you suspect that you have any copies of this sort in
+ your repository, you might want to rethink your set of
+ included/excluded paths。</para>
</sect3>
<sect3 id="svn-ch-5-sect-3.1.4">
- <title>svnshell.py</title>
+ <title>svnshell。py</title>
<para>The Subversion source tree also comes with a shell-like
- interface to the repository. The
- <command>svnshell.py</command> Python script (located in
- <filename>tools/examples/</filename> in the source tree)
- uses Subversion's language bindings (so you must have
- those properly compiled and installed in order for this
- script to work) to connect to the repository and filesystem
- libraries.</para>
-
- <para>Once started, the program behaves similarly to a shell
- program, allowing you to browse the various directories in
- your repository. Initially, you are
- <quote>positioned</quote> in the root directory of the
- <literal>HEAD</literal> revision of the repository, and
- presented with a command prompt. You can use the
- <literal>help</literal> command at any time to display a
- list of available commands and what they do.</para>
+ interface to the repository。 The <command>svnshell。py</command> Python
+ script (located in <filename>tools/examples/</filename> in the source
+ tree) uses Subversion's language bindings (so you must have those
+ properly compiled and installed in order for this script to work) to
+ connect to the repository and filesystem libraries。</para>
+
+ <para>Once started, the program behaves similarly to a shell program,
+ allowing you to browse the various directories in your repository。
+ Initially, you are <quote>positioned</quote> in the root directory of
+ the <literal>HEAD</literal> revision of the repository, and presented
+ with a command prompt。 You can use the <literal>help</literal> command
+ at any time to display a list of available commands and what they
+ do。</para>
<screen>
-$ svnshell.py /path/to/repos
+$ svnshell。py /path/to/repos
<rev: 2 />$ help
Available commands:
cat FILE : dump the contents of FILE
@@ -1653,20 +1289,18 @@
<rev: 2 />$
</screen>
- <para>Navigating the directory structure of your repository is
- done in the same way you would navigate a regular Unix or
- Windows shell—using the <literal>cd</literal> command.
- At all times, the command prompt will show you what revision
- (prefixed by <literal>rev:</literal>) or transaction
- (prefixed by <literal>txn:</literal>) you are currently
- examining, and at what path location in that revision or
- transaction. You can change your current revision or
- transaction with the <literal>setrev</literal> and
- <literal>settxn</literal> commands, respectively. As in a
- Unix shell, you can use the <literal>ls</literal> command to
- display the contents of the current directory, and you can
- use the <literal>cat</literal> command to display the
- contents of a file.</para>
+ <para>Navigating the directory structure of your repository is done in
+ the same way you would navigate a regular Unix or Windows shell—using
+ the <literal>cd</literal> command。 At all times, the command prompt
+ will show you what revision (prefixed by <literal>rev:</literal>) or
+ transaction (prefixed by <literal>txn:</literal>) you are currently
+ examining, and at what path location in that revision or transaction。
+ You can change your current revision or transaction with the
+ <literal>setrev</literal> and <literal>settxn</literal> commands,
+ respectively。 As in a Unix shell, you can use the
+ <literal>ls</literal> command to display the contents of the current
+ directory, and you can use the <literal>cat</literal> command to
+ display the contents of a file。</para>
<example id="svn-ch-8-sect-3.1.3-ex-1">
<title>Using svnshell to Navigate the Repository</title>
@@ -1675,207 +1309,189 @@
<rev: 2 />$ ls
REV AUTHOR NODE-REV-ID SIZE DATE NAME
----------------------------------------------------------------------------
- 1 sally < 2.0.1> Nov 15 11:50 A/
- 2 harry < 1.0.2> 56 Nov 19 08:19 iota
+ 1 sally < 2。0。1> Nov 15 11:50 A/
+ 2 harry < 1。0。2> 56 Nov 19 08:19 iota
<rev: 2 />$ cd A
<rev: 2 /A>$ ls
REV AUTHOR NODE-REV-ID SIZE DATE NAME
----------------------------------------------------------------------------
- 1 sally < 4.0.1> Nov 15 11:50 B/
- 1 sally < a.0.1> Nov 15 11:50 C/
- 1 sally < b.0.1> Nov 15 11:50 D/
- 1 sally < 3.0.1> 23 Nov 15 11:50 mu
+ 1 sally < 4。0。1> Nov 15 11:50 B/
+ 1 sally < a。0。1> Nov 15 11:50 C/
+ 1 sally < b。0。1> Nov 15 11:50 D/
+ 1 sally < 3。0。1> 23 Nov 15 11:50 mu
<rev: 2 /A>$ cd D/G
<rev: 2 /A/D/G>$ ls
REV AUTHOR NODE-REV-ID SIZE DATE NAME
----------------------------------------------------------------------------
- 1 sally < e.0.1> 23 Nov 15 11:50 pi
- 1 sally < f.0.1> 24 Nov 15 11:50 rho
- 1 sally < g.0.1> 24 Nov 15 11:50 tau
-<rev: 2 /A>$ cd ../..
+ 1 sally < e。0。1> 23 Nov 15 11:50 pi
+ 1 sally < f。0。1> 24 Nov 15 11:50 rho
+ 1 sally < g。0。1> 24 Nov 15 11:50 tau
+<rev: 2 /A>$ cd 。。/。。
<rev: 2 />$ cat iota
-This is the file 'iota'.
-Added this text in revision 2.
+This is the file 'iota'。
+Added this text in revision 2。
<rev: 2 />$ setrev 1; cat iota
-This is the file 'iota'.
+This is the file 'iota'。
<rev: 1 />$ exit
$
</screen>
</example>
- <para>As you can see in the previous example, multiple
- commands may be specified at a single command prompt,
- separated by a semicolon. Also, the shell understands the
- notions of relative and absolute paths, and will properly
- handle the <literal>.</literal> and
- <literal>..</literal> special path components.</para>
-
- <para>The <literal>youngest</literal> command displays the
- youngest revision. This is useful for determining the range
- of valid revisions you can use as arguments to the
- <literal>setrev</literal> command—you are allowed to
- browse all the revisions (recalling that they are named with
- integers) between 0 and the youngest, inclusively.
- Determining the valid browsable transactions isn't quite as
- pretty. Use the <command>lstxns</command> command to list
- the transactions that you are able to browse. The list of
- browsable transactions is the same list that
- <command>svnadmin lstxns</command> returns, and the same
- list that is valid for use with <command>svnlook</command>'s
- <option>--transaction</option> option.</para>
-
- <para>Once you've finished using the shell, you can exit
- cleanly by using the <command>exit</command> command.
- Alternatively, you can supply an end-of-file
- character—Control-D (though some Win32 Python
- distributions use the Windows Control-Z convention
- instead).</para>
-
+ <para>As you can see in the previous example, multiple commands may be
+ specified at a single command prompt, separated by a semicolon。 Also,
+ the shell understands the notions of relative and absolute paths, and
+ will properly handle the <literal>。</literal> and
+ <literal>。。</literal> special path components。</para>
+
+ <para>The <literal>youngest</literal> command displays the youngest
+ revision。 This is useful for determining the range of valid revisions
+ you can use as arguments to the <literal>setrev</literal> command—you
+ are allowed to browse all the revisions (recalling that they are named
+ with integers) between 0 and the youngest, inclusively。 Determining
+ the valid browsable transactions isn't quite as pretty。 Use the
+ <command>lstxns</command> command to list the transactions that you
+ are able to browse。 The list of browsable transactions is the same
+ list that <command>svnadmin lstxns</command> returns, and the same
+ list that is valid for use with <command>svnlook</command>'s
+ <option>--transaction</option> option。</para>
+
+ <para>Once you've finished using the shell, you can exit cleanly by
+ using the <command>exit</command> command。 Alternatively, you can
+ supply an end-of-file character—Control-D (though some Win32 Python
+ distributions use the Windows Control-Z convention instead)。</para>
</sect3>
<sect3 id="svn-ch-5-sect-3.1.5">
<title>Berkeley DB Utilities</title>
- <para>If you're using a Berkeley DB repository, then all of
- your versioned filesystem's structure and data live in a set
- of database tables within the <filename>db</filename>
- subdirectory of your repository. This subdirectory is a
- regular Berkeley DB environment directory, and can therefore
- be used in conjunction with any of the Berkeley database
- tools (you can see the documentation for these tools at
- SleepyCat's website, <systemitem
- class="url">http://www.sleepycat.com/</systemitem>).</para>
-
- <para>For day-to-day Subversion use, these tools are
- unnecessary. Most of the functionality typically needed for
- Subversion repositories has been duplicated in the
- <command>svnadmin</command> tool. For example,
- <command>svnadmin list-unused-dblogs</command> and
- <command>svnadmin list-dblogs</command> perform a
- subset of what is provided by the Berkeley
- <command>db_archive</command> command, and <command>svnadmin
- recover</command> reflects the common use cases of the
- <command>db_recover</command> utility.</para>
-
- <para>There are still a few Berkeley DB utilities that you
- might find useful. The <command>db_dump</command> and
- <command>db_load</command> programs write and read,
- respectively, a custom file format which describes the keys
- and values in a Berkeley DB database. Since Berkeley
- databases are not portable across machine architectures,
- this format is a useful way to transfer those databases from
- machine to machine, irrespective of architecture or
- operating system. Also, the <command>db_stat</command>
- utility can provide useful information about the status of
- your Berkeley DB environment, including detailed statistics
- about the locking and storage subsystems.</para>
-
+ <para>If you're using a Berkeley DB repository, then all of your
+ versioned filesystem's structure and data live in a set of database
+ tables within the <filename>db</filename> subdirectory of your
+ repository。 This subdirectory is a regular Berkeley DB environment
+ directory, and can therefore be used in conjunction with any of the
+ Berkeley database tools (you can see the documentation for these tools
+ at SleepyCat's website, <systemitem
+ class="url">http://www。sleepycat。com/</systemitem>)。</para>
+
+ <para>For day-to-day Subversion use, these tools are unnecessary。 Most
+ of the functionality typically needed for Subversion repositories has
+ been duplicated in the <command>svnadmin</command> tool。 For example,
+ <command>svnadmin list-unused-dblogs</command> and <command>svnadmin
+ list-dblogs</command> perform a subset of what is provided by the
+ Berkeley <command>db_archive</command> command, and <command>svnadmin
+ recover</command> reflects the common use cases of the
+ <command>db_recover</command> utility。</para>
+
+ <para>There are still a few Berkeley DB utilities that you might find
+ useful。 The <command>db_dump</command> and <command>db_load</command>
+ programs write and read, respectively, a custom file format which
+ describes the keys and values in a Berkeley DB database。 Since
+ Berkeley databases are not portable across machine architectures, this
+ format is a useful way to transfer those databases from machine to
+ machine, irrespective of architecture or operating system。 Also, the
+ <command>db_stat</command> utility can provide useful information
+ about the status of your Berkeley DB environment, including detailed
+ statistics about the locking and storage subsystems。</para>
</sect3>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-3.2">
- <title>Repository Cleanup</title>
-
- <para>Your Subversion repository will generally require very
- little attention once it is configured to your liking.
- However, there are times when some manual assistance from an
- administrator might be in order. The
- <command>svnadmin</command> utility provides some helpful
- functionality to assist you in performing such tasks as</para>
+ <title>资料库清理</title>
+
+ <para>Your Subversion repository will generally require very little
+ attention once it is configured to your liking。 However, there are times
+ when some manual assistance from an administrator might be in order。 The
+ <command>svnadmin</command> utility provides some helpful functionality
+ to assist you in performing such tasks as</para>
<itemizedlist>
<listitem>
- <para>modifying commit log messages,</para>
+ <para>modifying commit log messages,</para>
</listitem>
+
<listitem>
- <para>removing dead transactions,</para>
+ <para>removing dead transactions,</para>
</listitem>
+
<listitem>
- <para>recovering <quote>wedged</quote> repositories, and</para>
+ <para>recovering <quote>wedged</quote> repositories, and</para>
</listitem>
+
<listitem>
<para>migrating repository contents to a different
- repository.</para>
+ repository。</para>
</listitem>
</itemizedlist>
- <para>Perhaps the most commonly used of
- <command>svnadmin</command>'s subcommands is
- <literal>setlog</literal>. When a transaction is committed to
- the repository and promoted to a revision, the descriptive log
- message associated with that new revision (and provided by the
- user) is stored as an unversioned property attached to the
- revision itself. In other words, the repository remembers
- only the latest value of the property, and discards previous
- ones.</para>
+ <para>Perhaps the most commonly used of <command>svnadmin</command>'s
+ subcommands is <literal>setlog</literal>。 When a transaction is
+ committed to the repository and promoted to a revision, the descriptive
+ log message associated with that new revision (and provided by the user)
+ is stored as an unversioned property attached to the revision itself。 In
+ other words, the repository remembers only the latest value of the
+ property, and discards previous ones。</para>
<para>Sometimes a user will have an error in her log message (a
- misspelling or some misinformation, perhaps). If the
- repository is configured (using the
- <literal>pre-revprop-change</literal> and
- <literal>post-revprop-change</literal> hooks; see <xref
- linkend="svn-ch-5-sect-2.1"/>) to accept changes to this log
- message after the commit is finished, then the user can
- <quote>fix</quote> her log message remotely using the
- <command>svn</command> program's <literal>propset</literal>
- command (see <xref linkend="svn-ch-9"/>). However, because of
- the potential to lose information forever, Subversion
- repositories are not, by default, configured to allow changes
- to unversioned properties—except by an administrator.</para>
-
- <para>If a log message needs to be changed by an administrator,
- this can be done using <command>svnadmin setlog</command>.
- This command changes the log message (the
- <literal>svn:log</literal> property) on a given revision of a
- repository, reading the new value from a provided file.</para>
-
+ misspelling or some misinformation, perhaps)。 If the repository is
+ configured (using the <literal>pre-revprop-change</literal> and
+ <literal>post-revprop-change</literal> hooks; see <xref
+ linkend="svn-ch-5-sect-2.1" />) to accept changes to this log message
+ after the commit is finished, then the user can <quote>fix</quote> her
+ log message remotely using the <command>svn</command> program's
+ <literal>propset</literal> command (see <xref linkend="svn-ch-9" />)。
+ However, because of the potential to lose information forever,
+ Subversion repositories are not, by default, configured to allow changes
+ to unversioned properties—except by an administrator。</para>
+
+ <para>If a log message needs to be changed by an administrator, this can
+ be done using <command>svnadmin setlog</command>。 This command changes
+ the log message (the <literal>svn:log</literal> property) on a given
+ revision of a repository, reading the new value from a provided
+ file。</para>
+
<screen>
-$ echo "Here is the new, correct log message" > newlog.txt
-$ svnadmin setlog myrepos newlog.txt -r 388
+$ echo "Here is the new, correct log message" > newlog。txt
+$ svnadmin setlog myrepos newlog。txt -r 388
</screen>
-
- <para>The <command>svnadmin setlog</command> command alone is
- still bound by the same protections against modifying
- unversioned properties as a remote client is—the
- <literal>pre-</literal> and
- <literal>post-revprop-change</literal> hooks are still
- triggered, and therefore must be setup to accept changes of
- this nature. But an administrator can get around these
- protections by passing the <option>--bypass-hooks</option>
- option to the <command>svnadmin setlog</command> command.</para>
-
+
+ <para>The <command>svnadmin setlog</command> command alone is still
+ bound by the same protections against modifying unversioned properties
+ as a remote client is—the <literal>pre-</literal> and
+ <literal>post-revprop-change</literal> hooks are still triggered, and
+ therefore must be setup to accept changes of this nature。 But an
+ administrator can get around these protections by passing the
+ <option>--bypass-hooks</option> option to the <command>svnadmin
+ setlog</command> command。</para>
+
<warning>
- <para>Remember, though, that by bypassing the hooks, you are
- likely avoiding such things as email notifications of
- property changes, backup systems which track unversioned
- property changes, and so on. In other words, be very
- careful about what you are changing, and how you change
- it.</para>
+ <para>Remember, though, that by bypassing the hooks, you are likely
+ avoiding such things as email notifications of property changes,
+ backup systems which track unversioned property changes, and so on。 In
+ other words, be very careful about what you are changing, and how you
+ change it。</para>
</warning>
- <para>Another common use of <command>svnadmin</command> is to
- query the repository for outstanding—possibly
- dead—Subversion transactions. In the event that a
- commit should fail, the transaction is usually cleaned up.
- That is, the transaction itself is removed from the
- repository, and any data associated with (and only with) that
- transaction is removed as well. Occasionally, though, a
- failure occurs in such a way that the cleanup of the
- transaction never happens. This could happen for several
- reasons: perhaps the client operation was inelegantly
- terminated by the user, or a network failure might have
- occurred in the middle of an operation, etc. Regardless of
- the reason, dead transactions can happen. They don't do any
- real harm, other than consuming a small bit of disk space. A
- fastidious administrator may nonetheless want to remove
- them.</para>
+ <para>Another common use of <command>svnadmin</command> is to query the
+ repository for outstanding—possibly dead—Subversion transactions。 In the
+ event that a commit should fail, the transaction is usually cleaned up。
+ That is, the transaction itself is removed from the repository, and any
+ data associated with (and only with) that transaction is removed as
+ well。 Occasionally, though, a failure occurs in such a way that the
+ cleanup of the transaction never happens。 This could happen for several
+ reasons: perhaps the client operation was inelegantly terminated by the
+ user, or a network failure might have occurred in the middle of an
+ operation, etc。 Regardless of the reason, dead transactions can happen。
+ They don't do any real harm, other than consuming a small bit of disk
+ space。 A fastidious administrator may nonetheless want to remove
+ them。</para>
<para>You can use <command>svnadmin</command>'s
- <literal>lstxns</literal> command to list the names of the
- currently outstanding transactions.</para>
+ <literal>lstxns</literal> command to list the names of the currently
+ outstanding transactions。</para>
<screen>
$ svnadmin lstxns myrepos
@@ -1886,37 +1502,35 @@
</screen>
<para>Each item in the resultant output can then be used with
- <command>svnlook</command> (and its
- <option>--transaction</option> option) to determine who
- created the transaction, when it was created, what types of
- changes were made in the transaction—in other words,
- whether or not the transaction is a safe candidate for
- removal! If so, the transaction's name can be passed to
- <command>svnadmin rmtxns</command>, which will perform the
- cleanup of the transaction. In fact, the
- <literal>rmtxns</literal> subcommand can take its input
- directly from the output of <literal>lstxns</literal>!</para>
+ <command>svnlook</command> (and its <option>--transaction</option>
+ option) to determine who created the transaction, when it was created,
+ what types of changes were made in the transaction—in other words,
+ whether or not the transaction is a safe candidate for removal! If so,
+ the transaction's name can be passed to <command>svnadmin
+ rmtxns</command>, which will perform the cleanup of the transaction。 In
+ fact, the <literal>rmtxns</literal> subcommand can take its input
+ directly from the output of <literal>lstxns</literal>!</para>
<screen>
$ svnadmin rmtxns myrepos `svnadmin lstxns myrepos`
$
</screen>
- <para>If you use these two subcommands like this, you should
- consider making your repository temporarily inaccessible to
- clients. That way, no one can begin a legitimate transaction
- before you start your cleanup. The following is a little bit
- of shell-scripting that can quickly generate information about
- each outstanding transaction in your repository:</para>
+ <para>If you use these two subcommands like this, you should consider
+ making your repository temporarily inaccessible to clients。 That way, no
+ one can begin a legitimate transaction before you start your cleanup。
+ The following is a little bit of shell-scripting that can quickly
+ generate information about each outstanding transaction in your
+ repository:</para>
<example id="svn-ch-5-sect-3.2-ex-1">
- <title>txn-info.sh (Reporting Outstanding Transactions)</title>
+ <title>txn-info。sh (Reporting Outstanding Transactions)</title>
<programlisting>
#!/bin/sh
### Generate informational output for all outstanding transactions in
-### a Subversion repository.
+### a Subversion repository。
REPOS="${1}"
if [ "x$REPOS" = x ] ; then
@@ -1932,451 +1546,415 @@
</example>
<para>You can run the previous script using
- <command>/path/to/txn-info.sh /path/to/repos</command>. The
- output is basically a concatenation of several chunks of
- <command>svnlook info</command> output (see <xref
- linkend="svn-ch-5-sect-3.1.1"/>), and will look something
- like:</para>
+ <command>/path/to/txn-info。sh /path/to/repos</command>。 The output is
+ basically a concatenation of several chunks of <command>svnlook
+ info</command> output (see <xref linkend="svn-ch-5-sect-3.1.1" />), and
+ will look something like:</para>
<screen>
-$ txn-info.sh myrepos
+$ txn-info。sh myrepos
---[ Transaction 19 ]-------------------------------------------
sally
-2001-09-04 11:57:19 -0500 (Tue, 04 Sep 2001)
+2001-09-04 11:57:19 -0500 (Tue, 04 Sep 2001)
0
---[ Transaction 3a1 ]-------------------------------------------
harry
-2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001)
+2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001)
39
-Trying to commit over a faulty network.
+Trying to commit over a faulty network。
---[ Transaction a45 ]-------------------------------------------
sally
-2001-09-12 11:09:28 -0500 (Wed, 12 Sep 2001)
+2001-09-12 11:09:28 -0500 (Wed, 12 Sep 2001)
0
$
</screen>
- <para>An long-abandoned transaction usually represents some sort
- of failed or interrupted commit. A transaction's datestamp
- can provide interesting information—for example, how
- likely is it that an operation begun nine months ago is still
- active?</para>
-
- <para>In short, transaction cleanup decisions need not be made
- unwisely. Various sources of information—including
- Apache's error and access logs, the logs of successful
- Subversion commits, and so on—can be employed in the
- decision-making process. Finally, an administrator can often
- simply communicate with a seemingly dead transaction's owner
- (via email, for example) to verify that the transaction is, in
- fact, in a zombie state.</para>
-
+ <para>An long-abandoned transaction usually represents some sort of
+ failed or interrupted commit。 A transaction's datestamp can provide
+ interesting information—for example, how likely is it that an operation
+ begun nine months ago is still active?</para>
+
+ <para>In short, transaction cleanup decisions need not be made unwisely。
+ Various sources of information—including Apache's error and access logs,
+ the logs of successful Subversion commits, and so on—can be employed in
+ the decision-making process。 Finally, an administrator can often simply
+ communicate with a seemingly dead transaction's owner (via email, for
+ example) to verify that the transaction is, in fact, in a zombie
+ state。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-3.3">
- <title>Managing Disk Space</title>
+ <title>管理磁盘空间</title>
- <para>While the cost of storage has dropped incredibly in the
- past few years, disk usage is still a valid concern for
- administrators seeking to version large amounts of data.
- Every additional byte consumed by the live repository is a
- byte that needs to be backed up offsite, perhaps multiple
- times as part of rotating backup schedules. If using a
- Berkeley DB repository, the primary storage mechanism is a
- complex database system, it is useful to know what pieces of
- data need to remain on the live site, which need to be
- backed up, and which can be safely removed. This section is
- specific to Berkeley DB; FSFS repositories have no extra
- data that be cleaned up or reclaimed.</para>
-
- <para>Until recently, the largest offender of disk space usage
- with respect to Subversion repositories was the log files to
- which Berkeley DB performs its pre-writes before modifying
- the actual database files. These files capture all the
- actions taken along the route of changing the database from
- one state to another—while the database files reflect
- at any given time some state, the log files contain all the
- many changes along the way between states. As such, they
- can start to accumulate quite rapidly.</para>
-
- <para>Fortunately, beginning with the 4.2 release of Berkeley
- DB, the database environment has the ability to remove its
- own unused log files without any external procedures. Any
- repositories created using an <command>svnadmin</command>
- which is compiled against Berkeley DB version 4.2 or greater
- will be configured for this automatic log file removal. If
- you don't want this feature enabled, simply pass the
- <option>--bdb-log-keep</option> option to the
- <command>svnadmin create</command> command. If you forget
- to do this, or change your mind at a later time, simple edit
- the <filename>DB_CONFIG</filename> file found in your
- repository's <filename>db</filename> directory, comment out
- the line which contains the <literal>set_flags
- DB_LOG_AUTOREMOVE</literal> directive, and then run
- <command>svnadmin recover</command> on your repository to
- force the configuration changes to take effect. See <xref
- linkend="svn-ch-5-sect-2.2"/> for more information about
- database configuration.</para>
-
- <para>Without some sort of automatic log file removal in
- place, log files will accumulate as you use your repository.
- This is actually somewhat of a feature of the database
- system—you should be able to recreate your entire
- database using nothing but the log files, so these files can
- be useful for catastrophic database recovery. But
- typically, you'll want to archive the log files that are no
- longer in use by Berkeley DB, and then remove them from disk
- to conserve space. Use the <command>svnadmin
- list-unused-dblogs</command> command to list the unused
- log files:</para>
+ <para>While the cost of storage has dropped incredibly in the past few
+ years, disk usage is still a valid concern for administrators seeking to
+ version large amounts of data。 Every additional byte consumed by the
+ live repository is a byte that needs to be backed up offsite, perhaps
+ multiple times as part of rotating backup schedules。 If using a Berkeley
+ DB repository, the primary storage mechanism is a complex database
+ system, it is useful to know what pieces of data need to remain on the
+ live site, which need to be backed up, and which can be safely removed。
+ This section is specific to Berkeley DB; FSFS repositories have no extra
+ data that be cleaned up or reclaimed。</para>
+
+ <para>Until recently, the largest offender of disk space usage with
+ respect to Subversion repositories was the log files to which Berkeley
+ DB performs its pre-writes before modifying the actual database files。
+ These files capture all the actions taken along the route of changing
+ the database from one state to another—while the database files reflect
+ at any given time some state, the log files contain all the many changes
+ along the way between states。 As such, they can start to accumulate
+ quite rapidly。</para>
+
+ <para>Fortunately, beginning with the 4。2 release of Berkeley DB, the
+ database environment has the ability to remove its own unused log files
+ without any external procedures。 Any repositories created using an
+ <command>svnadmin</command> which is compiled against Berkeley DB
+ version 4。2 or greater will be configured for this automatic log file
+ removal。 If you don't want this feature enabled, simply pass the
+ <option>--bdb-log-keep</option> option to the <command>svnadmin
+ create</command> command。 If you forget to do this, or change your mind
+ at a later time, simple edit the <filename>DB_CONFIG</filename> file
+ found in your repository's <filename>db</filename> directory, comment
+ out the line which contains the <literal>set_flags
+ DB_LOG_AUTOREMOVE</literal> directive, and then run <command>svnadmin
+ recover</command> on your repository to force the configuration changes
+ to take effect。 See <xref linkend="svn-ch-5-sect-2.2" /> for more
+ information about database configuration。</para>
+
+ <para>Without some sort of automatic log file removal in place, log
+ files will accumulate as you use your repository。 This is actually
+ somewhat of a feature of the database system—you should be able to
+ recreate your entire database using nothing but the log files, so these
+ files can be useful for catastrophic database recovery。 But typically,
+ you'll want to archive the log files that are no longer in use by
+ Berkeley DB, and then remove them from disk to conserve space。 Use the
+ <command>svnadmin list-unused-dblogs</command> command to list the
+ unused log files:</para>
<screen>
$ svnadmin list-unused-dblogs /path/to/repos
-/path/to/repos/log.0000000031
-/path/to/repos/log.0000000032
-/path/to/repos/log.0000000033
+/path/to/repos/log。0000000031
+/path/to/repos/log。0000000032
+/path/to/repos/log。0000000033
$ svnadmin list-unused-dblogs /path/to/repos | xargs rm
## disk space reclaimed!
</screen>
- <para>To keep the size of the repository as small as possible,
- Subversion uses <firstterm>deltification</firstterm> (or,
- <quote>deltified storage</quote>) within the repository
- itself. Deltification involves encoding the representation
- of a chunk of data as a collection of differences against
- some other chunk of data. If the two pieces of data are
- very similar, this deltification results in storage savings
- for the deltified chunk—rather than taking up space
- equal to the size of the original data, it only takes up
- enough space to say, <quote>I look just like this other
- piece of data over here, except for the following couple of
- changes.</quote> Specifically, each time a new version of a
- file is committed to the repository, Subversion encodes the
- previous version (actually, several previous versions) as a
- delta against the new version. The result is that most of
- the repository data that tends to be sizable—namely,
- the contents of versioned files—is stored at a much
- smaller size than the original <quote>fulltext</quote>
- representation of that data.</para>
-
- <note>
- <para>Because all of the Subversion repository data that is
- subject to deltification is stored in a single Berkeley DB
- database file, reducing the size of the stored values will
- not necessarily reduce the size of the database file
- itself. Berkeley DB will, however, keep internal records
- of unused areas of the database file, and use those areas
- first before growing the size of the database file. So
- while deltification doesn't produce immediate space
- savings, it can drastically slow future growth of the
- database.</para>
- </note>
-
+ <para>To keep the size of the repository as small as possible,
+ Subversion uses <firstterm>deltification</firstterm> (or,
+ <quote>deltified storage</quote>) within the repository itself。
+ Deltification involves encoding the representation of a chunk of data as
+ a collection of differences against some other chunk of data。 If the two
+ pieces of data are very similar, this deltification results in storage
+ savings for the deltified chunk—rather than taking up space equal to the
+ size of the original data, it only takes up enough space to say,
+ <quote>I look just like this other piece of data over here, except for
+ the following couple of changes。</quote> Specifically, each time a new
+ version of a file is committed to the repository, Subversion encodes the
+ previous version (actually, several previous versions) as a delta
+ against the new version。 The result is that most of the repository data
+ that tends to be sizable—namely, the contents of versioned files—is
+ stored at a much smaller size than the original <quote>fulltext</quote>
+ representation of that data。</para>
+
+ <note>
+ <para>Because all of the Subversion repository data that is subject to
+ deltification is stored in a single Berkeley DB database file,
+ reducing the size of the stored values will not necessarily reduce the
+ size of the database file itself。 Berkeley DB will, however, keep
+ internal records of unused areas of the database file, and use those
+ areas first before growing the size of the database file。 So while
+ deltification doesn't produce immediate space savings, it can
+ drastically slow future growth of the database。</para>
+ </note>
</sect2>
-
+
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-3.4">
- <title>Repository Recovery</title>
+ <title>资料库的恢复</title>
+
+ <para>As mentioned in <xref linkend="svn-ch-5-sect-1.3.1" />, a Berkeley
+ DB repository can sometimes be left in frozen state if not closed
+ properly。 When this happens, an administrator needs to rewind the
+ database back into a consistent state。</para>
+
+ <para>In order to protect the data in your repository, Berkeley DB uses
+ a locking mechanism。 This mechanism ensures that portions of the
+ database are not simultaneously modified by multiple database accessors,
+ and that each process sees the data in the correct state when that data
+ is being read from the database。 When a process needs to change
+ something in the database, it first checks for the existence of a lock
+ on the target data。 If the data is not locked, the process locks the
+ data, makes the change it wants to make, and then unlocks the data。
+ Other processes are forced to wait until that lock is removed before
+ they are permitted to continue accessing that section of the
+ database。</para>
+
+ <para>In the course of using your Subversion repository, fatal errors
+ (such as running out of disk space or available memory) or interruptions
+ can prevent a process from having the chance to remove the locks it has
+ placed in the database。 The result is that the back-end database system
+ gets <quote>wedged</quote>。 When this happens, any attempts to access
+ the repository hang indefinitely (since each new accessor is waiting for
+ a lock to go away—which isn't going to happen)。</para>
+
+ <para>First, if this happens to your repository, don't panic。 The
+ Berkeley DB filesystem takes advantage of database transactions and
+ checkpoints and pre-write journaling to ensure that only the most
+ catastrophic of events <footnote>
+ <para>E。g。: hard drive + huge electromagnet = disaster。</para>
+ </footnote> can permanently destroy a database environment。 A
+ sufficiently paranoid repository administrator will be making off-site
+ backups of the repository data in some fashion, but don't call your
+ system administrator to restore a backup tape just yet。</para>
+
+ <para>Secondly, use the following recipe to attempt to
+ <quote>unwedge</quote> your repository:</para>
- <para>As mentioned in <xref linkend="svn-ch-5-sect-1.3.1"/>, a
- Berkeley DB repository can sometimes be left in frozen state
- if not closed properly. When this happens, an administrator
- needs to rewind the database back into a consistent
- state.</para>
-
- <para>In order to protect the data in your repository, Berkeley
- DB uses a locking mechanism. This mechanism ensures that
- portions of the database are not simultaneously modified by
- multiple database accessors, and that each process sees the
- data in the correct state when that data is being read from
- the database. When a process needs to change something in the
- database, it first checks for the existence of a lock on the
- target data. If the data is not locked, the process locks the
- data, makes the change it wants to make, and then unlocks the
- data. Other processes are forced to wait until that lock is
- removed before they are permitted to continue accessing that
- section of the database.</para>
-
- <para>In the course of using your Subversion repository, fatal
- errors (such as running out of disk space or available memory)
- or interruptions can prevent a process from having the chance to
- remove the locks it has placed in the database. The result is
- that the back-end database system gets <quote>wedged</quote>.
- When this happens, any attempts to access the repository hang
- indefinitely (since each new accessor is waiting for a lock to
- go away—which isn't going to happen).</para>
-
- <para>First, if this happens to your repository, don't panic.
- The Berkeley DB filesystem takes advantage of database
- transactions and checkpoints and pre-write journaling to
- ensure that only the most catastrophic of events
- <footnote>
- <para>E.g.: hard drive + huge electromagnet = disaster.</para>
- </footnote>
- can permanently destroy a database environment. A
- sufficiently paranoid repository administrator will be making
- off-site backups of the repository data in some fashion, but
- don't call your system administrator to restore a backup tape
- just yet.</para>
-
- <para>Secondly, use the following recipe to attempt to
- <quote>unwedge</quote> your repository:</para>
-
<orderedlist>
<listitem>
- <para>Make sure that there are no processes accessing (or
- attempting to access) the repository. For networked
- repositories, this means shutting down the Apache HTTP
- Server, too.</para>
- </listitem>
- <listitem>
- <para>Become the user who owns and manages the repository.
- This is important, as recovering a repository while
- running as the wrong user can tweak the permissions of the
- repository's files in such a way that your repository will
- still be inaccessible even after it is
- <quote>unwedged</quote>.</para>
+ <para>Make sure that there are no processes accessing (or attempting
+ to access) the repository。 For networked repositories, this means
+ shutting down the Apache HTTP Server, too。</para>
</listitem>
+
+ <listitem>
+ <para>Become the user who owns and manages the repository。 This is
+ important, as recovering a repository while running as the wrong
+ user can tweak the permissions of the repository's files in such a
+ way that your repository will still be inaccessible even after it is
+ <quote>unwedged</quote>。</para>
+ </listitem>
+
<listitem>
<para>Run the command <command>svnadmin recover
- /path/to/repos</command>. You should see output like
- this:</para>
-
+ /path/to/repos</command>。 You should see output like this:</para>
+
<screen>
-Repository lock acquired.
-Please wait; recovering the repository may take some time...
+Repository lock acquired。
+Please wait; recovering the repository may take some time。。。
-Recovery completed.
-The latest repos revision is 19.
+Recovery completed。
+The latest repos revision is 19。
</screen>
- <para>This command may take many minutes to complete.</para>
+
+ <para>This command may take many minutes to complete。</para>
</listitem>
+
<listitem>
- <para>Restart the Subversion server.</para>
+ <para>Restart the Subversion server。</para>
</listitem>
</orderedlist>
-
- <para>This procedure fixes almost every case of repository
- lock-up. Make sure that you run this command as the user that
- owns and manages the database, not just as
- <literal>root</literal>. Part of the recovery process might
- involve recreating from scratch various database files (shared
- memory regions, for example). Recovering as
- <literal>root</literal> will create those files such that they
- are owned by <literal>root</literal>, which means that even
- after you restore connectivity to your repository, regular
- users will be unable to access it.</para>
-
- <para>If the previous procedure, for some reason, does not
- successfully unwedge your repository, you should do two
- things. First, move your broken repository out of the way and
- restore your latest backup of it. Then, send an email to the
- Subversion user list (at
- <email>users at subversion.tigris.org</email>) describing your
- problem in detail. Data integrity is an extremely high
- priority to the Subversion developers.</para>
+ <para>This procedure fixes almost every case of repository lock-up。 Make
+ sure that you run this command as the user that owns and manages the
+ database, not just as <literal>root</literal>。 Part of the recovery
+ process might involve recreating from scratch various database files
+ (shared memory regions, for example)。 Recovering as
+ <literal>root</literal> will create those files such that they are owned
+ by <literal>root</literal>, which means that even after you restore
+ connectivity to your repository, regular users will be unable to access
+ it。</para>
+
+ <para>If the previous procedure, for some reason, does not successfully
+ unwedge your repository, you should do two things。 First, move your
+ broken repository out of the way and restore your latest backup of it。
+ Then, send an email to the Subversion user list (at
+ <email>users at subversion。tigris。org</email>) describing your problem in
+ detail。 Data integrity is an extremely high priority to the Subversion
+ developers。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-3.5">
- <title>Migrating a Repository</title>
-
- <para>A Subversion filesystem has its data spread throughout
- various database tables in a fashion generally understood by
- (and of interest to) only the Subversion developers
- themselves. However, circumstances may arise that call for
- all, or some subset, of that data to be collected into a
- single, portable, flat file format. Subversion provides such
- a mechanism, implemented in a pair of
- <command>svnadmin</command> subcommands:
- <literal>dump</literal> and <literal>load</literal>.</para>
-
- <para>The most common reason to dump and load a Subversion
- repository is due to changes in Subversion itself. As
- Subversion matures, there are times when certain changes made
- to the back-end database schema cause Subversion to be
- incompatible with previous versions of the repository. Other
- reasons for dumping and loading might be to migrate a Berkeley
- DB repository to a new OS or CPU architecture, or to switch
- between Berkeley DB and FSFS back-ends. The recommended
- course of action is relatively simple:</para>
-
+ <title>资料库的移植</title>
+
+ <para>A Subversion filesystem has its data spread throughout various
+ database tables in a fashion generally understood by (and of interest
+ to) only the Subversion developers themselves。 However, circumstances
+ may arise that call for all, or some subset, of that data to be
+ collected into a single, portable, flat file format。 Subversion provides
+ such a mechanism, implemented in a pair of <command>svnadmin</command>
+ subcommands: <literal>dump</literal> and <literal>load</literal>。</para>
+
+ <para>The most common reason to dump and load a Subversion repository is
+ due to changes in Subversion itself。 As Subversion matures, there are
+ times when certain changes made to the back-end database schema cause
+ Subversion to be incompatible with previous versions of the repository。
+ Other reasons for dumping and loading might be to migrate a Berkeley DB
+ repository to a new OS or CPU architecture, or to switch between
+ Berkeley DB and FSFS back-ends。 The recommended course of action is
+ relatively simple:</para>
+
<orderedlist>
<listitem>
<para>Using your <emphasis>current</emphasis> version of
- <command>svnadmin</command>, dump your repositories to
- dump files.</para>
+ <command>svnadmin</command>, dump your repositories to dump
+ files。</para>
</listitem>
+
<listitem>
- <para>Upgrade to the new version of Subversion.</para>
+ <para>Upgrade to the new version of Subversion。</para>
</listitem>
+
<listitem>
- <para>Move your old repositories out of the way, and create
- new empty ones in their place using your
- <emphasis>new</emphasis> <command>svnadmin</command>.</para>
+ <para>Move your old repositories out of the way, and create new
+ empty ones in their place using your <emphasis>new</emphasis>
+ <command>svnadmin</command>。</para>
</listitem>
+
<listitem>
<para>Again using your <emphasis>new</emphasis>
- <command>svnadmin</command>, load your dump files into
- their respective, just-created repositories.</para>
+ <command>svnadmin</command>, load your dump files into their
+ respective, just-created repositories。</para>
+ </listitem>
+
+ <listitem>
+ <para>Be sure to copy any customizations from your old repositories
+ to the new ones, including <filename>DB_CONFIG</filename> files and
+ hook scripts。 You'll want to pay attention to the release notes for
+ the new release of Subversion to see if any changes since your last
+ upgrade affect those hooks or configuration options。</para>
</listitem>
+
<listitem>
- <para>Be sure to copy any customizations from your old
- repositories to the new ones, including
- <filename>DB_CONFIG</filename> files and hook scripts.
- You'll want to pay attention to the release notes for the
- new release of Subversion to see if any changes since your
- last upgrade affect those hooks or configuration
- options.</para>
- </listitem>
- <listitem>
- <para>If the migration process made your repository
- accessible at a different URL (e.g. moved to a different
- computer, or is being accessed via a different schema),
- then you'll probably want to tell your users to run
- <command>svn switch --relocate</command> on their existing
- working copies. See <xref
- linkend="svn-ch-9-sect-1.2-re-switch"/>.</para>
+ <para>If the migration process made your repository accessible at a
+ different URL (e。g。 moved to a different computer, or is being
+ accessed via a different schema), then you'll probably want to tell
+ your users to run <command>svn switch --relocate</command> on their
+ existing working copies。 See <xref
+ linkend="svn-ch-9-sect-1.2-re-switch" />。</para>
</listitem>
</orderedlist>
- <para><command>svnadmin dump</command> will output a range of
- repository revisions that are formatted using Subversion's
- custom filesystem dump format. The dump format is printed to
- the standard output stream, while informative messages are
- printed to the standard error stream. This allows you to
- redirect the output stream to a file while watching the status
- output in your terminal window. For example:</para>
+ <para><command>svnadmin dump</command> will output a range of repository
+ revisions that are formatted using Subversion's custom filesystem dump
+ format。 The dump format is printed to the standard output stream, while
+ informative messages are printed to the standard error stream。 This
+ allows you to redirect the output stream to a file while watching the
+ status output in your terminal window。 For example:</para>
<screen>
$ svnlook youngest myrepos
26
$ svnadmin dump myrepos > dumpfile
-* Dumped revision 0.
-* Dumped revision 1.
-* Dumped revision 2.
-…
-* Dumped revision 25.
-* Dumped revision 26.
-</screen>
-
- <para>At the end of the process, you will have a single file
- (<filename>dumpfile</filename> in the previous example) that
- contains all the data stored in your repository in the
- requested range of revisions. Note that <command>svnadmin
- dump</command> is reading revision trees from the repository
- just like any other <quote>reader</quote> process would
- (<command>svn checkout</command>, for example.) So it's safe
- to run this command at any time.</para>
-
- <para>The other subcommand in the pair, <command>svnadmin
- load</command>, parses the standard input stream as a
- Subversion repository dump file, and effectively replays those
- dumped revisions into the target repository for that
- operation. It also gives informative feedback, this time
- using the standard output stream:</para>
+* Dumped revision 0。
+* Dumped revision 1。
+* Dumped revision 2。
+…
+* Dumped revision 25。
+* Dumped revision 26。
+</screen>
+
+ <para>At the end of the process, you will have a single file
+ (<filename>dumpfile</filename> in the previous example) that contains
+ all the data stored in your repository in the requested range of
+ revisions。 Note that <command>svnadmin dump</command> is reading
+ revision trees from the repository just like any other
+ <quote>reader</quote> process would (<command>svn checkout</command>,
+ for example。) So it's safe to run this command at any time。</para>
+
+ <para>The other subcommand in the pair, <command>svnadmin
+ load</command>, parses the standard input stream as a Subversion
+ repository dump file, and effectively replays those dumped revisions
+ into the target repository for that operation。 It also gives informative
+ feedback, this time using the standard output stream:</para>
<screen>
$ svnadmin load newrepos < dumpfile
-<<< Started new txn, based on original revision 1
- * adding path : A ... done.
- * adding path : A/B ... done.
- …
+<<< Started new txn, based on original revision 1
+ * adding path : A 。。。 done。
+ * adding path : A/B 。。。 done。
+ …
------- Committed new rev 1 (loaded from original rev 1) >>>
-<<< Started new txn, based on original revision 2
- * editing path : A/mu ... done.
- * editing path : A/D/G/rho ... done.
+<<< Started new txn, based on original revision 2
+ * editing path : A/mu 。。。 done。
+ * editing path : A/D/G/rho 。。。 done。
------- Committed new rev 2 (loaded from original rev 2) >>>
-…
+…
-<<< Started new txn, based on original revision 25
- * editing path : A/D/gamma ... done.
+<<< Started new txn, based on original revision 25
+ * editing path : A/D/gamma 。。。 done。
------- Committed new rev 25 (loaded from original rev 25) >>>
-<<< Started new txn, based on original revision 26
- * adding path : A/Z/zeta ... done.
- * editing path : A/mu ... done.
+<<< Started new txn, based on original revision 26
+ * adding path : A/Z/zeta 。。。 done。
+ * editing path : A/mu 。。。 done。
------- Committed new rev 26 (loaded from original rev 26) >>>
</screen>
- <para>Note that because <command>svnadmin</command> uses
- standard input and output streams for the repository dump and
- load process, people who are feeling especially saucy can try
- things like this (perhaps even using different versions of
- <command>svnadmin</command> on each side of the pipe):</para>
-
+ <para>Note that because <command>svnadmin</command> uses standard input
+ and output streams for the repository dump and load process, people who
+ are feeling especially saucy can try things like this (perhaps even
+ using different versions of <command>svnadmin</command> on each side of
+ the pipe):</para>
+
<screen>
$ svnadmin create newrepos
$ svnadmin dump myrepos | svnadmin load newrepos
</screen>
- <para>By default, the dump file will be quite large—much
- larger than the repository itself. That's because every
- version of every file is expressed as a full text in the
- dump file. This is the fastest and simplest behavior, and nice
- if you're piping the dump data directly into some other
- process (such as a compression program, filtering program, or
- into a loading process). But if you're creating a dump file for
- longer-term storage, you'll likely want to save disk space by
- using the <option>--deltas</option> switch. With this option,
- successive revisions of files will be output as compressed,
- binary differences—just as file revisions are stored in
- a repository. This option is slower, but results in a
- dump file much closer in size to the original
- repository.</para>
-
- <para>We mentioned previously that <command>svnadmin
- dump</command> outputs a range of revisions. Use the
- <option>--revision</option> option to specify a single
- revision to dump, or a range of revisions. If you omit this
- option, all the existing repository revisions will be
- dumped.</para>
+ <para>By default, the dump file will be quite large—much larger than the
+ repository itself。 That's because every version of every file is
+ expressed as a full text in the dump file。 This is the fastest and
+ simplest behavior, and nice if you're piping the dump data directly into
+ some other process (such as a compression program, filtering program, or
+ into a loading process)。 But if you're creating a dump file for
+ longer-term storage, you'll likely want to save disk space by using the
+ <option>--deltas</option> switch。 With this option, successive revisions
+ of files will be output as compressed, binary differences—just as file
+ revisions are stored in a repository。 This option is slower, but results
+ in a dump file much closer in size to the original repository。</para>
+
+ <para>We mentioned previously that <command>svnadmin dump</command>
+ outputs a range of revisions。 Use the <option>--revision</option> option
+ to specify a single revision to dump, or a range of revisions。 If you
+ omit this option, all the existing repository revisions will be
+ dumped。</para>
<screen>
-$ svnadmin dump myrepos --revision 23 > rev-23.dumpfile
-$ svnadmin dump myrepos --revision 100:200 > revs-100-200.dumpfile
+$ svnadmin dump myrepos --revision 23 > rev-23。dumpfile
+$ svnadmin dump myrepos --revision 100:200 > revs-100-200。dumpfile
</screen>
- <para>As Subversion dumps each new revision, it outputs only
- enough information to allow a future loader to re-create that
- revision based on the previous one. In other words, for any
- given revision in the dump file, only the items that were
- changed in that revision will appear in the dump. The only
- exception to this rule is the first revision that is dumped
- with the current <command>svnadmin dump</command>
- command.</para>
-
- <para>By default, Subversion will not express the first dumped
- revision as merely differences to be applied to the previous
- revision. For one thing, there is no previous revision in the
- dump file! And secondly, Subversion cannot know the state of
- the repository into which the dump data will be loaded (if it
- ever, in fact, occurs). To ensure that the output of each
- execution of <command>svnadmin dump</command> is
- self-sufficient, the first dumped revision is by default a
- full representation of every directory, file, and property in
- that revision of the repository.</para>
-
- <para>However, you can change this default behavior. If you add
- the <option>--incremental</option> option when you dump your
- repository, <command>svnadmin</command> will compare the first
- dumped revision against the previous revision in the
- repository, the same way it treats every other revision that
- gets dumped. It will then output the first revision exactly
- as it does the rest of the revisions in the dump
- range—mentioning only the changes that occurred in that
- revision. The benefit of this is that you can create several
- small dump files that can be loaded in succession, instead of
- one large one, like so:</para>
+ <para>As Subversion dumps each new revision, it outputs only enough
+ information to allow a future loader to re-create that revision based on
+ the previous one。 In other words, for any given revision in the dump
+ file, only the items that were changed in that revision will appear in
+ the dump。 The only exception to this rule is the first revision that is
+ dumped with the current <command>svnadmin dump</command> command。</para>
+
+ <para>By default, Subversion will not express the first dumped revision
+ as merely differences to be applied to the previous revision。 For one
+ thing, there is no previous revision in the dump file! And secondly,
+ Subversion cannot know the state of the repository into which the dump
+ data will be loaded (if it ever, in fact, occurs)。 To ensure that the
+ output of each execution of <command>svnadmin dump</command> is
+ self-sufficient, the first dumped revision is by default a full
+ representation of every directory, file, and property in that revision
+ of the repository。</para>
+
+ <para>However, you can change this default behavior。 If you add the
+ <option>--incremental</option> option when you dump your repository,
+ <command>svnadmin</command> will compare the first dumped revision
+ against the previous revision in the repository, the same way it treats
+ every other revision that gets dumped。 It will then output the first
+ revision exactly as it does the rest of the revisions in the dump
+ range—mentioning only the changes that occurred in that revision。 The
+ benefit of this is that you can create several small dump files that can
+ be loaded in succession, instead of one large one, like so:</para>
<screen>
$ svnadmin dump myrepos --revision 0:1000 > dumpfile1
@@ -2384,8 +1962,8 @@
$ svnadmin dump myrepos --revision 2001:3000 --incremental > dumpfile3
</screen>
- <para>These dump files could be loaded into a new repository with
- the following command sequence:</para>
+ <para>These dump files could be loaded into a new repository with the
+ following command sequence:</para>
<screen>
$ svnadmin load newrepos < dumpfile1
@@ -2394,99 +1972,93 @@
</screen>
<para>Another neat trick you can perform with this
- <option>--incremental</option> option involves appending to an
- existing dump file a new range of dumped revisions. For
- example, you might have a <literal>post-commit</literal> hook
- that simply appends the repository dump of the single revision
- that triggered the hook. Or you might have a script that runs
- nightly to append dump file data for all the revisions that
- were added to the repository since the last time the script
- ran. Used like this, <command>svnadmin</command>'s
- <literal>dump</literal> and <literal>load</literal> commands
- can be a valuable means by which to backup changes to your
- repository over time in case of a system crash or some other
- catastrophic event.</para>
-
- <para>The dump format can also be used to merge the contents of
- several different repositories into a single repository. By
- using the <option>--parent-dir</option> option of <command>svnadmin
- load</command>, you can specify a new virtual root directory
- for the load process. That means if you have dump files for
- three repositories, say <filename>calc-dumpfile</filename>,
- <filename>cal-dumpfile</filename>, and
- <filename>ss-dumpfile</filename>, you can first create a new
- repository to hold them all:</para>
+ <option>--incremental</option> option involves appending to an existing
+ dump file a new range of dumped revisions。 For example, you might have a
+ <literal>post-commit</literal> hook that simply appends the repository
+ dump of the single revision that triggered the hook。 Or you might have a
+ script that runs nightly to append dump file data for all the revisions
+ that were added to the repository since the last time the script ran。
+ Used like this, <command>svnadmin</command>'s <literal>dump</literal>
+ and <literal>load</literal> commands can be a valuable means by which to
+ backup changes to your repository over time in case of a system crash or
+ some other catastrophic event。</para>
+
+ <para>The dump format can also be used to merge the contents of several
+ different repositories into a single repository。 By using the
+ <option>--parent-dir</option> option of <command>svnadmin
+ load</command>, you can specify a new virtual root directory for the
+ load process。 That means if you have dump files for three repositories,
+ say <filename>calc-dumpfile</filename>,
+ <filename>cal-dumpfile</filename>, and <filename>ss-dumpfile</filename>,
+ you can first create a new repository to hold them all:</para>
<screen>
$ svnadmin create /path/to/projects
$
</screen>
- <para>Then, make new directories in the repository which will
- encapsulate the contents of each of the three previous
- repositories:</para>
+ <para>Then, make new directories in the repository which will
+ encapsulate the contents of each of the three previous
+ repositories:</para>
<screen>
$ svn mkdir -m "Initial project roots" \
file:///path/to/projects/calc \
file:///path/to/projects/calendar \
file:///path/to/projects/spreadsheet
-Committed revision 1.
+Committed revision 1。
$
</screen>
- <para>Lastly, load the individual dump files into their
- respective locations in the new repository:</para>
+ <para>Lastly, load the individual dump files into their respective
+ locations in the new repository:</para>
<screen>
$ svnadmin load /path/to/projects --parent-dir calc < calc-dumpfile
-…
+…
$ svnadmin load /path/to/projects --parent-dir calendar < cal-dumpfile
-…
+…
$ svnadmin load /path/to/projects --parent-dir spreadsheet < ss-dumpfile
-…
+…
$
</screen>
- <para>We'll mention one final way to use the Subversion
- repository dump format—conversion from a different
- storage mechanism or version control system altogether.
- Because the dump file format is, for the most part,
- human-readable,
- <footnote>
- <para>The Subversion repository dump format resembles
- an RFC-822 format, the same type of format used for most
- email.</para>
- </footnote>
- it should be relatively easy to describe generic sets of
- changes—each of which should be treated as a new
- revision—using this file format. In fact, the
- <command>cvs2svn.py</command> utility (see <xref
- linkend="svn-ap-a-sect-11"/>) uses the dump format to represent the
- contents of a CVS repository so that those contents can be
- moved in a Subversion repository.</para>
-
+ <para>We'll mention one final way to use the Subversion repository dump
+ format—conversion from a different storage mechanism or version control
+ system altogether。 Because the dump file format is, for the most part,
+ human-readable, <footnote>
+ <para>The Subversion repository dump format resembles an RFC-822
+ format, the same type of format used for most email。</para>
+ </footnote> it should be relatively easy to describe generic sets of
+ changes—each of which should be treated as a new revision—using this
+ file format。 In fact, the <command>cvs2svn。py</command> utility (see
+ <xref linkend="svn-ap-a-sect-11" />) uses the dump format to represent
+ the contents of a CVS repository so that those contents can be moved in
+ a Subversion repository。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-3.6">
<title>版本库备份</title>
- <para>尽管现代计算机的诞生带来了许多便利,但有一件事听起来是完全正确的—有时候,事情变的糟糕,很糟糕,动力损耗、网络中断、坏掉的内存和损坏的硬盘都是对魔鬼的一种体验,即使对于最尽职的管理员,命运也早已注定。所以我们来到了这个最重要的主题—怎样备份你的版本库数据。</para>
+ <para>尽管现代计算机的诞生带来了许多便利,但有一件事听起来是完全正确的—有时候,事情变的糟糕,很糟糕,动力损耗、网络中断、坏掉的内存和损坏的硬盘都是对魔鬼的一种体验,即使对于最尽职的管理员,命运也早已注定。所以我们来到了这个最重要的主题—怎样备份你的版本库数据。</para>
- <para>Subversion版本库管理员通常有两种备份方式—增量的和完全的。我们在早先的章节曾经讨论过如何使用<command>svnadmin dump --incremental</command>命令执行增量备份(见<xref
- linkend="svn-ch-5-sect-3.5"/>),从本质上讲,这个方法只是备份了从你上次备份版本库到现在的变化。</para>
+ <para>Subversion版本库管理员通常有两种备份方式—增量的和完全的。我们在早先的章节曾经讨论过如何使用<command>svnadmin
+ dump --incremental</command>命令执行增量备份(见<xref
+ linkend="svn-ch-5-sect-3.5" />),从本质上讲,这个方法只是备份了从你上次备份版本库到现在的变化。</para>
<para>一个完全的版本库备份照字面上讲就是对整个版本库目录的复制(包括伯克利数据库或者文件FSFS环境),现在,除非你临时关闭了其他对版本库的访问,否则仅仅做一次迭代的拷贝会有产生错误备份的风险,因为有人可能会在并行的写数据库。</para>
- <para>如果是伯克利数据库,恼人的文档描述了保证安全拷贝的步骤,对于FSFS的数据,也有类似的顺序。我们有更好的选择,我们不需要自己去实现这个算法,因为Subversion开发小组已经为你实现了这些算法。Subversion源文件分发版本的<filename>tools/backup/</filename>目录有一个<command>hot-backup.py</command>文件,给定版本库路径和备份路径,<command>hot-backup.py</command>—是一个包裹了<command>svnadmin hotcopy</command>但更加智能的命令—将会执行必要的步骤来备份你的活动的版本库—不需要你首先禁止公共的版本库访问—而且之后会从你的版本库清理死掉的伯克利日志文件。</para>
+ <para>如果是伯克利数据库,恼人的文档描述了保证安全拷贝的步骤,对于FSFS的数据,也有类似的顺序。我们有更好的选择,我们不需要自己去实现这个算法,因为Subversion开发小组已经为你实现了这些算法。Subversion源文件分发版本的<filename>tools/backup/</filename>目录有一个<command>hot-backup。py</command>文件,给定版本库路径和备份路径,<command>hot-backup。py</command>—是一个包裹了<command>svnadmin
+ hotcopy</command>但更加智能的命令—将会执行必要的步骤来备份你的活动的版本库—不需要你首先禁止公共的版本库访问—而且之后会从你的版本库清理死掉的伯克利日志文件。</para>
- <para>
- 甚至当你用了一个增量备份时,你也会希望有计划的运行这个程序。举个例子,你考虑在你的程序调度程序(如Unix下的<command>cron</command>)里加入<command>hot-backup.py</command>,或者你喜欢更加细致的备份解决方案,你可以让你的post-commit的钩子脚本执行<command>hot-backup.py</command>(见see <xref
- linkend="svn-ch-5-sect-2.1" />),这样会导致你的版本库的每次提交执行一次备份,只要在你的<filename>hooks/post-commit</filename>脚本里添加如下代码:</para>
+ <para>甚至当你用了一个增量备份时,你也会希望有计划的运行这个程序。举个例子,你考虑在你的程序调度程序(如Unix下的<command>cron</command>)里加入<command>hot-backup。py</command>,或者你喜欢更加细致的备份解决方案,你可以让你的post-commit的钩子脚本执行<command>hot-backup。py</command>(见see
+ <xref
+ linkend="svn-ch-5-sect-2.1" />),这样会导致你的版本库的每次提交执行一次备份,只要在你的<filename>hooks/post-commit</filename>脚本里添加如下代码:</para>
<programlisting>
-(cd /path/to/hook/scripts; ./hot-backup.py ${REPOS} /path/to/backups &)
+(cd /path/to/hook/scripts; 。/hot-backup。py ${REPOS} /path/to/backups &)
</programlisting>
<para>作为结果的备份是一个完全功能的版本库,当发生严重错误时可以作为你的活动版本库的替换。</para>
@@ -2496,105 +2068,100 @@
<para>增量备份会使用的版本库导出格式在Subversion的数据库模式改变时非常完美,因此当我们升级Subversion数据库模式的时候,一个完整的版本库导出和导入是必须的,做一半工作非常的容易(导出部分),不幸的是,增量备份的创建和恢复会占用很长时间,因为每一次提交都会被重放,对于导出文件和版本库。</para>
<para>在每一种备份情境下,版本库管理员需要意识到对未版本化的修订版本属性对备份的影响,因为这些修改本身不会产生新的修订,他们不会触发post-commit触发器的钩子程序,也不会触发pre-revprop-change和post-revprop-change的钩子。
- <footnote>
+ <footnote>
<para><command>svnadmin setlog</command>可以被绕过钩子程序被调用。</para>
- </footnote> 而且因为你可以改变修订版本的属性,而不需要遵照时间顺序—你可在任何时刻是修改任何修订版本的属性—因此最新版本的增量备份不会捕捉到以前特定修订版本的属性修改。</para>
-
- <para>通常说来,在每次提交时,只有妄想狂才会备份整个版本库,然而,假设一个给定的版本库拥有一些恰当粒度得冗余机制(如每次提交的邮件),版本库管理员也许会希望将版本库的热备份引入到系统级的每夜备份,对大多数版本库,归档的提交邮件为保存资源提供了足够的冗余措施,至少对于最近的提交。但是它是你的数据—你喜欢怎样保护都可以。</para>
-
- <para>经常的,最好的版本库备份方式是混合的,你可以平衡完全和增量备份,另外配合提交邮件的归档,Subversion开发者,举个例子,在每个新的修订版本建立时备份Subversion的源代码版本库,并且保留所有的提交和属性修改通知文件。你的解决方案类似,必须迎合你的需要,平衡便利和你的偏执。然而这些不会改变你的硬件来自钢铁的命运。<footnote> <para>你知道的— 所有的术语只是她的
- <quote>变幻无常的手指</quote>.</para>
</footnote>
- 这一定会帮助你减少尝试的时间。</para>
+ 而且因为你可以改变修订版本的属性,而不需要遵照时间顺序—你可在任何时刻是修改任何修订版本的属性—因此最新版本的增量备份不会捕捉到以前特定修订版本的属性修改。</para>
+ <para>通常说来,在每次提交时,只有妄想狂才会备份整个版本库,然而,假设一个给定的版本库拥有一些恰当粒度得冗余机制(如每次提交的邮件),版本库管理员也许会希望将版本库的热备份引入到系统级的每夜备份,对大多数版本库,归档的提交邮件为保存资源提供了足够的冗余措施,至少对于最近的提交。但是它是你的数据—你喜欢怎样保护都可以。</para>
+
+ <para>经常的,最好的版本库备份方式是混合的,你可以平衡完全和增量备份,另外配合提交邮件的归档,Subversion开发者,举个例子,在每个新的修订版本建立时备份Subversion的源代码版本库,并且保留所有的提交和属性修改通知文件。你的解决方案类似,必须迎合你的需要,平衡便利和你的偏执。然而这些不会改变你的硬件来自钢铁的命运。<footnote>
+ <para>你知道的— 所有的术语只是她的 <quote>变幻无常的手指</quote>。</para>
+ </footnote> 这一定会帮助你减少尝试的时间。</para>
</sect2>
</sect1>
-
<!-- ******************************************************************* -->
+
<!-- *** SECTION 6: ADDING PROJECTS *** -->
+
<!-- ******************************************************************* -->
+
<sect1 id="svn-ch-5-sect-6">
<title>添加项目</title>
- <para>一旦你的版本库已经建立并且配置好了,剩下的就是使用了。
- Once your repository is created and configured, all that
- remains is to begin using it. If you have a collection of
- existing data that is ready to be placed under version control,
- you will more than likely want to use the <command>svn</command>
- client program's <literal>import</literal> subcommand to
- accomplish that. Before doing this, though, you should
- carefully consider your long-term plans for the repository. In
- this section, we will offer some advice on how to plan the
- layout of your repository, and how to get your data arranged in
- that layout.</para>
+ <para>一旦你的版本库已经建立并且配置好了,剩下的就是使用了。 Once your repository is created and
+ configured, all that remains is to begin using it。 If you have a
+ collection of existing data that is ready to be placed under version
+ control, you will more than likely want to use the <command>svn</command>
+ client program's <literal>import</literal> subcommand to accomplish that。
+ Before doing this, though, you should carefully consider your long-term
+ plans for the repository。 In this section, we will offer some advice on
+ how to plan the layout of your repository, and how to get your data
+ arranged in that layout。</para>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-6.1">
<title>Choosing a Repository Layout</title>
- <para>While Subversion allows you to move around versioned files
- and directories without any loss of information, doing so can
- still disrupt the workflow of those who access the repository
- often and come to expect things to be at certain locations.
- Try to peer into the future a bit; plan ahead before placing
- your data under version control. By <quote>laying out</quote>
- the contents of your repositories in an effective manner the
- first time, you can prevent a load of future headaches.</para>
-
- <para>There are a few things to consider when setting up
- Subversion repositories. Let's assume that as repository
- administrator, you will be responsible for supporting the
- version control system for several projects. The first
- decision is whether to use a single repository for multiple
- projects, or to give each project its own repository, or some
- compromise of these two.</para>
-
- <para>There are benefits to using a single repository for
- multiple projects, most obviously the lack of duplicated
- maintenance. A single repository means that there is one set
- of hook scripts, one thing to routinely backup, one thing to
- dump and load if Subversion releases an incompatible new
- version, and so on. Also, you can move data between projects
- easily, and without losing any historical versioning
- information.</para>
-
- <para>The downside of using a single repository is that
- different projects may have different commit mailing lists or
- different authentication and authorization requirements.
- Also, remember that Subversion uses repository-global revision
- numbers. Some folks don't like the fact that even though no
- changes have been made to their project lately, the youngest
- revision number for the repository keeps climbing because
- other projects are actively adding new revisions.</para>
-
- <para>A middle-ground approach can be taken, too. For example,
- projects can be grouped by how well they relate to each other.
- You might have a few repositories with a handful of projects
- in each repository. That way, projects that are likely to
- want to share data can do so easily, and as new revisions are
- added to the repository, at least the developers know that
- those new revisions are at least remotely related to everyone
- who uses that repository.</para>
-
- <para>After deciding how to organize your projects with respect
- to repositories, you'll probably want to think about directory
- hierarchies in the repositories themselves. Because
- Subversion uses regular directory copies for branching and
- tagging (see <xref linkend="svn-ch-4"/>), the Subversion
- community recommends that you choose a repository location for
- each <firstterm>project root</firstterm>—the
- <quote>top-most</quote> directory which contains data related
- to that project—and then create three subdirectories
- beneath that root: <filename>trunk</filename>, meaning the
- directory under which the main project development occurs;
- <filename>branches</filename>, which is a directory in which
- to create various named branches of the main development line;
- <filename>tags</filename>, which is a directory of branches
- that are created, and perhaps destroyed, but never
- changed.</para>
+ <para>While Subversion allows you to move around versioned files and
+ directories without any loss of information, doing so can still disrupt
+ the workflow of those who access the repository often and come to expect
+ things to be at certain locations。 Try to peer into the future a bit;
+ plan ahead before placing your data under version control。 By
+ <quote>laying out</quote> the contents of your repositories in an
+ effective manner the first time, you can prevent a load of future
+ headaches。</para>
+
+ <para>There are a few things to consider when setting up Subversion
+ repositories。 Let's assume that as repository administrator, you will be
+ responsible for supporting the version control system for several
+ projects。 The first decision is whether to use a single repository for
+ multiple projects, or to give each project its own repository, or some
+ compromise of these two。</para>
+
+ <para>There are benefits to using a single repository for multiple
+ projects, most obviously the lack of duplicated maintenance。 A single
+ repository means that there is one set of hook scripts, one thing to
+ routinely backup, one thing to dump and load if Subversion releases an
+ incompatible new version, and so on。 Also, you can move data between
+ projects easily, and without losing any historical versioning
+ information。</para>
+
+ <para>The downside of using a single repository is that different
+ projects may have different commit mailing lists or different
+ authentication and authorization requirements。 Also, remember that
+ Subversion uses repository-global revision numbers。 Some folks don't
+ like the fact that even though no changes have been made to their
+ project lately, the youngest revision number for the repository keeps
+ climbing because other projects are actively adding new
+ revisions。</para>
+
+ <para>A middle-ground approach can be taken, too。 For example, projects
+ can be grouped by how well they relate to each other。 You might have a
+ few repositories with a handful of projects in each repository。 That
+ way, projects that are likely to want to share data can do so easily,
+ and as new revisions are added to the repository, at least the
+ developers know that those new revisions are at least remotely related
+ to everyone who uses that repository。</para>
+
+ <para>After deciding how to organize your projects with respect to
+ repositories, you'll probably want to think about directory hierarchies
+ in the repositories themselves。 Because Subversion uses regular
+ directory copies for branching and tagging (see <xref
+ linkend="svn-ch-4" />), the Subversion community recommends that you
+ choose a repository location for each <firstterm>project
+ root</firstterm>—the <quote>top-most</quote> directory which contains
+ data related to that project—and then create three subdirectories
+ beneath that root: <filename>trunk</filename>, meaning the directory
+ under which the main project development occurs;
+ <filename>branches</filename>, which is a directory in which to create
+ various named branches of the main development line;
+ <filename>tags</filename>, which is a directory of branches that are
+ created, and perhaps destroyed, but never changed。</para>
- <para>For example, your repository might look like:</para>
+ <para>For example, your repository might look like:</para>
<screen>
/
@@ -2610,18 +2177,17 @@
trunk/
tags/
branches/
- …
+ …
</screen>
- <para>Note that it doesn't matter where in your repository each
- project root is. If you have only one project per repository,
- the logical place to put each project root is at the root of
- that project's respective repository. If you have multiple
- projects, you might want to arrange them in groups inside the
- repository, perhaps putting projects with similar goals or
- shared code in the same subdirectory, or maybe just grouping
- them alphabetically. Such an arrangement might look
- like:</para>
+ <para>Note that it doesn't matter where in your repository each project
+ root is。 If you have only one project per repository, the logical place
+ to put each project root is at the root of that project's respective
+ repository。 If you have multiple projects, you might want to arrange
+ them in groups inside the repository, perhaps putting projects with
+ similar goals or shared code in the same subdirectory, or maybe just
+ grouping them alphabetically。 Such an arrangement might look
+ like:</para>
<screen>
/
@@ -2634,42 +2200,38 @@
trunk/
tags/
branches/
- …
+ …
office/
spreadsheet/
trunk/
tags/
branches/
- …
+ …
</screen>
- <para>Lay out your repository in whatever way you see fit.
- Subversion does not expect or enforce a layout schema—in
- its eyes, a directory is a directory is a directory.
- Ultimately, you should choose the repository arrangement that
- meets the needs of the people who work on the projects that
- live there.</para>
-
+ <para>Lay out your repository in whatever way you see fit。 Subversion
+ does not expect or enforce a layout schema—in its eyes, a directory is a
+ directory is a directory。 Ultimately, you should choose the repository
+ arrangement that meets the needs of the people who work on the projects
+ that live there。</para>
</sect2>
<!-- ***************************************************************** -->
+
<sect2 id="svn-ch-5-sect-6.2">
- <title>Creating the Layout, and Importing Initial Data</title>
-
- <para>After deciding how to arrange the projects in your
- repository, you'll probably want to actually populate the
- repository with that layout and with initial project data.
- There are a couple of ways to do this in Subversion. You
- could use the <command>svn mkdir</command> command (see <xref
- linkend="svn-ch-9"/>) to create each directory in your
- skeletal repository layout, one-by-one. A quicker way to
- accomplish the same task is to use the <command>svn
- import</command> command (see <xref
- linkend="svn-ch-3-sect-7.3"/>). By first creating the layout
- in a temporary location on your drive, you can import the
- whole layout tree into the repository in a single
- commit:</para>
-
+ <title>Creating the Layout, and Importing Initial Data</title>
+
+ <para>After deciding how to arrange the projects in your repository,
+ you'll probably want to actually populate the repository with that
+ layout and with initial project data。 There are a couple of ways to do
+ this in Subversion。 You could use the <command>svn mkdir</command>
+ command (see <xref linkend="svn-ch-9" />) to create each directory in
+ your skeletal repository layout, one-by-one。 A quicker way to accomplish
+ the same task is to use the <command>svn import</command> command (see
+ <xref linkend="svn-ch-3-sect-7.3" />)。 By first creating the layout in a
+ temporary location on your drive, you can import the whole layout tree
+ into the repository in a single commit:</para>
+
<screen>
$ mkdir tmpdir
$ cd tmpdir
@@ -2681,8 +2243,8 @@
$ mkdir projectB/trunk
$ mkdir projectB/branches
$ mkdir projectB/tags
-…
-$ svn import . file:///path/to/repos --message 'Initial repository layout'
+…
+$ svn import 。 file:///path/to/repos --message 'Initial repository layout'
Adding projectA
Adding projectA/trunk
Adding projectA/branches
@@ -2691,62 +2253,53 @@
Adding projectB/trunk
Adding projectB/branches
Adding projectB/tags
-…
-Committed revision 1.
-$ cd ..
+…
+Committed revision 1。
+$ cd 。。
$ rm -rf tmpdir
$
</screen>
<para>You can verify the results of the import by running the
- <command>svn list</command> command:</para>
+ <command>svn list</command> command:</para>
<screen>
$ svn list --verbose file:///path/to/repos
1 harry May 08 21:48 projectA/
1 harry May 08 21:48 projectB/
-…
+…
$
</screen>
- <para>Once you have your skeletal layout in place, you can begin
- importing actual project data into your repository, if any
- such data exists yet. Once again, there are several ways to
- do this. You could use the <command>svn import</command>
- command. You could checkout a working copy from your new
- repository, move and arrange project data inside the working
- copy, and use the <command>svn add</command> and <command>svn
- commit</command> commands. But once we start talking about
- such things, we're no longer discussing repository
- administration. If you aren't already familiar with the
- <command>svn</command> client program, see <xref
- linkend="svn-ch-3"/>.</para>
-
+ <para>Once you have your skeletal layout in place, you can begin
+ importing actual project data into your repository, if any such data
+ exists yet。 Once again, there are several ways to do this。 You could use
+ the <command>svn import</command> command。 You could checkout a working
+ copy from your new repository, move and arrange project data inside the
+ working copy, and use the <command>svn add</command> and <command>svn
+ commit</command> commands。 But once we start talking about such things,
+ we're no longer discussing repository administration。 If you aren't
+ already familiar with the <command>svn</command> client program, see
+ <xref linkend="svn-ch-3" />。</para>
</sect2>
</sect1>
<!-- ******************************************************************* -->
- <!-- *** SECTION 7: SUMMARY *** -->
+
+ <!-- *** 第七部分: 总结 *** -->
+
<!-- ******************************************************************* -->
+
<sect1 id="svn-ch-5-sect-7">
- <title>Summary</title>
+ <title>总结</title>
- <para>By now you should have a basic understanding of how to
- create, configure, and maintain Subversion repositories. We've
- introduced you to the various tools that will assist you with
- this task. Throughout the chapter, we've noted common
- administration pitfalls, and suggestions for avoiding
- them.</para>
-
- <para>All that remains is for you to decide what exciting data to
- store in your repository, and finally, how to make it available
- over a network. The next chapter is all about networking.</para>
+ <para>现在,你应该已经对如何创建、配置以及维护Subversion资料库有了个基本的认识。我们向您介绍了几个可以帮助您工作的工具。通过这一章,我们说明了一些通常的管理的误区,并提出了避免陷入误区的建议。</para>
+ <para>剩下的,就是由你决定在你的资料库中存放一些什么有趣的资料,并最终通过网络获得这些资料。下一章是关于网络的内容。</para>
</sect1>
</chapter>
-
<!--
local variables:
sgml-parent-document: ("book.xml" "chapter")
end:
--->
+-->
\ No newline at end of file
More information about the svnbook-dev
mailing list