[svnbook commit] r1421 - in trunk/src/ru: . book

dmitriy svnbook-dev at red-bean.com
Sun Jun 5 09:31:28 CDT 2005


Author: dmitriy
Date: Sun Jun  5 09:31:27 2005
New Revision: 1421

Modified:
   trunk/src/ru/LAST_UPDATED
   trunk/src/ru/book/appc.xml
   trunk/src/ru/book/appd.xml
   trunk/src/ru/book/ch02.xml
   trunk/src/ru/book/ch03.xml
   trunk/src/ru/book/ch05.xml
   trunk/src/ru/book/ch07.xml
   trunk/src/ru/book/ch08.xml
   trunk/src/ru/book/ch09.xml
Log:
For check of correct work of synchronization with en/,
in a root directory has been executed 'make sync'.
Synchronization works normally.

* LAST_UPDATED
  Updated

* book/ch02.xml
  Has been translated sidebar
  'svn.basic.vsn-models.copy-merge.sb-1'

* book/appc.xml  
* book/appd.xml
* book/ch03.xml
* book/ch05.xml
* book/ch07.xml
* book/ch08.xml
* book/ch09.xml
  Just merged with en/


Modified: trunk/src/ru/LAST_UPDATED
==============================================================================
--- trunk/src/ru/LAST_UPDATED	(original)
+++ trunk/src/ru/LAST_UPDATED	Sun Jun  5 09:31:27 2005
@@ -1 +1 @@
-1366
\ No newline at end of file
+1420

Modified: trunk/src/ru/book/appc.xml
==============================================================================
--- trunk/src/ru/book/appc.xml	(original)
+++ trunk/src/ru/book/appc.xml	Sun Jun  5 09:31:27 2005
@@ -311,10 +311,10 @@
   <sect1 id="svn.webdav.autoversioning">
     <title>Autoversioning </title>
 
-    <para>All is not lost.  There's still a bright gleam of
-      interoperability around this cloud, one which justifies
-      Subversion's original adoption of WebDAV: it's called
-      autoversioning.</para>
+    <para>While the Subversion client is not a full DeltaV client, nor
+      the Subversion server a full DeltaV server, there's still a
+      glimmer of WebDAV interoperability to be happy about:  it's
+      called autoversioning.</para>
 
     <para>Autoversioning is an optional feature defined in the DeltaV
       standard.  A typical DeltaV server will reject an ignorant

Modified: trunk/src/ru/book/appd.xml
==============================================================================
--- trunk/src/ru/book/appd.xml	(original)
+++ trunk/src/ru/book/appd.xml	Sun Jun  5 09:31:27 2005
@@ -53,9 +53,9 @@
 
       <varlistentry>
         <term>RapidSVN (<systemitem
-          class="url">http://rapidsvn.tigris.org/</systemitem>)</term>
+          class="url">http://www.rapidsvn.org/</systemitem>)</term>
         <listitem><para>Cross-platform Subversion GUI, based on the
-          WxPython libraries</para></listitem>
+          wxWidgets libraries</para></listitem>
       </varlistentry>
 
       <varlistentry>

Modified: trunk/src/ru/book/ch02.xml
==============================================================================
--- trunk/src/ru/book/ch02.xml	(original)
+++ trunk/src/ru/book/ch02.xml	Sun Jun  5 09:31:27 2005
@@ -478,6 +478,59 @@
         защищена от конфликтов; на практике блокирование снижает
         продуктивность как ничто другое.</para>
 
+      <sidebar id="svn.basic.vsn-models.copy-merge.sb-1">
+        <!-- @ENGLISH {{{
+        <title>When Locking is Necessary</title>
+        @ ENGLISH }}} -->
+        <title>Когда блокирование необходимо</title>
+
+        <!-- @ENGLISH {{{
+        <para>While the lock-modify-unlock model is considered
+          generally harmful to collaboration, there are still times
+          when locking is appropriate.</para>
+        @ ENGLISH }}} -->
+        <para>Несмотря на то, что модель
+          блокирование-изменение-разблокирование названа, вцелом, губительной
+          для командной работы, все-таки есть моменты когда блокирование
+          умесно.</para>
+
+        <!-- @ENGLISH {{{
+        <para>The copy-modify-merge model is based on the assumption
+          that files are contextually mergeable: that is, that the
+          majority of the files in the repository are line-based text
+          files (such as program source code.)  But for files with
+          binary formats, such as artwork or sound, it's often
+          impossible to merge conflicting changes.  In these
+          situations, it really is necessary to users to take strict
+          turns when changing the file.  Without serialized access,
+          somebody ends up wasting their time on changes that are
+          ultimately discarded.</para>
+        @ ENGLISH }}} -->
+        <para>Модель копирование-изменение-слияние основывается на
+          предположении о том, что файлы контекстно объединяемы: это так
+          если большинство файлов в хранилище - основаные на строках текстовые
+          файлы (такие как исходный код программы). Но для файлов бинарных
+          форматов, таких как графические или звуковые, как правило
+          не возможно объединить конфликтующие изменения. В таких ситуациях
+          пользователям действительно необходимо быть внимательными при
+          изменении файла. Без раздельного доступа кто-то может впустую
+          потратить время на изменения которые в конце концов
+          потеряются.</para>
+
+        <!-- @ENGLISH {{{
+        <para>While CVS and Subversion are still primarily
+          copy-modify-merge systems, they both recognize the need to
+          lock an occasional file and provide mechanisms for this.
+          See <xref linkend="svn.advanced.locking"/>.</para>
+        @ ENGLISH }}} -->
+        <para>Так как CVS и Subversion в первую очередь системы типа
+          копирование-изменение-слияние в них обоих признается необходимость
+          блокирования определенных файлов и предлагаются механизмы для
+          этого. См. <xref linkend="svn.advanced.locking"/>.</para>
+
+      </sidebar>
+
+
     </sect2>
 
   </sect1>

Modified: trunk/src/ru/book/ch03.xml
==============================================================================
--- trunk/src/ru/book/ch03.xml	(original)
+++ trunk/src/ru/book/ch03.xml	Sun Jun  5 09:31:27 2005
@@ -814,21 +814,27 @@
           actually printed by <command>svn status</command>.)</para>
       
         <screen>
-  L    abc.c               # svn has a lock in its .svn directory for abc.c
-M      bar.c               # the content in bar.c has local modifications
- M     baz.c               # baz.c has property but no content modifications
-X      3rd_party           # this dir is part of an externals definition
-?      foo.o               # svn doesn't manage foo.o
-!      some_dir            # svn manages this, but it's either missing or incomplete
-~      qux                 # versioned as file/dir/link, but type has changed
-I      .screenrc           # svn doesn't manage this, and is configured to ignore it
-A  +   moved_dir           # added with history of where it came from
-M  +   moved_dir/README    # added with history and has local modifications
-D      stuff/fish.c        # this file is scheduled for deletion
-A      stuff/loot/bloo.h   # this file is scheduled for addition
-C      stuff/loot/lump.c   # this file has conflicts from an update
-R      xyz.c               # this file is scheduled for replacement
-    S  stuff/squawk        # this file or dir has been switched to a branch
+  L     some_dir            # svn left a lock in the .svn area of some_dir
+M       bar.c               # the content in bar.c has local modifications
+ M      baz.c               # baz.c has property but no content modifications
+X       3rd_party           # dir is part of an externals definition
+?       foo.o               # svn doesn't manage foo.o
+!       some_dir            # svn manages this, but it's missing or incomplete
+~       qux                 # versioned as file/dir/link, but type has changed
+I       .screenrc           # svn doesn't manage this, and is set to ignore it
+A  +    moved_dir           # added with history of where it came from
+M  +    moved_dir/README    # added with history and has local modifications
+D       stuff/fish.c        # file is scheduled for deletion
+A       stuff/loot/bloo.h   # file is scheduled for addition
+C       stuff/loot/lump.c   # file has textual conflicts from an update
+ C      stuff/loot/glub.c   # file has property conflicts from an update
+R       xyz.c               # file is scheduled for replacement
+    S   stuff/squawk        # file or dir has been switched to a branch
+     K  dog.jpg             # file is locked locally; lock-token present 
+     O  cat.jpg             # file is locked in the repository by other user
+     B  bird.jpg            # file is locked locally, but lock has been broken
+     T  fish.jpg            # file is locked locally, but lock has been stolen
+
 </screen>
       
         <para>In this output format <command>svn status</command>
@@ -975,8 +981,8 @@
         
         <para>The third column will only show whitespace or an
           <computeroutput>L</computeroutput> which means that
-          Subversion has locked the item in
-          the <filename>.svn</filename> working area.  You will see an
+          Subversion has locked the direcotry's
+          <filename>.svn</filename> working area.  You will see an
           <computeroutput>L</computeroutput> if you run <command>svn
           status</command> in a directory where an <command>svn
           commit</command> is in progress—perhaps when you are
@@ -1011,6 +1017,10 @@
           file or directory has been switched from the path of the
           rest of the working copy (using <command>svn
           switch</command>) to a branch.</para>
+
+        <para>The sixth column shows information about locks, which is
+          further explained in <xref
+          linkend="svn.advanced.locking"/>.</para>
         
         <para>If you pass a specific path to <command>svn
           status</command>, it gives you information about that item
@@ -2123,7 +2133,8 @@
 
       <screen>
 $ svnadmin create /usr/local/svn/newrepos
-$ svn import mytree file:///usr/local/svn/newrepos/some/project
+$ svn import mytree file:///usr/local/svn/newrepos/some/project \
+             -m "Initial import"
 Adding         mytree/foo.c
 Adding         mytree/bar.c
 Adding         mytree/subdir

Modified: trunk/src/ru/book/ch05.xml
==============================================================================
--- trunk/src/ru/book/ch05.xml	(original)
+++ trunk/src/ru/book/ch05.xml	Sun Jun  5 09:31:27 2005
@@ -467,10 +467,11 @@
       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>In Subversion 1.2, a repository is created with a FSFS
+      back-end by default (see <xref
+      linkend="svn.reposadmin.basics.backends"/>). The back-end can be
+      explicitly chosen with the <option>--fs-type</option>
+      argument:</para>
 
     <screen>
 $ svnadmin create --fs-type fsfs /path/to/repos
@@ -611,9 +612,9 @@
             
       <screen>
 $ ls repos/hooks/
-post-commit.tmpl          pre-revprop-change.tmpl
-post-revprop-change.tmpl  start-commit.tmpl
-pre-commit.tmpl           
+post-commit.tmpl          post-unlock.tmpl          pre-revprop-change.tmpl
+post-lock.tmpl            pre-commit.tmpl           pre-unlock.tmpl
+post-revprop-change.tmpl  pre-lock.tmpl             start-commit.tmpl
 </screen>
             
       <para>There is one template for each hook that the Subversion
@@ -659,8 +660,8 @@
         programs.</para>
       </tip>
 
-      <para>Currently there are five hooks implemented by the
-        Subversion repository:</para>
+      <para>There are nine hooks implemented by the Subversion
+        repository:</para>
 
       <variablelist>
         <varlistentry>
@@ -798,6 +799,70 @@
               value.</para>
           </listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term><filename>pre-lock</filename></term>
+          <listitem>
+            <para>This hook runs whenever someone attempts to lock a
+              file.  It can be used to prevent locks altogether, or to
+              create a more complex policy specifying exactly which
+              users are allowed to lock particular paths.  If the hook
+              notices a pre-existing lock, then it can also decide
+              whether a user is allowed to "steal" the existing lock.
+              The repository passes three arguments to the hook: the
+              path to the repository, the path being locked, and the
+              user attempting to perform the lock.  If the program
+              returns a non-zero exit value, the lock action is
+              aborted and anything printed to stderr is marshalled
+              back to the client.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><filename>post-lock</filename></term>
+          <listitem>
+            <para>This hook runs after a path is locked.  The locked
+              path is passed to the hook's stdin, and the hook also
+              receives two arguments:  the path to the repository, and
+              the user who performed the lock.  The hook is then free
+              to send email notification or record the event in any
+              way it chooses.  Because the lock already happened, the
+              output of the hook is ignored.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><filename>pre-unlock</filename></term>
+          <listitem>
+            <para>This hook runs whenever someone attempts to remove a
+              lock on a file.  It can be used to create policies that
+              specify which users are allowed to unlock particular
+              paths.  It's particularly important for determining
+              policies about lock breakage.  If user A locks a file,
+              is user B allowed to break the lock?  What if the lock
+              is more than a week old?  These sorts of things can be
+              decided and enforced by the hook.  The repository passes
+              three arguments to the hook: the path to the repository,
+              the path being unlocked, and the user attempting to
+              remove the lock.  If the program returns a non-zero exit
+              value, the unlock action is aborted and anything printed
+              to stderr is marshalled back to the client.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><filename>post-unlock</filename></term>
+          <listitem>
+            <para>This hook runs after a path is unlocked.  The
+              unlocked path is passed to the hook's stdin, and the
+              hook also receives two arguments: the path to the
+              repository, and the user who removed the lock.  The hook
+              is then free to send email notification or record the
+              event in any way it chooses.  Because the lock removal
+              already happened, the output of the hook is
+              ignored.</para>
+          </listitem>
+        </varlistentry>
       </variablelist>
 
       <warning>
@@ -1139,6 +1204,13 @@
           </varlistentry>
 
           <varlistentry>
+            <term><literal>lock</literal></term>
+            <listitem>
+              <para>If a path is locked, describe the lock attributes.</para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
             <term><literal>propget</literal></term>
             <listitem>
               <para>Print the value of a property on a path in the
@@ -1286,6 +1358,14 @@
           <varlistentry>
             <term><literal>lstxns</literal></term>
             <listitem>
+              <para>List and describe any locks that exist in the
+                repository.</para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term><literal>lstxns</literal></term>
+            <listitem>
               <para>List the names of uncommitted Subversion
                 transactions that currently exist in the repository.</para>
             </listitem>
@@ -1302,6 +1382,14 @@
           </varlistentry>
 
           <varlistentry>
+            <term><literal>rmlocks</literal></term>
+            <listitem>
+              <para>Unconditionally remove locks from listed
+                paths.</para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
             <term><literal>rmtxns</literal></term>
             <listitem>
               <para>Cleanly remove Subversion transactions from the

Modified: trunk/src/ru/book/ch07.xml
==============================================================================
--- trunk/src/ru/book/ch07.xml	(original)
+++ trunk/src/ru/book/ch07.xml	Sun Jun  5 09:31:27 2005
@@ -1686,6 +1686,40 @@
           the working copy.</para>
       </sect3>
 
+      <sect3 id="svn.advanced.props.special.needs-lock">
+        <title><literal>svn:needs-lock</literal></title>
+
+        <para>This property is used to signify that the file it's
+          attached to ought to be locked before editing.  The value of
+          the property is irrelevant; Subversion will normalize its
+          value to <literal>*</literal>.  When present, the file will
+          be read-only <emphasis>unless</emphasis> the user has
+          explicitly locked the file.  When a lock-token is present
+          (as a result of running <command>svn lock</command>), the
+          file becomes read-write.  When the lock is released, the
+          file becomes read-only again.</para>
+
+        <para>Users and administrators are encouraged to attach this
+          property to any file which cannot be contextually merged,
+          such as binary or proprietary-formatted files.  The main
+          idea is to prevent wasted time;  if the file is normally
+          read-only, then users will be reminded to lock the file
+          before editing, thus discovering any pre-existing
+          locks.</para>
+
+        <para>Note that this property is a communication system which
+          works independent of the locking system.  In other words,
+          any file can be locked, whether or not this property is
+          present.  And conversely, the presence of this property
+          doesn't make the repository require a lock.  It's possible
+          for a misbehaving application to "hijack" the read-only
+          file, edit it anyway, then allow the user to commit without
+          a lock.</para>
+
+        <para>For more on locking, see <xref
+        linkend="svn.advanced.locking"/>.</para>
+      </sect3>
+
     </sect2>
 
     <!-- ***************************************************************** -->
@@ -1744,6 +1778,16 @@
   </sect1>
 
   <!-- ******************************************************************* -->
+  <!-- *** LOCKING                                                     *** -->
+  <!-- ******************************************************************* -->
+  <sect1 id="svn.advanced.locking">
+    <title>Locking</title>
+
+
+  </sect1>
+
+
+  <!-- ******************************************************************* -->
   <!-- *** SECTION 2 1/2:  PEG AND OPERATIVE REVISIONS                 *** -->
   <!-- ******************************************************************* -->
   <sect1 id="svn.advanced.pegrevs">
@@ -2626,16 +2670,19 @@
           related to character set conversions:</para>
 
         <screen>
-svn: Can't recode string.
+svn: Can't convert string from native encoding to 'UTF-8':
+…
+svn: Can't convert string from 'UTF-8' to native encoding:
+…
 </screen>
     
-        <para>The message is cryptic, but generally occurs when the
-          Subversion client has received a UTF-8 string from the
-          repository, but the characters can't be converted to the
-          current locale.  For example, if your locale is
-          <literal>en_US</literal> but a collaborator has committed a
-          Japanese filename, you're likely to see this error when you
-          receive the file during an <command>svn
+        <para>Errors like this typically occur when the Subversion
+          client has received a UTF-8 string from the repository, but
+          not all of the characters in that string can be represented
+          using the encoding of the current locale.  For example, if
+          your locale is <literal>en_US</literal> but a collaborator
+          has committed a Japanese filename, you're likely to see this
+          error when you receive the file during an <command>svn
           update</command>.</para>
 
         <para>The solution is either to set your locale to something

Modified: trunk/src/ru/book/ch08.xml
==============================================================================
--- trunk/src/ru/book/ch08.xml	(original)
+++ trunk/src/ru/book/ch08.xml	Sun Jun  5 09:31:27 2005
@@ -950,97 +950,204 @@
         library suite, combined with a powerful, flexible binding
         language, is so appealing.</para>
 
-      <para>Let's look at an example that uses Subversion's Python
-        SWIG bindings.  Our example will do the same thing as our last
-        example.  Note the difference in size and complexity of the
-        function this time!</para>
+      <para>Let's look at a sample program that uses Subversion's
+        Python SWIG bindings to recursively crawl the youngest
+        repository revision, and print the various paths reached
+        during the crawl.</para>
 
       <example id="svn.developer.usingapi.otherlangs.ex-1">
         <title>Using the Repository Layer with Python</title>
 
         <programlisting>
-from svn import fs
+#!/usr/bin/python
+
+"""Crawl a repository, printing versioned object path names."""
+
+import sys
 import os.path
+import svn.fs, svn.core, svn.repos
+
+def crawl_filesystem_dir(root, directory, pool):
+    """Recursively crawl DIRECTORY under ROOT in the filesystem, and return
+    a list of all the paths at or below DIRECTORY.  Use POOL for all 
+    allocations."""
+
+    # Print the name of this path.
+    print directory + "/"
+    
+    # Get the directory entries for DIRECTORY.
+    entries = svn.fs.svn_fs_dir_entries(root, directory, pool)
+
+    # Use an iteration subpool.
+    subpool = svn.core.svn_pool_create(pool)
+
+    # Loop over the entries.
+    names = entries.keys()
+    for name in names:
+        # Clear the iteration subpool.
+        svn.core.svn_pool_clear(subpool)
+
+        # Calculate the entry's full path.
+        full_path = directory + '/' + name
+
+        # If the entry is a directory, recurse.  The recursion will return
+        # a list with the entry and all its children, which we will add to
+        # our running list of paths.
+        if svn.fs.svn_fs_is_dir(root, full_path, subpool):
+            crawl_filesystem_dir(root, full_path, subpool)
+        else:
+            # Else it's a file, so print its path here.
+            print full_path
+
+    # Destroy the iteration subpool.
+    svn.core.svn_pool_destroy(subpool)
+
+def crawl_youngest(pool, repos_path):
+    """Open the repository at REPOS_PATH, and recursively crawl its
+    youngest revision."""
+    
+    # Open the repository at REPOS_PATH, and get a reference to its
+    # versioning filesystem.
+    repos_obj = svn.repos.svn_repos_open(repos_path, pool)
+    fs_obj = svn.repos.svn_repos_fs(repos_obj)
 
-def crawl_filesystem_dir (root, directory, pool):
-  """Recursively crawl DIRECTORY under ROOT in the filesystem, and return
-  a list of all the paths at or below DIRECTORY.  Use POOL for all 
-  allocations."""
-
-  # Get the directory entries for DIRECTORY.
-  entries = fs.dir_entries(root, directory, pool)
-
-  # Initialize our returned list with the directory path itself.
-  paths = [directory]
-
-  # Loop over the entries
-  names = entries.keys()
-  for name in names:
-    # Calculate the entry's full path.
-    full_path = os.path.join(basepath, name)
-
-    # If the entry is a directory, recurse.  The recursion will return
-    # a list with the entry and all its children, which we will add to
-    # our running list of paths.
-    if fs.is_dir(fsroot, full_path, pool):
-      subpaths = crawl_filesystem_dir(root, full_path, pool)
-      paths.extend(subpaths)
-
-    # Else, it is a file, so add the entry's full path to the FILES list.
-    else:
-      paths.append(full_path)
+    # Query the current youngest revision.
+    youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj, pool)
+    
+    # Open a root object representing the youngest (HEAD) revision.
+    root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev, pool)
 
-  return paths
+    # Do the recursive crawl.
+    crawl_filesystem_dir(root_obj, "", pool)
+    
+if __name__ == "__main__":
+    # Check for sane usage.
+    if len(sys.argv) != 2:
+        sys.stderr.write("Usage: %s REPOS_PATH\n"
+                         % (os.path.basename(sys.argv[0])))
+        sys.exit(1)
+
+    # Call the app-wrapper, which takes care of APR initialization/shutdown
+    # and the creation and cleanup of our top-level memory pool.
+    svn.core.run_app(crawl_youngest, os.path.normpath(sys.argv[1]))
 </programlisting>
       </example>
 
-      <para>An implementation in C of the previous example would
-        stretch on quite a bit longer.  The same routine in C would
-        need to pay close attention to memory usage, and need to use
-        custom datatypes for representing the hash of entries and the
-        list of paths.  Python has hashes (called
-        <quote>dictionaries</quote>) and lists as built-in datatypes,
-        and provides a wonderful selection of methods for operating on
-        those types.  And since Python uses reference counting and
-        garbage collection, users of the language don't have to bother
-        themselves with allocating and freeing memory.</para>
-
-      <para>In the previous section of this chapter, we mentioned the
-        <filename>libsvn_client</filename> interface, and how it
-        exists for the sole purpose of simplifying the process of
-        writing a Subversion client.  The following is a brief example
-        of how that library can be accessed via the SWIG bindings.  In
-        just a few lines of Python, you can check out a fully
-        functional Subversion working copy!</para>
+      <para>This same program in C would need to deal with custom
+        datatypes (such as those provided by the APR library) for
+        representing the hash of entries and the list of paths, but
+        Python has hashes (called <quote>dictionaries</quote>) and
+        lists as built-in datatypes, and provides a rich collection of
+        functions for operating on those types.  So SWIG (with the
+        help of some customizations in Subversion's language bindings
+        layer) takes care of mapping those custom datatypes into the
+        native datatypes of the target language.  This provides a more
+        intuitive interface for users of that language.</para>
+
+      <para>The Subversion Python bindings can be used for working
+        copy operations, too.  In the previous section of this
+        chapter, we mentioned the <filename>libsvn_client</filename>
+        interface, and how it exists for the sole purpose of
+        simplifying the process of writing a Subversion client.  The
+        following is a brief example of how that library can be
+        accessed via the SWIG bindings to recreate a scaled-down
+        version of the <command>svn status</command> command.</para>
 
       <example id="svn.developer.usingapi.otherlangs.ex-2">
-        <title>A Simple Script to Check Out a Working Copy.</title>
+        <title>A Python Status Crawler</title>
 
         <programlisting>
 #!/usr/bin/env python
-import sys
-from svn import util, _util, _client
 
-def usage():
-  print "Usage: " + sys.argv[0] + " URL PATH\n"
-  sys.exit(0)
-
-def run(url, path):
-  # Initialize APR and get a POOL.
-  _util.apr_initialize()
-  pool = util.svn_pool_create(None)
-
-  # Checkout the HEAD of URL into PATH (silently)
-  _client.svn_client_checkout(None, None, url, path, -1, 1, None, pool)
-
-  # Cleanup our POOL, and shut down APR.
-  util.svn_pool_destroy(pool)
-  _util.apr_terminate()
+"""Crawl a working copy directory, printing status information."""
 
+import sys
+import os.path
+import getopt
+import svn.core, svn.client, svn.wc
+
+def generate_status_code(status):
+    """Translate a status value into a single-character status code,
+    using the same logic as the Subversion command-line client."""
+
+    if status == svn.wc.svn_wc_status_none:
+        return ' '
+    if status == svn.wc.svn_wc_status_normal:
+        return ' '
+    if status == svn.wc.svn_wc_status_added:
+        return 'A'
+    if status == svn.wc.svn_wc_status_missing:
+        return '!'
+    if status == svn.wc.svn_wc_status_incomplete:
+        return '!'
+    if status == svn.wc.svn_wc_status_deleted:
+        return 'D'
+    if status == svn.wc.svn_wc_status_replaced:
+        return 'R'
+    if status == svn.wc.svn_wc_status_modified:
+        return 'M'
+    if status == svn.wc.svn_wc_status_merged:
+        return 'G'
+    if status == svn.wc.svn_wc_status_conflicted:
+        return 'C'
+    if status == svn.wc.svn_wc_status_obstructed:
+        return '~'
+    if status == svn.wc.svn_wc_status_ignored:
+        return 'I'
+    if status == svn.wc.svn_wc_status_external:
+        return 'X'
+    if status == svn.wc.svn_wc_status_unversioned:
+        return '?'
+    return '?'
+
+def do_status(pool, wc_path, verbose):
+    # Calculate the length of the input working copy path.
+    wc_path_len = len(wc_path)
+
+    # Build a client context baton.
+    ctx = svn.client.svn_client_ctx_t()
+
+    def _status_callback(path, status, root_path_len=wc_path_len):
+        """A callback function for svn_client_status."""
+
+        # Print the path, minus the bit that overlaps with the root of
+        # the status crawl
+        text_status = generate_status_code(status.text_status)
+        prop_status = generate_status_code(status.prop_status)
+        print '%s%s  %s' % (text_status, prop_status, path[wc_path_len + 1:])
+        
+    # Do the status crawl, using _status_callback() as our callback function.
+    svn.client.svn_client_status(wc_path, None, _status_callback,
+                                 1, verbose, 0, 0, ctx, pool)
+
+def usage_and_exit(errorcode):
+    """Print usage message, and exit with ERRORCODE."""
+    stream = errorcode and sys.stderr or sys.stdout
+    stream.write("""Usage: %s OPTIONS WC-PATH
+Options:
+  --help, -h    : Show this usage message
+  --verbose, -v : Show all statuses, even uninteresting ones
+""" % (os.path.basename(sys.argv[0])))
+    sys.exit(errorcode)
+    
 if __name__ == '__main__':
-  if len(sys.argv) != 3:
-    usage()
-  run(sys.argv[1], sys.argv[2])
+    # Parse command-line options.
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose"])
+    except getopt.GetoptError:
+        usage_and_exit(1)
+    verbose = 0
+    for opt, arg in opts:
+        if opt in ("-h", "--help"):
+            usage_and_exit(0)
+        if opt in ("-v", "--verbose"):
+            verbose = 1
+    if len(args) != 1:
+        usage_and_exit(2)
+            
+    # Call the app-wrapper, which takes care of APR initialization/shutdown
+    # and the creation and cleanup of our top-level memory pool.
+    svn.core.run_app(do_status, os.path.normpath(args[0]), verbose)
 </programlisting>
       </example>
 

Modified: trunk/src/ru/book/ch09.xml
==============================================================================
--- trunk/src/ru/book/ch09.xml	(original)
+++ trunk/src/ru/book/ch09.xml	Sun Jun  5 09:31:27 2005
@@ -3249,8 +3249,9 @@
             <varlistentry>
               <term>'C'</term>
               <listitem>
-                <para>Item is in conflict with updates received from
-                  the repository.</para>
+                <para>The contents (as opposed to the properties) of
+                  the item conflict with updates received from the
+                  repository.</para>  
               </listitem>
             </varlistentry>
 



More information about the svnbook-dev mailing list