⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.texi

📁 linux subdivision ying gai ke yi le ba
💻 TEXI
📖 第 1 页 / 共 2 页
字号:
   |_______| |___\____|            |___\____|
                  \                     \
                   \                     \
                 ___\____              ___\____
                |D       |            |D       |
                |        |            |        |
                | tuna   |            | tuna   |
                |___\____|            |___\____|
                     \                     \
                      \                     \
                    ___\____              ___\____
                   |F       |            |F       |
                   |        |            |        |
                   |        |            |        |
                   |________|            |________|

@end group
@end example

Finally, after all our new nodes are written, we finish the ``bubble
up'' process by linking this new tree to the next available revision in
the history array.  In this case, the new tree becomes revision 2 in the
repository.

@example
@group
       ______________________________________________________
      |___1_______2________3________4________5_________6_____...
          |        \
          |         \__________
       ___|_____             __\_____
      |D        |           |D       |
      |         |           |        |
      |   A     |           |   A    |
      |    \    |           |    \   |
      |   B \   |           |   B \  |
      |__/___\__|           |__/___\_|
        /     \               /     \
       |    ___\_____________/       \
       |   /    \                     \
    ___|__/   ___\____              ___\____
   |D      | |D       |            |D       |
   |       | |        |            |        |
   |       | | fish   |            | fish   |
   |_______| |___\____|            |___\____|
                  \                     \
                   \                     \
                 ___\____              ___\____
                |D       |            |D       |
                |        |            |        |
                | tuna   |            | tuna   |
                |___\____|            |___\____|
                     \                     \
                      \                     \
                    ___\____              ___\____
                   |F       |            |F       |
                   |        |            |        |
                   |        |            |        |
                   |________|            |________|

@end group
@end example

Generalizing on this example, you can now see that each ``revision'' in
the repository history represents a root node of a unique tree (and an
atomic commit to the whole filesystem.)  There are many trees in the
repository, and many of them share nodes.

Many nice behaviors come from this model:

@enumerate
@item
@b{Easy reads.}  If a filesystem reader wants to locate revision
@var{X} of file @file{foo.c}, it need only traverse the repository's
history, locate revision @var{X}'s root node, then walk down the tree to
@file{foo.c}.
@item
@b{Writers don't interfere with readers.}  Writers can continue to
create new nodes, bubbling their way up to the top, and concurrent
readers cannot see the work in progress.  The new tree only becomes
visible to readers after the writer makes its final ``link'' to the
repository's history.
@item
@b{File structure is versioned.}  Unlike CVS, the very structure of
each tree is being saved from revision to revision.  File and directory
renames, additions, and deletions are part of the repository's history.
@end enumerate

Let's demonstrate the last point by renaming the @file{tuna} to
@file{book}.

We start by creating a new parent ``fish'' directory, except that this
parent directory has a different dir_entry, one which points the
@emph{same} old file node, but has a different name:

@example
@group
       ______________________________________________________
      |___1_______2________3________4________5_________6_____...
          |        \
          |         \__________
       ___|_____             __\_____
      |D        |           |D       |
      |         |           |        |
      |   A     |           |   A    |
      |    \    |           |    \   |
      |   B \   |           |   B \  |
      |__/___\__|           |__/___\_|
        /     \               /     \
       |    ___\_____________/       \
       |   /    \                     \
    ___|__/   ___\____              ___\____
   |D      | |D       |            |D       |
   |       | |        |            |        |
   |       | | fish   |            | fish   |
   |_______| |___\____|            |___\____|
                  \                     \
                   \                     \
                 ___\____              ___\____      ________
                |D       |            |D       |    |D       |
                |        |            |        |    |        |
                | tuna   |            | tuna   |    | book   |
                |___\____|            |___\____|    |_/______|
                     \                     \         /
                      \                     \       /
                    ___\____              ___\____ /
                   |F       |            |F       |
                   |        |            |        |
                   |        |            |        |
                   |________|            |________|
@end group
@end example

From here, we finish with the bubble-up process.  We make new parent
directories up to the top, culminating in a new root directory with two
dir_entries (one points to the old ``B'' directory node we've had all
along, the other to the new revision of ``A''), and finally link the new
tree to the history as revision 3:

@example
@group
       ______________________________________________________
      |___1_______2________3________4________5_________6_____...
          |        \        \_________________
          |         \__________               \
       ___|_____             __\_____        __\_____
      |D        |           |D       |      |D       |
      |         |           |        |      |        |
      |   A     |           |   A    |      |   A    |
      |    \    |           |    \   |      |    \   |
      |   B \   |           |   B \  |      |   B \  |
      |__/___\__|           |__/___\_|      |__/___\_|
        /  ___________________/_____\_________/     \
       |  / ___\_____________/       \               \
       | / /    \                     \               \
    ___|/_/   ___\____              ___\____      _____\__
   |D      | |D       |            |D       |    |D       |
   |       | |        |            |        |    |        |
   |       | | fish   |            | fish   |    | fish   |
   |_______| |___\____|            |___\____|    |___\____|
                  \                     \             \
                   \                     \             \
                 ___\____              ___\____      ___\____
                |D       |            |D       |    |D       |
                |        |            |        |    |        |
                | tuna   |            | tuna   |    | book   |
                |___\____|            |___\____|    |_/______|
                     \                     \         /
                      \                     \       /
                    ___\____              ___\____ /
                   |F       |            |F       |
                   |        |            |        |
                   |        |            |        |
                   |________|            |________|

@end group
@end example

For our last example, we'll demonstrate the way ``tags'' and
``branches'' are implemented in the repository.

In a nutshell, they're one and the same thing.  Because nodes are so
easily shared, we simply create a @emph{new} directory entry that points
to an existing directory node.  It's an extremely cheap way of copying a
tree; we call this new entry a @dfn{clone}, or more colloquially, a
``cheap copy''.

Let's go back to our original tree, assuming that we're at revision 6 to
begin with:

@example
@group
       ______________________________________________________
    ...___6_______7________8________9________10_________11_____...
          |
          |
       ___|_____
      |D        |
      |         |
      |   A     |
      |    \    |
      |   B \   |
      |__/___\__|
        /     \
       |       \
       |        \
    ___|___   ___\____
   |D      | |D       |
   |       | |        |
   |       | | fish   |
   |_______| |___\____|
                  \
                   \
                 ___\____
                |D       |
                |        |
                | tuna   |
                |___\____|
                     \
                      \
                    ___\____
                   |F       |
                   |        |
                   |        |
                   |________|

@end group
@end example

Let's ``tag'' directory A.  To make the clone, we create a new dir_entry
@b{T} in our root, pointing to A's node:

@example
@group
       ______________________________________________________
      |___6_______7________8________9________10_________11_____...
          |        \
          |         \
       ___|_____   __\______
      |D        | |D        |
      |         | |         |
      |   A     | |    A    |
      |    \    | |    |    |
      |   B \   | |  B |  T |
      |__/___\__| |_/__|__|_|
        /     \    /   |  |
       |    ___\__/   /  /
       |   /    \    /  /
    ___|__/   ___\__/_ /
   |D      | |D       |
   |       | |        |
   |       | | fish   |
   |_______| |___\____|
                  \
                   \
                 ___\____
                |D       |
                |        |
                | tuna   |
                |___\____|
                     \
                      \
                    ___\____
                   |F       |
                   |        |
                   |        |
                   |________|

@end group
@end example

Now we're all set.  In the future, the contents of directories A and B
may change quite a lot.  However, assuming we never make any changes
to directory T, it will @emph{always} point to a particular pristine
revision of directory A at some point in time.  Thus, T is a tag.

(In theory, we can use some kind of authorization system to prevent
anyone from writing to directory T.  In practice, a well-laid out
repository should encourage ``tag directories'' to live in one place,
so that it's clear to all users that they're not meant to change.)

However, if we @emph{do} decide to allow commits in directory T, and
now our repository tree increments to revision 8, then T becomes a
branch.  Specifically, it's a branch of directory A which shares
history with A up to a certain point, and then ``broke off'' from the
main line at revision 8.

@node Diffy Storage
@subsubsection Diffy Storage

You may have been thinking, ``Gee, this bubble up method seems nice, but
it sure wastes a lot of space.  Every commit to the repository creates
an entire line of new directory nodes!''

Like many other revision control systems, Subversion stores changes as
differences.  It doesn't make complete copies of nodes; instead, it
stores the @emph{latest} revision as a full text, and previous revisions
as a succession of reverse diffs (the word "diff" is used loosely here
-- for files, it means vdeltas, for directories, it means a format that
expresses changes to directories).


@c -----------------------
@node Implementation
@subsection Implementation

For the initial release of Subversion,

@itemize @bullet
@item
The filesystem will be implemented as a library on Unix.
@item
The filesystem's data will probably be stored in a collection of .db
files, using the Berkeley Database library.@footnote{In the future, of
course, contributors are free modify the Subversion filesystem to
operate with more powerful SQL database.}  (For more information, see
@uref{http://www.sleepycat.com, Sleepycat Software}.)
@end itemize


@c ----------------------------------------------------------------

@node Repository Library
@section Repository Library


@c Jimb, Karl:  Maybe we should turn this into a discussion about how
@c the filesystem will use non-historical properties for internal ACLs,
@c and how people can add "external" ACL systems via historical
@c properties...?

A subversion @dfn{repository} is a directory that contains a number of
components:

@itemize @bullet
@item a versioned filesystem (typically a collection of .db files)
@item some hook scripts (for executing before or after commits)
@item a locking area (used by Berkeley DB or other processes)
@item a configuration area (for changing global behaviors)
@end itemize

The Subversion filesystem is just that: a filesystem.  But it's also
useful to provide an API that acts at the level of the repository.
The repository library (@file{libsvn_repos}) does this.

In particular, it wraps a few @file{libsvn_fs} routines, such as those
for beginning and ending commits, so that hook-scripts can run.  A
pre-commit-hook script might check for a valid log message, and a
post-commit-hook script might send an email to a mailing list.

Additionally, the repository library provides convenience routines for
examining and manipulating the filesystem.  For example, a routine to
generate a tree-delta by comparing two revisions, routines for
constructing new transactions, routines for querying log messages, and
routines for exporting and importing filesystem data.



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -