You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/05/13 06:51:28 UTC

svn commit: r1679139 [2/7] - in /subversion/branches/1.10-cache-improvements: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ subversion/bindings/javahl/ subversion/bindings/javahl/native/ subversion/bindings/javahl/native/jniwra...

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java Wed May 13 04:51:26 2015
@@ -94,7 +94,9 @@ public interface ISVNEditor
      * <code>replacesRevision</code> set accordingly <em>must</em> be used.
      * <p>
      * <b>Note:</b> The <code>contents</code> stream's lifetime must not
-     *      extend beyond the scope of this function.
+     *      extend beyond the scope of this function. An
+     *      implementation <b>must</b> close the stream after
+     *      consuming its contents.
      *
      * @throws ClientException
      */
@@ -193,7 +195,9 @@ public interface ISVNEditor
      * #addFile().
      * <p>
      * <b>Note:</b> The <code>contents</code> stream's lifetime must not
-     *      extend beyond the scope of this function.
+     *      extend beyond the scope of this function. An
+     *      implementation <b>must</b> close the stream after
+     *      consuming its contents.
      *
      * @throws ClientException
      */

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Wed May 13 04:51:26 2015
@@ -294,7 +294,7 @@ public class SVNClient implements ISVNCl
 
     public void cleanup(String path) throws ClientException
     {
-        cleanup(path, false, true, true, true, false);
+        cleanup(path, true, true, true, true, false);
     }
 
     public native void resolve(String path, Depth depth,

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java Wed May 13 04:51:26 2015
@@ -33,6 +33,7 @@ import java.util.GregorianCalendar;
 import java.util.Locale;
 import java.util.SimpleTimeZone;
 import java.io.InputStream;
+import java.io.IOException;
 import java.nio.charset.Charset;
 
 /**
@@ -78,6 +79,14 @@ class StatusEditor implements ISVNEditor
                         long replacesRevision)
     {
         //DEBUG:System.err.println("  [J] StatusEditor.addFile");
+        if (contents != null) {
+            try {
+                contents.close();
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
         checkState();
         receiver.addedFile(relativePath);
     }
@@ -120,6 +129,14 @@ class StatusEditor implements ISVNEditor
                           Map<String, byte[]> properties)
     {
         //DEBUG:System.err.println("  [J] StatusEditor.alterFile");
+        if (contents != null) {
+            try {
+                contents.close();
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
         checkState();
         receiver.modifiedFile(relativePath,
                               (checksum != null && contents != null),

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Wed May 13 04:51:26 2015
@@ -1091,6 +1091,7 @@ public class BasicTests extends SVNTests
     private void setupPinExternalsTest(OneTest thisTest) throws Throwable
     {
         byte[] extref = ("^/A/D/H ADHext\n" +
+                         "^/A/D/H ADHext2\n" +
                          "^/A/D/H@1 peggedADHext\n" +
                          "-r1 ^/A/D/H revvedADHext\n").getBytes();
         Set<String> paths = new HashSet<String>();
@@ -1130,6 +1131,7 @@ public class BasicTests extends SVNTests
 
         // Verification
         String expected = ("^/A/D/H@2 ADHext\n" +
+                           "^/A/D/H@2 ADHext2\n" +
                            "^/A/D/H@1 peggedADHext\n" +
                            "-r1 ^/A/D/H@2 revvedADHext\n");
         String actual =
@@ -1158,6 +1160,7 @@ public class BasicTests extends SVNTests
 
         // Verification
         String expected = ("^/A/D/H@2 ADHext\n" +
+                           "^/A/D/H@2 ADHext2\n" +
                            "^/A/D/H@1 peggedADHext\n" +
                            "-r1 ^/A/D/H@2 revvedADHext\n");
         String actual =
@@ -1186,6 +1189,7 @@ public class BasicTests extends SVNTests
 
         // Verification
         String expected = ("^/A/D/H@2 ADHext\n" +
+                           "^/A/D/H@2 ADHext2\n" +
                            "^/A/D/H@1 peggedADHext\n" +
                            "-r1 ^/A/D/H@2 revvedADHext\n");
         String actual =
@@ -1214,6 +1218,7 @@ public class BasicTests extends SVNTests
 
         // Verification
         String expected = ("^/A/D/H@2 ADHext\n" +
+                           "^/A/D/H@2 ADHext2\n" +
                            "^/A/D/H@1 peggedADHext\n" +
                            "-r1 ^/A/D/H@2 revvedADHext\n");
         String actual =
@@ -1249,6 +1254,44 @@ public class BasicTests extends SVNTests
 
         // Verification
         String expected = ("^/A/D/H@2 ADHext\n" +
+                           "^/A/D/H ADHext2\n" +
+                           "^/A/D/H@1 peggedADHext\n" +
+                           "-r1 ^/A/D/H revvedADHext\n");
+        String actual =
+            new String(client.propertyGet(target, "svn:externals", null, null));
+
+        assertEquals(expected, actual);
+    }
+
+    /**
+     * Test REPO-to-REPO copy with explicit pinned externals that
+     * don't correspond to actual externals
+     * @throws Throwable
+     */
+    public void testCopyPinExternals_repo2repo_corkscrew() throws Throwable
+    {
+        // build the test setup
+        OneTest thisTest = new OneTest();
+        setupPinExternalsTest(thisTest);
+
+        String sourceUrl = thisTest.getUrl() + "/A/B";
+        Map<String, List<ExternalItem>> externalsToPin =
+            new HashMap<String, List<ExternalItem>>();
+        List<ExternalItem> items = new ArrayList<ExternalItem>(1);
+        items.add(new ExternalItem("ADHext", "^/A/D/H", null, null));
+        externalsToPin.put(sourceUrl + "/A", items);
+
+        List<CopySource> sources = new ArrayList<CopySource>(1);
+        sources.add(new CopySource(sourceUrl, null, null));
+        String target = thisTest.getUrl() + "/A/Bcopy";
+        client.copy(sources, target, true, false, false, false,
+                    true,       // pinExternals
+                    externalsToPin,
+                    null, new ConstMsg("Copy WC to REPO"), null);
+
+        // Verification
+        String expected = ("^/A/D/H ADHext\n" +
+                           "^/A/D/H ADHext2\n" +
                            "^/A/D/H@1 peggedADHext\n" +
                            "-r1 ^/A/D/H revvedADHext\n");
         String actual =

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Wed May 13 04:51:26 2015
@@ -53,15 +53,35 @@ import java.security.NoSuchAlgorithmExce
  */
 public class SVNRemoteTests extends SVNTests
 {
+    /**
+     * Base name of all our tests.
+     */
+    public final static String testName = "remote_test";
+
     protected OneTest thisTest;
 
     public SVNRemoteTests()
     {
+        init();
     }
 
     public SVNRemoteTests(String name)
     {
         super(name);
+        init();
+    }
+
+    /**
+     * Initialize the testBaseName and the testCounter, if this is the
+     * first test of this class.
+     */
+    private void init()
+    {
+        if (!testName.equals(testBaseName))
+        {
+            testCounter = 0;
+            testBaseName = testName;
+        }
     }
 
     protected void setUp() throws Exception

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java Wed May 13 04:51:26 2015
@@ -40,13 +40,33 @@ import java.util.Map;
  */
 public class SVNReposTests extends SVNTests
 {
+    /**
+     * Base name of all our tests.
+     */
+    public final static String testName = "repos_test";
+
     public SVNReposTests()
     {
+        init();
     }
 
     public SVNReposTests(String name)
     {
         super(name);
+        init();
+    }
+
+    /**
+     * Initialize the testBaseName and the testCounter, if this is the
+     * first test of this class.
+     */
+    private void init()
+    {
+        if (!testName.equals(testBaseName))
+        {
+            testCounter = 0;
+            testBaseName = testName;
+        }
     }
 
     /**

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNTests.java Wed May 13 04:51:26 2015
@@ -80,6 +80,17 @@ class SVNTests extends TestCase
     protected static int testCounter;
 
     /**
+     * Set to true if tests should clean up after themselves.
+     */
+    protected boolean cleanupAfterTests = false;
+
+    /**
+     * this list contains the names of all repository and working copy
+     * directories created by one test case.
+     */
+    protected static List<File> testDirs;
+
+    /**
      * the file in which the sample repository has been dumped.
      */
     protected File greekDump;
@@ -173,6 +184,10 @@ class SVNTests extends TestCase
 
     private void init()
     {
+        String cleanupProp = System.getProperty("test.cleanup");
+        if (cleanupProp != null)
+            cleanupAfterTests = (0 < cleanupProp.trim().length());
+
         String disableCredStore = System.getProperty("test.disablecredstore");
         if (disableCredStore != null)
         {
@@ -510,6 +525,16 @@ class SVNTests extends TestCase
         client.dispose();
         // remove the temporary directory
         removeDirOrFile(localTmp);
+
+        // optionally remove the test directories
+        List<File> td = testDirs;
+        testDirs = null;
+        if (cleanupAfterTests && td != null)
+        {
+            for(File f: td)
+                removeDirOrFile(f);
+        }
+
         super.tearDown();
     }
 
@@ -788,6 +813,13 @@ class SVNTests extends TestCase
             return wc;
         }
 
+        private void trackDir(File dir)
+        {
+            if (testDirs == null)
+                testDirs = new ArrayList<File>();
+            testDirs.add(dir);
+        }
+
         /**
          * Create the repository for the beginning of the test.
          * Assumes that {@link #testName} has been set.
@@ -804,6 +836,7 @@ class SVNTests extends TestCase
             // build a clean repository directory
             File repos = new File(repositories, this.testName);
             removeDirOrFile(repos);
+            trackDir(repos);
             // create and load the repository from the default repository dump
             admin.create(repos, true, false, conf, fsType);
             if (loadGreek)
@@ -829,6 +862,7 @@ class SVNTests extends TestCase
             URI uri = makeReposUrl(repos);
             workingCopy = new File(workingCopies, this.testName);
             removeDirOrFile(workingCopy);
+            trackDir(workingCopy);
             // checkout the repository
             client.checkout(uri.toString(), workingCopy.getAbsolutePath(),
                    null, null, Depth.infinity, false, false);

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNAdminTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNAdminTests.java?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNAdminTests.java (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/SVNAdminTests.java Wed May 13 04:51:26 2015
@@ -35,13 +35,33 @@ import org.tigris.subversion.javahl.Subv
  */
 public class SVNAdminTests extends SVNTests
 {
+    /**
+     * Base name of all our tests.
+     */
+    public final static String testName = "admin_test";
+
     public SVNAdminTests()
     {
+        init();
     }
 
     public SVNAdminTests(String name)
     {
         super(name);
+        init();
+    }
+
+    /**
+     * Initialize the testBaseName and the testCounter, if this is the
+     * first test of this class.
+     */
+    private void init()
+    {
+        if (!testName.equals(testBaseName))
+        {
+            testCounter = 0;
+            testBaseName = testName;
+        }
     }
 
     /**

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/swig/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/swig/INSTALL?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/swig/INSTALL (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/swig/INSTALL Wed May 13 04:51:26 2015
@@ -65,7 +65,7 @@ BUILDING SWIG BINDINGS FOR SVN ON UNIX
 
 
 Step 1:  Install a suitable version of SWIG (which is
-         currently SWIG version 1.3.24 or later).
+         currently SWIG version 1.3.24 or later, but not SWIG 3.0.0 or newer).
 
     * Perhaps your distribution packages a suitable version - if it does
       install it, and skip to the last bullet point in this section.

Modified: subversion/branches/1.10-cache-improvements/subversion/bindings/swig/include/apr.swg
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/bindings/swig/include/apr.swg?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/bindings/swig/include/apr.swg (original)
+++ subversion/branches/1.10-cache-improvements/subversion/bindings/swig/include/apr.swg Wed May 13 04:51:26 2015
@@ -31,23 +31,21 @@
 */
 #ifdef SWIGPERL
 %typemap(out) long long {
-    char temp[256];
+    char temp[30];
     sprintf(temp, "%" APR_INT64_T_FMT, (apr_int64_t) $1);
-    ST(argvi) = sv_newmortal();
-    sv_setpv((SV*)ST(argvi++), temp);
+    %append_output(sv_2mortal(newSVpv(temp, 0)));
 }
 
 %typemap(out) unsigned long long {
-    char temp[256];
+    char temp[30];
     sprintf(temp, "%" APR_UINT64_T_FMT, (apr_uint64_t) $1);
-    ST(argvi) = sv_newmortal();
-    sv_setpv((SV*)ST(argvi++), temp);
+    %append_output(sv_2mortal(newSVpv(temp, 0)));
 }
 
 %typemap(in, numinputs=0) long long *OUTPUT (apr_int64_t temp)
     "$1 = &temp;";
 %typemap(argout) long long *OUTPUT {
-  char temp[256];
+  char temp[30];
   sprintf(temp, "%" APR_INT64_T_FMT, (apr_int64_t)*($1));
   %append_output(sv_2mortal(newSVpv(temp, 0)));
 }
@@ -55,7 +53,7 @@
 %typemap(in, numinputs=0) unsigned long long *OUTPUT (apr_uint64_t temp)
     "$1 = &temp;";
 %typemap(argout) unsigned long long *OUTPUT {
-  char temp[256];
+  char temp[30];
   sprintf(temp, "%" APR_UINT64_T_FMT, (apr_uint64_t)*($1));
   %append_output(sv_2mortal(newSVpv(temp, 0)));
 }

Modified: subversion/branches/1.10-cache-improvements/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/private/svn_client_private.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/private/svn_client_private.h Wed May 13 04:51:26 2015
@@ -40,6 +40,51 @@ extern "C" {
 #endif /* __cplusplus */
 
 
+/* Set *REVNUM to the revision number identified by REVISION.
+
+   If REVISION->kind is svn_opt_revision_number, just use
+   REVISION->value.number, ignoring LOCAL_ABSPATH and RA_SESSION.
+
+   Else if REVISION->kind is svn_opt_revision_committed,
+   svn_opt_revision_previous, or svn_opt_revision_base, or
+   svn_opt_revision_working, then the revision can be identified
+   purely based on the working copy's administrative information for
+   LOCAL_ABSPATH, so RA_SESSION is ignored.  If LOCAL_ABSPATH is not
+   under revision control, return SVN_ERR_UNVERSIONED_RESOURCE, or if
+   LOCAL_ABSPATH is null, return SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED.
+
+   Else if REVISION->kind is svn_opt_revision_date or
+   svn_opt_revision_head, then RA_SESSION is used to retrieve the
+   revision from the repository (using REVISION->value.date in the
+   former case), and LOCAL_ABSPATH is ignored.  If RA_SESSION is null,
+   return SVN_ERR_CLIENT_RA_ACCESS_REQUIRED.
+
+   Else if REVISION->kind is svn_opt_revision_unspecified, set
+   *REVNUM to SVN_INVALID_REVNUM.
+
+   If YOUNGEST_REV is non-NULL, it is an in/out parameter.  If
+   *YOUNGEST_REV is valid, use it as the youngest revision in the
+   repository (regardless of reality) -- don't bother to lookup the
+   true value for HEAD, and don't return any value in *REVNUM greater
+   than *YOUNGEST_REV.  If *YOUNGEST_REV is not valid, and a HEAD
+   lookup is required to populate *REVNUM, then also populate
+   *YOUNGEST_REV with the result.  This is useful for making multiple
+   serialized calls to this function with a basically static view of
+   the repository, avoiding race conditions which could occur between
+   multiple invocations with HEAD lookup requests.
+
+   Else return SVN_ERR_CLIENT_BAD_REVISION.
+
+   Use SCRATCH_POOL for any temporary allocation.  */
+svn_error_t *
+svn_client__get_revision_number(svn_revnum_t *revnum,
+                                svn_revnum_t *youngest_rev,
+                                svn_wc_context_t *wc_ctx,
+                                const char *local_abspath,
+                                svn_ra_session_t *ra_session,
+                                const svn_opt_revision_t *revision,
+                                apr_pool_t *scratch_pool);
+
 /* Return true if KIND is a revision kind that is dependent on the working
  * copy. Otherwise, return false. */
 #define SVN_CLIENT__REVKIND_NEEDS_WC(kind)                                 \

Modified: subversion/branches/1.10-cache-improvements/subversion/include/private/svn_cmdline_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/private/svn_cmdline_private.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/private/svn_cmdline_private.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/private/svn_cmdline_private.h Wed May 13 04:51:26 2015
@@ -88,11 +88,15 @@ typedef struct svn_cmdline__config_argum
  * containing svn_cmdline__config_argument_t* elements, allocating the option
  * data in @a pool
  *
+ * [Since 1.9/1.10:] If the file, section, or option value is not recognized,
+ * warn to @c stderr, using @a prefix as in svn_handle_warning2().
+ *
  * @since New in 1.7.
  */
 svn_error_t *
 svn_cmdline__parse_config_option(apr_array_header_t *config_options,
                                  const char *opt_arg,
+                                 const char *prefix,
                                  apr_pool_t *pool);
 
 /** Sets the config options in @a config_options, an apr array containing
@@ -220,6 +224,20 @@ svn_boolean_t
 svn_cmdline__be_interactive(svn_boolean_t non_interactive,
                             svn_boolean_t force_interactive);
 
+/* Parses the argument value of '--trust-server-cert-failures' OPT_ARG into
+ * the expected booleans for passing to svn_cmdline_create_auth_baton2()
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_cmdline__parse_trust_options(
+                        svn_boolean_t *trust_server_cert_unknown_ca,
+                        svn_boolean_t *trust_server_cert_cn_mismatch,
+                        svn_boolean_t *trust_server_cert_expired,
+                        svn_boolean_t *trust_server_cert_not_yet_valid,
+                        svn_boolean_t *trust_server_cert_other_failure,
+                        const char *opt_arg,
+                        apr_pool_t *scratch_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/1.10-cache-improvements/subversion/include/private/svn_mutex.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/private/svn_mutex.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/private/svn_mutex.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/private/svn_mutex.h Wed May 13 04:51:26 2015
@@ -27,8 +27,6 @@
 #ifndef SVN_MUTEX_H
 #define SVN_MUTEX_H
 
-#include <apr_thread_mutex.h>
-
 #include "svn_error.h"
 
 #ifdef __cplusplus

Modified: subversion/branches/1.10-cache-improvements/subversion/include/private/svn_subr_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/private/svn_subr_private.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/private/svn_subr_private.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/private/svn_subr_private.h Wed May 13 04:51:26 2015
@@ -681,6 +681,11 @@ svn_boolean_t
 svn_bit_array__get(svn_bit_array__t *array,
                    apr_size_t idx);
 
+/* Return the global pool used by the DSO loader, this may be NULL if
+   no DSOs have been loaded. */
+apr_pool_t *
+svn_dso__pool(void);
+
 /** @} */
 
 #ifdef __cplusplus

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_client.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_client.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_client.h Wed May 13 04:51:26 2015
@@ -4109,6 +4109,13 @@ svn_client_mergeinfo_log_eligible(const
  * If @a remove_ignored_items is @c TRUE, remove ignored unversioned items
  * in @a dir after successful working copy cleanup.
  *
+ * If @a fix_recorded_timestamps is @c TRUE, this function fixes recorded
+ * timestamps for unmodified files in the working copy, reducing comparision
+ * time on future checks.
+ *
+ * If @a vacuum_pristines is @c TRUE, and @a dir_abspath points to the working
+ * copy root unreferenced files in the pristine store are removed.
+ *
  * When asked to remove unversioned or ignored items, and the working copy
  * is already locked, return #SVN_ERR_WC_LOCKED. This prevents accidental
  * working copy corruption in case users run the cleanup operation to

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_diff.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_diff.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_diff.h Wed May 13 04:51:26 2015
@@ -412,6 +412,9 @@ typedef enum svn_diff_conflict_display_s
 /** Given a vtable of @a output_fns/@a output_baton for consuming
  * differences, output the differences in @a diff.
  *
+ * If not @c NULL, call @a cancel_func with @a cancel_baton once or multiple
+ * times while processing larger diffs.
+ *
  * @since New in 1.9.
  */
 svn_error_t *
@@ -628,6 +631,9 @@ svn_diff_file_diff4(svn_diff_t **diff,
  * will be used in the generated diff output. Otherwise the legacy compile
  * time default will be used.
  *
+ * If not @c NULL, call @a cancel_func with @a cancel_baton once or multiple
+ * times while processing larger diffs.
+ *
  * @since New in 1.9.
  */
 svn_error_t *
@@ -645,7 +651,7 @@ svn_diff_file_output_unified4(svn_stream
                               void *cancel_baton,
                               apr_pool_t *scratch_pool);
 
-/** Similar to svn_diff_file_output_unified3(), but without cancel
+/** Similar to svn_diff_file_output_unified4(), but without cancel
  * support and with @a context_size set to -1.
  *
  * @since New in 1.5.
@@ -708,6 +714,9 @@ svn_diff_file_output_unified(svn_stream_
  * @a conflict_style dictates how conflicts are displayed. 
  * Uses @a scratch_pool for temporary allocations.
  *
+ * If not @c NULL, call @a cancel_func with @a cancel_baton once or multiple
+ * times while processing larger diffs.
+ *
  * @since New in 1.9.
  */
 svn_error_t *
@@ -783,7 +792,10 @@ svn_diff_file_output_merge(svn_stream_t
  * Either @a original or @a latest may be NULL to describe that the version
  * didn't exist.
  *
- * Writes the ouput to @a output_stream.
+ * Writes the output to @a output_stream.
+ *
+ * If not @c NULL, call @a cancel_func with @a cancel_baton once or multiple
+ * times while processing larger diffs.
  *
  * @since New in 1.9.
  */
@@ -859,6 +871,9 @@ svn_diff_mem_string_diff4(svn_diff_t **d
  * will be used in the generated diff output. Otherwise the legacy compile
  * time default will be used.
  *
+ * If not @c NULL, call @a cancel_func with @a cancel_baton once or multiple
+ * times while processing larger diffs.
+ *
  * Uses @a scratch_pool for temporary allocations.
  *
  * @since New in 1.9
@@ -927,6 +942,9 @@ svn_diff_mem_string_output_unified(svn_s
  *
  * @a conflict_style dictates how conflicts are displayed.
  *
+ * If not @c NULL, call @a cancel_func with @a cancel_baton once or multiple
+ * times while processing larger diffs.
+ *
  * Uses @a scratch_pool for temporary allocations.
  *
  * @since New in 1.9.

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_dirent_uri.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_dirent_uri.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_dirent_uri.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_dirent_uri.h Wed May 13 04:51:26 2015
@@ -363,9 +363,9 @@ svn_relpath_dirname(const char *relpath,
  * @since New in 1.9.
  */
 const char *
-svn_relpath_limit(const char *relpath,
-                  int max_components,
-                  apr_pool_t *result_pool);
+svn_relpath_prefix(const char *relpath,
+                   int max_components,
+                   apr_pool_t *result_pool);
 
 
 /** Divide the canonicalized @a uri into a uri @a *dirpath and a

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_error.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_error.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_error.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_error.h Wed May 13 04:51:26 2015
@@ -165,18 +165,16 @@ svn_error_wrap_apr(apr_status_t status,
                    ...)
        __attribute__((format(printf, 2, 3)));
 
-/** A quick n' easy way to create a wrapped exception with your own
- * message, before throwing it up the stack.  (It uses all of the
- * @a child's fields.)
+/** If @child is SVN_NO_ERROR, return SVN_NO_ERROR.
+ * Else, prepend a new error to the error chain of @a child. The new error
+ * uses @a new_msg as error message but all other error attributes (such
+ * as the error code) are copied from @a child.
  */
 svn_error_t *
 svn_error_quick_wrap(svn_error_t *child,
                      const char *new_msg);
 
-/** A quick n' easy way to create a wrapped exception with your own
- * printf-style error message produced by passing @a fmt, using
- * apr_psprintf(), before throwing it up the stack.  (It uses all of the
- * @a child's fields.)
+/** Like svn_error_quick_wrap(), but with format string support.
  *
  * @since New in 1.9.
  */

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_fs.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_fs.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_fs.h Wed May 13 04:51:26 2015
@@ -113,7 +113,7 @@ typedef struct svn_fs_t svn_fs_t;
  *
  * "2" is allowed, too and means "enable if efficient",
  * i.e. this will not create warning at runtime if there
- * if no efficient support for revprop caching.
+ * is no efficient support for revprop caching.
  *
  * @since New in 1.8.
  */
@@ -888,27 +888,39 @@ svn_fs_access_add_lock_token(svn_fs_acce
  * @{
  */
 
-/** Defines the possible ways two arbitrary node-revisions may be related.
+/** Defines the possible ways two arbitrary (root, path)-pairs may be
+ * related.
  *
  * @since New in 1.9.
  */
 typedef enum svn_fs_node_relation_t
 {
-  /** The node-revisions are not related.
-   * Node-revisions from different repositories are always unrelated.
-   * #svn_fs_compare_ids would return the value -1 in this case.
+  /** The (root, path)-pairs are not related, i.e. none of the other cases
+   * apply.  If the roots refer to different @c svn_fs_t instances, then
+   * they are always considered unrelated - even if the underlying
+   * repository is the same.
    */
   svn_fs_node_unrelated = 0,
 
-  /** They are the same node-revision, i.e. there is no intervening change.
-   * However, due to lazy copying, there may be part of different parent
-   * copies.  #svn_fs_compare_ids would return the value 0 in this case.
+  /** No changes have been made between the (root, path)-pairs, i.e. they
+   * have the same (relative) nodes in their sub-trees, corresponding sub-
+   * tree nodes have the same contents as well as properties and report the
+   * same "created-path" and "created-rev" data.  This implies having a
+   * common ancestor.
+   *
+   * However, due to efficiency considerations, the FS implementation may
+   * report some combinations as merely having a common ancestor
+   * (@a svn_fs_node_common_ancestor) instead of actually being unchanged.
    */
-  svn_fs_node_same,
+  svn_fs_node_unchanged,
 
-  /** The node-revisions have a common ancestor (which may be one of them)
-   * but are not the same.
-   * #svn_fs_compare_ids would return the value 1 in this case.
+  /** The (root, path)-pairs have a common ancestor (which may be one of
+   * them) but there are changes between them, i.e. they don't fall into
+   * the @c svn_fs_node_unchanged category.
+   *
+   * Due to efficiency considerations, the FS implementation may falsely
+   * classify some combinations as merely having a common ancestor that
+   * are, in fact, unchanged (@a svn_fs_node_unchanged).
    */
   svn_fs_node_common_ancestor
 
@@ -1811,6 +1823,18 @@ svn_fs_node_proplist(apr_hash_t **table_
                      const char *path,
                      apr_pool_t *pool);
 
+/** Set @a *has_props to TRUE if the node @a path in @a root has properties
+ * and to FALSE if it doesn't have properties. Perform temporary allocations
+ * in @a scratch_pool.
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_fs_node_has_props(svn_boolean_t *has_props,
+                      svn_fs_root_t *root,
+                      const char *path,
+                      apr_pool_t *scratch_pool);
+
 
 /** Change a node's property's value, or add/delete a property.
  *
@@ -2086,7 +2110,8 @@ svn_fs_dir_entries(apr_hash_t **entries_
  * #svn_fs_dir_entries for @a root and determine an optimized ordering
  * in which data access would most likely be efficient.  Set @a *ordered_p
  * to a newly allocated APR array of pointers to these #svn_fs_dirent_t
- * structures.  Allocate the array (but not its contents) in @a pool.
+ * structures.  Allocate the array (but not its contents) in @a result_pool
+ * and use @a scratch_pool for temporaries.
  *
  * @since New in 1.9.
  */
@@ -2094,7 +2119,8 @@ svn_error_t *
 svn_fs_dir_optimal_order(apr_array_header_t **ordered_p,
                          svn_fs_root_t *root,
                          apr_hash_t *entries,
-                         apr_pool_t *pool);
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
 
 /** Create a new directory named @a path in @a root.  The new directory has
  * no entries, and no properties.  @a root must be the root of a transaction,
@@ -2638,8 +2664,8 @@ svn_fs_set_uuid(svn_fs_t *fs,
  */
 typedef struct svn_fs_lock_target_t svn_fs_lock_target_t;
 
-/** Create an <tt>svn_fs_lock_target_t</tt> allocated in @a pool. @a
- * token can be NULL and @a current_rev can be SVN_INVALID_REVNUM.
+/** Create an <tt>svn_fs_lock_target_t</tt> allocated in @a result_pool.
+ * @a token can be NULL and @a current_rev can be SVN_INVALID_REVNUM.
  *
  * The @a token is not duplicated and so must have a lifetime at least as
  * long as the returned target object.
@@ -2648,7 +2674,7 @@ typedef struct svn_fs_lock_target_t svn_
  */
 svn_fs_lock_target_t *svn_fs_lock_target_create(const char *token,
                                                 svn_revnum_t current_rev,
-                                                apr_pool_t *pool);
+                                                apr_pool_t *result_pool);
 
 /** Update @a target changing the token to @a token, @a token can be NULL.
  *
@@ -2668,7 +2694,12 @@ void svn_fs_lock_target_set_token(svn_fs
  * returns, use svn_error_dup() to preserve the error.
  *
  * If the callback returns an error no further callbacks will be made
- * and svn_fs_lock_many/svn_fs_unlock_many will return an error.
+ * and svn_fs_lock_many/svn_fs_unlock_many will return an error.  The
+ * caller cannot rely on any particular order for these callbacks and
+ * cannot rely on interrupting the underlying operation by returning
+ * an error.  Returning an error stops the callbacks but any locks
+ * that would have been reported in further callbacks may, or may not,
+ * still be created/released.
  *
  * @since New in 1.9.
  */
@@ -2676,7 +2707,7 @@ typedef svn_error_t *(*svn_fs_lock_callb
                                                const char *path,
                                                const svn_lock_t *lock,
                                                svn_error_t *fs_err,
-                                               apr_pool_t *pool);
+                                               apr_pool_t *scratch_pool);
 
 /** Lock the paths in @a lock_targets in @a fs.
  *
@@ -2716,13 +2747,17 @@ typedef svn_error_t *(*svn_fs_lock_callb
  *
  * For each path in @a lock_targets @a lock_callback will be invoked
  * passing @a lock_baton and the lock and error that apply to path.
- * @a lock_callback can be NULL in which case it is not called.
+ * @a lock_callback can be NULL in which case it is not called and any
+ * errors that would have been passed to the callback are not reported.
  *
  * The lock and path passed to @a lock_callback will be allocated in
  * @a result_pool.  Use @a scratch_pool for temporary allocations.
  *
  * @note At this time, only files can be locked.
  *
+ * @note This function is not atomic.  If it returns an error, some targets
+ * may remain unlocked while others may have been locked.
+ *
  * @note You probably don't want to use this directly.  Take a look at
  * svn_repos_fs_lock_many() instead.
  *
@@ -2790,11 +2825,15 @@ svn_fs_generate_lock_token(const char **
  * For each path in @a unlock_targets @a lock_callback will be invoked
  * passing @a lock_baton and error that apply to path.  The @a lock
  * passed to the callback will be NULL.  @a lock_callback can be NULL
- * in which case it is not called.
+ * in which case it is not called and any errors that would have been
+ * passed to the callback are not reported.
  *
  * The path passed to lock_callback will be allocated in @a result_pool.
  * Use @a scratch_pool for temporary allocations.
  *
+ * @note This function is not atomic.  If it returns an error, some targets
+ * may remain locked while others may have been unlocked.
+ *
  * @note You probably don't want to use this directly.  Take a look at
  * svn_repos_fs_unlock_many() instead.
  *

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_ra.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_ra.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_ra.h Wed May 13 04:51:26 2015
@@ -1094,11 +1094,10 @@ svn_ra_get_file(svn_ra_session_t *sessio
  * callers want to know, and some don't.)
  *
  * If @a props is non @c NULL, set @a *props to contain the properties of
- * the directory.  This means @em all properties: not just ones controlled by
- * the user and stored in the repository fs, but non-tweakable ones
- * generated by the SCM system itself (e.g. 'wcprops', 'entryprops',
- * etc.)  The keys are <tt>const char *</tt>, values are
- * <tt>@c svn_string_t *</tt>.
+ * the directory, including properties that are non-tweakable and
+ * generated by the SCM system itself (such as #svn_prop_wc_kind and
+ * #svn_prop_entry_kind properties).  The keys are <tt>const char *</tt>,
+ * values are <tt>@c svn_string_t *</tt>.
  *
  * @since New in 1.4.
  */

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_repos.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_repos.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_repos.h Wed May 13 04:51:26 2015
@@ -250,7 +250,7 @@ typedef enum svn_repos_notify_action_t
   svn_repos_notify_hotcopy_rev_range
 } svn_repos_notify_action_t;
 
-/** The type of error occurring.
+/** The type of warning occurring.
  *
  * @since New in 1.7.
  */
@@ -2265,10 +2265,12 @@ svn_repos_fs_begin_txn_for_update(svn_fs
  * The pre-lock is run for every path in @a targets. Those targets for
  * which the pre-lock is successful are passed to svn_fs_lock_many and
  * the post-lock is run for those that are successfully locked.
+ * Pre-lock hook errors are passed to @a lock_callback.
  *
  * For each path in @a targets @a lock_callback will be invoked
  * passing @a lock_baton and the lock and error that apply to path.
- * @a lock_callback can be NULL in which case it is not called.
+ * @a lock_callback can be NULL in which case it is not called and any
+ * errors that would have been passed to the callback are not reported.
  *
  * If an error occurs when running the post-lock hook the error is
  * returned wrapped with #SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED.  If the
@@ -2281,6 +2283,9 @@ svn_repos_fs_begin_txn_for_update(svn_fs
  * The lock and path passed to @a lock_callback will be allocated in
  * @a result_pool.  Use @a scratch_pool for temporary allocations.
  *
+ * @note This function is not atomic.  If it returns an error, some targets
+ * may remain unlocked while others may have been locked.
+ *
  * @see svn_fs_lock_many
  *
  * @since New in 1.9.
@@ -2320,12 +2325,14 @@ svn_repos_fs_lock(svn_lock_t **lock,
  * The pre-unlock hook is run for every path in @a targets. Those
  * targets for which the pre-unlock is successful are passed to
  * svn_fs_unlock_many and the post-unlock is run for those that are
- * successfully unlocked.
+ * successfully unlocked. Pre-unlock hook errors are passed to @a
+ * lock_callback.
  *
  * For each path in @a targets @a lock_callback will be invoked
  * passing @a lock_baton and error that apply to path.  The lock
  * passed to the callback will be NULL.  @a lock_callback can be NULL
- * in which case it is not called.
+ * in which case it is not called and any errors that would have been
+ * passed to the callback are not reported.
  *
  * If an error occurs when running the post-unlock hook, return the
  * original error wrapped with #SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED.
@@ -2335,6 +2342,9 @@ svn_repos_fs_lock(svn_lock_t **lock,
  * The path passed to @a lock_callback will be allocated in @a result_pool.
  * Use @a scratch_pool for temporary allocations.
  *
+ * @note This function is not atomic.  If it returns an error, some targets
+ * may remain locked while others may have been unlocked.
+ *
  * @see svn_fs_unlock_many
  *
  * @since New in 1.9.

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_types.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_types.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_types.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_types.h Wed May 13 04:51:26 2015
@@ -150,17 +150,22 @@ typedef int svn_boolean_t;
 
 
 
-/** Declaration of the null pointer constant type.
+/* Declaration of a unique type, never defined, for the SVN_VA_NULL macro.
  *
- * @since New in 1.9.
+ * NOTE: Private. Not for direct use by third-party code.
  */
-struct svn_null_pointer_constant_stdarg_sentinel_t;
+struct svn__null_pointer_constant_stdarg_sentinel_t;
 
 /** Null pointer constant used as a sentinel in variable argument lists.
  *
+ * Use of this macro ensures that the argument is of the correct size when a
+ * pointer is expected. (The macro @c NULL is not defined as a pointer on
+ * all systems, and the arguments to variadic functions are not converted
+ * automatically to the expected type.)
+ *
  * @since New in 1.9.
  */
-#define SVN_VA_NULL ((struct svn_null_pointer_constant_stdarg_sentinel_t*)0)
+#define SVN_VA_NULL ((struct svn__null_pointer_constant_stdarg_sentinel_t*)0)
 /* See? (char*)NULL -- They have the same length, but the cast looks ugly. */
 
 

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_wc.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_wc.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_wc.h Wed May 13 04:51:26 2015
@@ -1911,8 +1911,9 @@ typedef struct svn_wc_conflict_descripti
   /** The path that is in conflict (for a tree conflict, it is the victim) */
   const char *path;
 
-  /** The node type of the path being operated on (for a tree conflict,
-   *  ### which version?) */
+  /** The local node type of the path being operated on (for a tree conflict,
+   *  this specifies the local node kind, which may be (and typically is)
+   *  different than the left and right kind) */
   svn_node_kind_t node_kind;
 
   /** What sort of conflict are we describing? */
@@ -2063,7 +2064,7 @@ svn_wc_conflict_description_create_prop(
  *
  * Set the @c local_abspath field of the created struct to @a local_abspath
  * (which must be an absolute path), the @c kind field to
- * #svn_wc_conflict_kind_tree, the @c local_node_kind to @a local_node_kind,
+ * #svn_wc_conflict_kind_tree, the @c node_kind to @a node_kind,
  * the @c operation to @a operation, the @c src_left_version field to
  * @a src_left_version, and the @c src_right_version field to
  * @a src_right_version.
@@ -2104,7 +2105,7 @@ svn_wc_conflict_description_create_tree(
 /** Return a duplicate of @a conflict, allocated in @a result_pool.
  * A deep copy of all members will be made.
  *
- * @since New in 1.7.
+ * @since New in 1.9.
  */
 svn_wc_conflict_description2_t *
 svn_wc_conflict_description2_dup(
@@ -2131,8 +2132,11 @@ svn_wc__conflict_description2_dup(
  */
 typedef enum svn_wc_conflict_choice_t
 {
-  /** Undefined; for internal use only.
-      This value is never returned in svn_wc_conflict_result_t.
+  /** Undefined; for private use only.
+      This value must never be returned in svn_wc_conflict_result_t,
+      but a separate value, unequal to all other pre-defined values may
+      be useful in conflict resolver implementations to signal that no
+      choice is made yet.
    * @since New in 1.9
    */
   svn_wc_conflict_choose_undefined = -1,
@@ -4657,6 +4661,9 @@ svn_wc_delete(const char *path,
  * If @a local_abspath does not exist as file, directory or symlink, return
  * #SVN_ERR_WC_PATH_NOT_FOUND.
  *
+ * If @a notify_func is non-NULL, invoke it with @a notify_baton to report
+ * the item being added.
+ *
  * ### TODO: Split into add_dir, add_file, add_symlink?
  *
  * @since New in 1.9.
@@ -4672,7 +4679,7 @@ svn_wc_add_from_disk3(svn_wc_context_t *
 
 /**
  * Similar to svn_wc_add_from_disk3(), but always passes FALSE for
- * @a skip_som_prop_canon
+ * @a skip_checks
  *
  * @since New in 1.8.
  * @deprecated Provided for backward compatibility with the 1.8 API.
@@ -7304,6 +7311,12 @@ svn_wc_get_pristine_copy_path(const char
  * points during the operation.  If it returns an error (typically
  * #SVN_ERR_CANCELLED), return that error immediately.
  *
+ * If @a notify_func is non-NULL, invoke it with @a notify_baton to report
+ * the progress of the operation.
+ *
+ * @note In 1.9, @a notify_func does not get called at all.  This may change
+ * in later releases.
+ *
  * @since New in 1.9.
  */
 svn_error_t *

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_client/client.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_client/client.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_client/client.h Wed May 13 04:51:26 2015
@@ -73,52 +73,6 @@ typedef struct svn_client__private_ctx_t
 svn_client__private_ctx_t *
 svn_client__get_private_ctx(svn_client_ctx_t *ctx);
 
-
-/* Set *REVNUM to the revision number identified by REVISION.
-
-   If REVISION->kind is svn_opt_revision_number, just use
-   REVISION->value.number, ignoring LOCAL_ABSPATH and RA_SESSION.
-
-   Else if REVISION->kind is svn_opt_revision_committed,
-   svn_opt_revision_previous, or svn_opt_revision_base, or
-   svn_opt_revision_working, then the revision can be identified
-   purely based on the working copy's administrative information for
-   LOCAL_ABSPATH, so RA_SESSION is ignored.  If LOCAL_ABSPATH is not
-   under revision control, return SVN_ERR_UNVERSIONED_RESOURCE, or if
-   LOCAL_ABSPATH is null, return SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED.
-
-   Else if REVISION->kind is svn_opt_revision_date or
-   svn_opt_revision_head, then RA_SESSION is used to retrieve the
-   revision from the repository (using REVISION->value.date in the
-   former case), and LOCAL_ABSPATH is ignored.  If RA_SESSION is null,
-   return SVN_ERR_CLIENT_RA_ACCESS_REQUIRED.
-
-   Else if REVISION->kind is svn_opt_revision_unspecified, set
-   *REVNUM to SVN_INVALID_REVNUM.
-
-   If YOUNGEST_REV is non-NULL, it is an in/out parameter.  If
-   *YOUNGEST_REV is valid, use it as the youngest revision in the
-   repository (regardless of reality) -- don't bother to lookup the
-   true value for HEAD, and don't return any value in *REVNUM greater
-   than *YOUNGEST_REV.  If *YOUNGEST_REV is not valid, and a HEAD
-   lookup is required to populate *REVNUM, then also populate
-   *YOUNGEST_REV with the result.  This is useful for making multiple
-   serialized calls to this function with a basically static view of
-   the repository, avoiding race conditions which could occur between
-   multiple invocations with HEAD lookup requests.
-
-   Else return SVN_ERR_CLIENT_BAD_REVISION.
-
-   Use SCRATCH_POOL for any temporary allocation.  */
-svn_error_t *
-svn_client__get_revision_number(svn_revnum_t *revnum,
-                                svn_revnum_t *youngest_rev,
-                                svn_wc_context_t *wc_ctx,
-                                const char *local_abspath,
-                                svn_ra_session_t *ra_session,
-                                const svn_opt_revision_t *revision,
-                                apr_pool_t *scratch_pool);
-
 /* Set *ORIGINAL_REPOS_RELPATH and *ORIGINAL_REVISION to the original location
    that served as the source of the copy from which PATH_OR_URL at REVISION was
    created, or NULL and SVN_INVALID_REVNUM (respectively) if PATH_OR_URL at

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_client/copy.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_client/copy.c Wed May 13 04:51:26 2015
@@ -300,10 +300,12 @@ make_external_description(const char **n
   return SVN_NO_ERROR;
 }
 
-/* Pin all externals listed in EXTERNALS_PROP_VAL to their last-changed
- * revision. Return a new property value in *PINNED_EXTERNALS allocated
- * in RESULT_POOL. LOCAL_ABSPATH_OR_URL is the path or URL defining the
- * svn:externals property. Use SCRATCH_POOL for temporary allocations.
+/* Pin all externals listed in EXTERNALS_PROP_VAL to their
+ * last-changed revision. Set *PINNED_EXTERNALS to a new property
+ * value allocated in RESULT_POOL, or to NULL if none of the externals
+ * in EXTERNALS_PROP_VAL were changed. LOCAL_ABSPATH_OR_URL is the
+ * path or URL defining the svn:externals property. Use SCRATCH_POOL
+ * for temporary allocations.
  */
 static svn_error_t *
 pin_externals_prop(svn_string_t **pinned_externals,
@@ -319,6 +321,7 @@ pin_externals_prop(svn_string_t **pinned
   apr_array_header_t *external_items;
   apr_array_header_t *parser_infos;
   apr_array_header_t *items_to_pin;
+  int pinned_items;
   int i;
   apr_pool_t *iterpool;
 
@@ -330,13 +333,22 @@ pin_externals_prop(svn_string_t **pinned
                                               scratch_pool));
 
   if (externals_to_pin)
-    items_to_pin = svn_hash_gets((apr_hash_t *)externals_to_pin,
-                                 local_abspath_or_url);
+    {
+      items_to_pin = svn_hash_gets((apr_hash_t *)externals_to_pin,
+                                   local_abspath_or_url);
+      if (!items_to_pin)
+        {
+          /* No pinning at all for this path. */
+          *pinned_externals = NULL;
+          return SVN_NO_ERROR;
+        }
+    }
   else
     items_to_pin = NULL;
 
   buf = svn_stringbuf_create_empty(scratch_pool);
   iterpool = svn_pool_create(scratch_pool);
+  pinned_items = 0;
   for (i = 0; i < external_items->nelts; i++)
     {
       svn_wc_external_item2_t *item;
@@ -386,11 +398,13 @@ pin_externals_prop(svn_string_t **pinned
 
       if (item->peg_revision.kind == svn_opt_revision_date)
         {
+          /* Already pinned ... copy the peg date. */
           external_pegrev.kind = svn_opt_revision_date;
           external_pegrev.value.date = item->peg_revision.value.date;
         }
       else if (item->peg_revision.kind == svn_opt_revision_number)
         {
+          /* Already pinned ... copy the peg revision number. */
           external_pegrev.kind = svn_opt_revision_number;
           external_pegrev.value.number = item->peg_revision.value.number;
         }
@@ -400,6 +414,9 @@ pin_externals_prop(svn_string_t **pinned
             item->peg_revision.kind == svn_opt_revision_head ||
             item->peg_revision.kind == svn_opt_revision_unspecified);
 
+          /* We're actually going to change the peg revision. */
+          ++pinned_items;
+
           if (svn_path_is_url(local_abspath_or_url))
             {
               const char *resolved_url;
@@ -539,14 +556,19 @@ pin_externals_prop(svn_string_t **pinned
     }
   svn_pool_destroy(iterpool);
 
-  *pinned_externals = svn_string_create_from_buf(buf, result_pool);
+  if (pinned_items > 0)
+    *pinned_externals = svn_string_create_from_buf(buf, result_pool);
+  else
+    *pinned_externals = NULL;
 
   return SVN_NO_ERROR;
 }
 
-/* Return, in *NEW_EXTERNALS, a new hash of externals definitions, some or
- * which all of which are pinned. If EXTERNALS_TO_PIN is NULL, pin all
- * externals, else pin the externals mentioned in EXTERNALS_TO_PIN.
+/* Return, in *PINNED_EXTERNALS, a new hash mapping URLs or local abspaths
+ * to svn:externals property values (as const char *), where some or all
+ * external references have been pinned.
+ * If EXTERNALS_TO_PIN is NULL, pin all externals, else pin the externals
+ * mentioned in EXTERNALS_TO_PIN.
  * The pinning operation takes place as part of the copy operation for
  * the source/destination pair PAIR. Use RA_SESSION and REPOS_ROOT_URL
  * to contact the repository containing the externals definition, if neccesary.
@@ -554,7 +576,7 @@ pin_externals_prop(svn_string_t **pinned
  * neccessary. Allocate *NEW_EXTERNALS in RESULT_POOL.
  * Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
-resolve_pinned_externals(apr_hash_t **new_externals,
+resolve_pinned_externals(apr_hash_t **pinned_externals,
                          const apr_hash_t *externals_to_pin,
                          svn_client__copy_pair_t *pair,
                          svn_ra_session_t *ra_session,
@@ -568,7 +590,7 @@ resolve_pinned_externals(apr_hash_t **ne
   apr_hash_index_t *hi;
   apr_pool_t *iterpool;
 
-  *new_externals = apr_hash_make(result_pool);
+  *pinned_externals = apr_hash_make(result_pool);
 
   if (svn_path_is_url(pair->src_abspath_or_url))
     {
@@ -630,15 +652,19 @@ resolve_pinned_externals(apr_hash_t **ne
                                  externals_to_pin,
                                  repos_root_url, local_abspath_or_url, ctx,
                                  result_pool, iterpool));
-      if (svn_path_is_url(pair->src_abspath_or_url))
-        relpath = svn_uri_skip_ancestor(pair->src_abspath_or_url,
-                                        local_abspath_or_url,
-                                        result_pool);
-      else
-        relpath = svn_dirent_skip_ancestor(pair->src_abspath_or_url,
-                                           local_abspath_or_url);
-      SVN_ERR_ASSERT(relpath);
-      svn_hash_sets(*new_externals, relpath, new_propval);
+      if (new_propval)
+        {
+          if (svn_path_is_url(pair->src_abspath_or_url))
+            relpath = svn_uri_skip_ancestor(pair->src_abspath_or_url,
+                                            local_abspath_or_url,
+                                            result_pool);
+          else
+            relpath = svn_dirent_skip_ancestor(pair->src_abspath_or_url,
+                                               local_abspath_or_url);
+          SVN_ERR_ASSERT(relpath);
+
+          svn_hash_sets(*pinned_externals, relpath, new_propval);
+        }
     }
   svn_pool_destroy(iterpool);
 
@@ -1616,7 +1642,10 @@ repos_to_repos_copy(const apr_array_head
           && (relpath != NULL && *relpath != '\0'))
         {
           info->resurrection = TRUE;
-          top_url = svn_uri_dirname(top_url, pool);
+          top_url = svn_uri_get_longest_ancestor(
+                            top_url,
+                            svn_uri_dirname(pair->dst_abspath_or_url, pool),
+                            pool);
           SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));
         }
     }

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_client/export.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_client/export.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_client/export.c Wed May 13 04:51:26 2015
@@ -1508,7 +1508,7 @@ svn_client_export5(svn_revnum_t *result_
       eib.ignore_keywords = ignore_keywords;
       eib.wc_ctx = ctx->wc_ctx;
       eib.native_eol = native_eol;
-      eib.notify_func = ctx->notify_func2;;
+      eib.notify_func = ctx->notify_func2;
       eib.notify_baton = ctx->notify_baton2;
       eib.origin_abspath = from_path_or_url;
       eib.exported = FALSE;

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/editor.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/editor.c Wed May 13 04:51:26 2015
@@ -249,7 +249,7 @@ can_modify(svn_fs_root_t *txn_root,
       svn_fs_close_root(rev_root);
 
       /* Has the target node changed in the future?  */
-      if (relation != svn_fs_node_same)
+      if (relation != svn_fs_node_unchanged)
         {
           /* Restarting the commit will base the txn on the future/new
              revision, allowing the modification at REVISION.  */

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.c Wed May 13 04:51:26 2015
@@ -27,7 +27,6 @@
 #include <apr_atomic.h>
 #include <apr_hash.h>
 #include <apr_md5.h>
-#include <apr_thread_mutex.h>
 #include <apr_uuid.h>
 #include <apr_strings.h>
 
@@ -140,7 +139,7 @@ load_module(fs_init_func_t *initfunc, co
                                  _("Invalid name for FS type '%s'"),
                                  name);
 
-    libname = apr_psprintf(pool, "libsvn_fs_%s-%d.so.%d",
+    libname = apr_psprintf(pool, "libsvn_fs_%s-" SVN_DSO_SUFFIX_FMT,
                            name, SVN_VER_MAJOR, SVN_SOVERSION);
     funcname = apr_psprintf(pool, "svn_fs_%s__init", name);
 
@@ -1197,6 +1196,16 @@ svn_fs_node_proplist(apr_hash_t **table_
 }
 
 svn_error_t *
+svn_fs_node_has_props(svn_boolean_t *has_props,
+                      svn_fs_root_t *root,
+                      const char *path,
+                      apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(root->vtable->node_has_props(has_props, root, path,
+                                                      scratch_pool));
+}
+
+svn_error_t *
 svn_fs_change_node_prop(svn_fs_root_t *root, const char *path,
                         const char *name, const svn_string_t *value,
                         apr_pool_t *pool)
@@ -1321,10 +1330,13 @@ svn_error_t *
 svn_fs_dir_optimal_order(apr_array_header_t **ordered_p,
                          svn_fs_root_t *root,
                          apr_hash_t *entries,
-                         apr_pool_t *pool)
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
   return svn_error_trace(root->vtable->dir_optimal_order(ordered_p, root,
-                                                         entries, pool));
+                                                         entries,
+                                                         result_pool,
+                                                         scratch_pool));
 }
 
 svn_error_t *
@@ -1759,9 +1771,10 @@ svn_fs_generate_lock_token(const char **
 svn_fs_lock_target_t *
 svn_fs_lock_target_create(const char *token,
                           svn_revnum_t current_rev,
-                          apr_pool_t *pool)
+                          apr_pool_t *result_pool)
 {
-  svn_fs_lock_target_t *target = apr_palloc(pool, sizeof(svn_fs_lock_target_t));
+  svn_fs_lock_target_t *target = apr_palloc(result_pool,
+                                            sizeof(svn_fs_lock_target_t));
 
   target->token = token;
   target->current_rev = current_rev;
@@ -1899,7 +1912,7 @@ svn_fs_compare_ids(const svn_fs_id_t *a,
 {
   switch (a->vtable->compare(a, b))
     {
-    case svn_fs_node_same:
+    case svn_fs_node_unchanged:
       return 0;
     case svn_fs_node_common_ancestor:
       return 1;

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs/fs-loader.h Wed May 13 04:51:26 2015
@@ -346,6 +346,8 @@ typedef struct root_vtable_t
                             apr_pool_t *pool);
   svn_error_t *(*node_proplist)(apr_hash_t **table_p, svn_fs_root_t *root,
                                 const char *path, apr_pool_t *pool);
+  svn_error_t *(*node_has_props)(svn_boolean_t *has_props, svn_fs_root_t *root,
+                                 const char *path, apr_pool_t *scratch_pool);
   svn_error_t *(*change_node_prop)(svn_fs_root_t *root, const char *path,
                                    const char *name,
                                    const svn_string_t *value,
@@ -361,7 +363,8 @@ typedef struct root_vtable_t
   svn_error_t *(*dir_optimal_order)(apr_array_header_t **ordered_p,
                                     svn_fs_root_t *root,
                                     apr_hash_t *entries,
-                                    apr_pool_t *pool);
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
   svn_error_t *(*make_dir)(svn_fs_root_t *root, const char *path,
                            apr_pool_t *pool);
 

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/fs.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/fs.c Wed May 13 04:51:26 2015
@@ -780,7 +780,7 @@ base_create(svn_fs_t *fs,
   ((base_fs_data_t *) fs->fsap_data)->format = format;
 
   SVN_ERR(populate_opened_fs(fs, pool));
-  return SVN_NO_ERROR;;
+  return SVN_NO_ERROR;
 
 error:
   return svn_error_compose_create(svn_err,

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/id.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/id.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/id.c Wed May 13 04:51:26 2015
@@ -113,7 +113,7 @@ svn_fs_base__id_compare(const svn_fs_id_
                         const svn_fs_id_t *b)
 {
   if (svn_fs_base__id_eq(a, b))
-    return svn_fs_node_same;
+    return svn_fs_node_unchanged;
   return (svn_fs_base__id_check_related(a, b) ? svn_fs_node_common_ancestor
                                               : svn_fs_node_unrelated);
 }

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/lock.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/lock.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/lock.c Wed May 13 04:51:26 2015
@@ -243,6 +243,7 @@ svn_fs_base__lock(svn_fs_t *fs,
   apr_hash_index_t *hi;
   svn_error_t *cb_err = SVN_NO_ERROR;
   svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
   SVN_ERR(svn_fs_base__youngest_rev(&youngest_rev, fs, scratch_pool));
@@ -255,6 +256,7 @@ svn_fs_base__lock(svn_fs_t *fs,
       svn_lock_t *lock;
       svn_error_t *err = NULL;
 
+      svn_pool_clear(iterpool);
       args.lock_p = &lock;
       args.path = svn_fs__canonicalize_abspath(path, result_pool);
       args.token = target->token;
@@ -275,11 +277,12 @@ svn_fs_base__lock(svn_fs_t *fs,
 
       if (!err)
         err = svn_fs_base__retry_txn(fs, txn_body_lock, &args, TRUE,
-                                     scratch_pool);
+                                     iterpool);
       if (!cb_err && lock_callback)
-        cb_err = lock_callback(lock_baton, args.path, lock, err, scratch_pool);
+        cb_err = lock_callback(lock_baton, args.path, lock, err, iterpool);
       svn_error_clear(err);
     }
+  svn_pool_destroy(iterpool);
 
   return svn_error_trace(cb_err);
 }
@@ -368,6 +371,7 @@ svn_fs_base__unlock(svn_fs_t *fs,
 {
   apr_hash_index_t *hi;
   svn_error_t *cb_err = SVN_NO_ERROR;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
 
@@ -378,16 +382,18 @@ svn_fs_base__unlock(svn_fs_t *fs,
       const char *token = apr_hash_this_val(hi);
       svn_error_t *err;
 
+      svn_pool_clear(iterpool);
       args.path = svn_fs__canonicalize_abspath(path, result_pool);
       args.token = token;
       args.break_lock = break_lock;
 
       err = svn_fs_base__retry_txn(fs, txn_body_unlock, &args, TRUE,
-                                   scratch_pool);
+                                   iterpool);
       if (!cb_err && lock_callback)
-        cb_err = lock_callback(lock_baton, path, NULL, err, scratch_pool);
+        cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
       svn_error_clear(err);
     }
+  svn_pool_destroy(iterpool);
 
   return svn_error_trace(cb_err);
 }

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/tree.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_base/tree.c Wed May 13 04:51:26 2015
@@ -1285,6 +1285,21 @@ base_node_proplist(apr_hash_t **table_p,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+base_node_has_props(svn_boolean_t *has_props,
+                    svn_fs_root_t *root,
+                    const char *path,
+                    apr_pool_t *scratch_pool)
+{
+  apr_hash_t *props;
+
+  SVN_ERR(base_node_proplist(&props, root, path, scratch_pool));
+
+  *has_props = (0 < apr_hash_count(props));
+
+  return SVN_NO_ERROR;
+}
+
 
 struct change_node_prop_args {
   svn_fs_root_t *root;
@@ -1608,13 +1623,15 @@ static svn_error_t *
 base_dir_optimal_order(apr_array_header_t **ordered_p,
                        svn_fs_root_t *root,
                        apr_hash_t *entries,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   /* 1:1 copy of entries with no differnce in ordering */
   apr_hash_index_t *hi;
-  apr_array_header_t *result = apr_array_make(pool, apr_hash_count(entries),
-                                              sizeof(svn_fs_dirent_t *));
-  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
+  apr_array_header_t *result
+    = apr_array_make(result_pool, apr_hash_count(entries),
+                     sizeof(svn_fs_dirent_t *));
+  for (hi = apr_hash_first(scratch_pool, entries); hi; hi = apr_hash_next(hi))
     APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = apr_hash_this_val(hi);
 
   *ordered_p = result;
@@ -3164,7 +3181,8 @@ txn_body_copy(void *baton,
   if ((to_parent_path->node)
       && (svn_fs_base__id_compare(svn_fs_base__dag_get_id(from_node),
                                   svn_fs_base__dag_get_id
-                                  (to_parent_path->node)) == svn_fs_node_same))
+                                  (to_parent_path->node))
+          == svn_fs_node_unchanged))
     return SVN_NO_ERROR;
 
   if (! from_root->is_txn_root)
@@ -5489,6 +5507,7 @@ static root_vtable_t root_vtable = {
   base_closest_copy,
   base_node_prop,
   base_node_proplist,
+  base_node_has_props,
   base_change_node_prop,
   base_props_changed,
   base_dir_entries,

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c Wed May 13 04:51:26 2015
@@ -286,6 +286,114 @@ use_block_read(svn_fs_t *fs)
   return svn_fs_fs__use_log_addressing(fs) && ffd->use_block_read;
 }
 
+svn_error_t *
+svn_fs_fs__fixup_expanded_size(svn_fs_t *fs,
+                               representation_t *rep,
+                               apr_pool_t *scratch_pool)
+{
+  svn_checksum_t checksum;
+  svn_checksum_t *empty_md5;
+  svn_fs_fs__revision_file_t *revision_file;
+  svn_fs_fs__rep_header_t *rep_header;
+
+  /* Anything to do at all?
+   *
+   * Note that a 0 SIZE is only possible for PLAIN reps due to the SVN\1
+   * magic prefix in any DELTA rep. */
+  if (!rep || rep->expanded_size != 0 || rep->size == 0)
+    return SVN_NO_ERROR;
+
+  /* This function may only be called for committed data. */
+  assert(!svn_fs_fs__id_txn_used(&rep->txn_id));
+
+  /* EXPANDED_SIZE is 0. If the MD5 does not match the one for empty
+   * contents, we know that EXPANDED_SIZE == 0 is wrong and needs to
+   * be set to the actual value given by SIZE.
+   *
+   * Using svn_checksum_match() will also accept all-zero values for
+   * the MD5 digest and only report a mismatch if the MD5 has actually
+   * been given. */
+  empty_md5 = svn_checksum_empty_checksum(svn_checksum_md5, scratch_pool);
+
+  checksum.digest = rep->md5_digest;
+  checksum.kind = svn_checksum_md5;
+  if (!svn_checksum_match(empty_md5, &checksum))
+    {
+      rep->expanded_size = rep->size;
+      return SVN_NO_ERROR;
+    }
+
+  /* Data in the rep-cache.db does not have MD5 checksums (all zero) on it.
+   * Compare SHA1 instead. */
+  if (rep->has_sha1)
+    {
+      svn_checksum_t *empty_sha1
+        = svn_checksum_empty_checksum(svn_checksum_sha1, scratch_pool);
+
+      checksum.digest = rep->sha1_digest;
+      checksum.kind = svn_checksum_sha1;
+      if (!svn_checksum_match(empty_sha1, &checksum))
+        {
+          rep->expanded_size = rep->size;
+          return SVN_NO_ERROR;
+        }
+    }
+
+  /* Only two cases are left here.
+   * (1) A non-empty PLAIN rep with a MD5 collision on EMPTY_MD5.
+   * (2) A DELTA rep with zero-length output. */
+
+  /* SVN always stores a DELTA rep with zero-length output as an empty
+   * sequence of txdelta windows, i.e. as "SVN\1".  In that case, SIZE is
+   * 4 bytes.  There is no other possible DELTA rep of that size and any
+   * PLAIN rep of 4 bytes would produce a different MD5.  Hence, if SIZE is
+   * actually 4 here, we know that this is an empty DELTA rep.
+   *
+   * Note that it is technically legal to have DELTA reps with a 0 length
+   * output window.  Their on-disk size would be longer.  We handle that
+   * case later together with the equally unlikely MD5 collision. */
+  if (rep->size == 4)
+    {
+      /* EXPANDED_SIZE is already 0. */
+      return SVN_NO_ERROR;
+    }
+
+  /* We still have the two options, PLAIN or DELTA rep.  At this point, we
+   * are in an extremely unlikely case and can spend some time to figure it
+   * out.  So, let's just look at the representation header. */
+  SVN_ERR(open_and_seek_revision(&revision_file, fs, rep->revision,
+                                 rep->item_index, scratch_pool));
+  SVN_ERR(svn_fs_fs__read_rep_header(&rep_header, revision_file->stream,
+                                     scratch_pool, scratch_pool));
+  SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
+
+  /* Only for PLAIN reps do we have to correct EXPANDED_SIZE. */
+  if (rep_header->type == svn_fs_fs__rep_plain)
+    rep->expanded_size = rep->size;
+
+  return SVN_NO_ERROR;
+}
+
+/* Correct known issues with committed NODEREV in FS.
+ * Uses SCRATCH_POOL for temporaries.
+ */
+static svn_error_t *
+fixup_node_revision(svn_fs_t *fs,
+                    node_revision_t *noderev,
+                    apr_pool_t *scratch_pool)
+{
+  /* Workaround issue #4031: is-fresh-txn-root in revision files. */
+  noderev->is_fresh_txn_root = FALSE;
+
+  /* Make sure EXPANDED_SIZE has the correct value for every rep. */
+  SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, noderev->data_rep,
+                                         scratch_pool));
+  SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, noderev->prop_rep,
+                                         scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Get the node-revision for the node ID in FS.
    Set *NODEREV_P to the new node-revision structure, allocated in POOL.
    See svn_fs_fs__get_node_revision, which wraps this and adds another
@@ -376,9 +484,7 @@ get_node_revision_body(node_revision_t *
                                           revision_file->stream,
                                           result_pool,
                                           scratch_pool));
-
-          /* Workaround issue #4031: is-fresh-txn-root in revision files. */
-          (*noderev_p)->is_fresh_txn_root = FALSE;
+          SVN_ERR(fixup_node_revision(fs, *noderev_p, scratch_pool));
 
           /* The noderev is not in cache, yet. Add it, if caching has been enabled. */
           if (ffd->node_revision_cache)
@@ -765,9 +871,7 @@ create_rep_state_body(rep_state_t **rep_
      Since we don't know the depth of the delta chain, let's assume, the
      whole contents get rewritten 3 times.
    */
-  estimated_window_storage
-    = 4 * (  (rep->expanded_size ? rep->expanded_size : rep->size)
-           + SVN_DELTA_WINDOW_SIZE);
+  estimated_window_storage = 4 * (rep->expanded_size + SVN_DELTA_WINDOW_SIZE);
   estimated_window_storage = MIN(estimated_window_storage, APR_SIZE_MAX);
 
   rs->window_cache =    ffd->txdelta_window_cache
@@ -1322,15 +1426,11 @@ set_cached_combined_window(svn_stringbuf
    ID, and representation REP.
    Also, set *WINDOW_P to the base window content for *LIST, if it
    could be found in cache. Otherwise, *LIST will contain the base
-   representation for the whole delta chain.
-   Finally, return the expanded size of the representation in
-   *EXPANDED_SIZE. It will take care of cases where only the on-disk
-   size is known.  */
+   representation for the whole delta chain. */
 static svn_error_t *
 build_rep_list(apr_array_header_t **list,
                svn_stringbuf_t **window_p,
                rep_state_t **src_state,
-               svn_filesize_t *expanded_size,
                svn_fs_t *fs,
                representation_t *first_rep,
                apr_pool_t *pool)
@@ -1345,24 +1445,9 @@ build_rep_list(apr_array_header_t **list
   *list = apr_array_make(pool, 1, sizeof(rep_state_t *));
   rep = *first_rep;
 
-  /* The value as stored in the data struct.
-     0 is either for unknown length or actually zero length. */
-  *expanded_size = first_rep->expanded_size;
-
   /* for the top-level rep, we need the rep_args */
   SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file, &rep, fs, pool,
                            iterpool));
-
-  /* Unknown size or empty representation?
-     That implies the this being the first iteration.
-     Usually size equals on-disk size, except for empty,
-     compressed representations (delta, size = 4).
-     Please note that for all non-empty deltas have
-     a 4-byte header _plus_ some data. */
-  if (*expanded_size == 0)
-    if (rep_header->type == svn_fs_fs__rep_plain || first_rep->size != 4)
-      *expanded_size = first_rep->size;
-
   while (1)
     {
       svn_pool_clear(iterpool);
@@ -1624,9 +1709,11 @@ get_combined_window(svn_stringbuf_t **re
       /* Maybe, we've got a PLAIN start representation.  If we do, read
          as much data from it as the needed for the txdelta window's source
          view.
-         Note that BUF / SOURCE may only be NULL in the first iteration. */
+         Note that BUF / SOURCE may only be NULL in the first iteration.
+         Also note that we may have short-cut reading the delta chain --
+         in which case SRC_OPS is 0 and it might not be a PLAIN rep. */
       source = buf;
-      if (source == NULL && rb->src_state != NULL)
+      if (source == NULL && rb->src_state != NULL && window->src_ops)
         SVN_ERR(read_plain_window(&source, rb->src_state, window->sview_len,
                                   pool, iterpool));
 
@@ -1664,7 +1751,7 @@ get_combined_window(svn_stringbuf_t **re
 }
 
 /* Returns whether or not the expanded fulltext of the file is cachable
- * based on its size SIZE.  The decision depends on the cache used by RB.
+ * based on its size SIZE.  The decision depends on the cache used by FFD.
  */
 static svn_boolean_t
 fulltext_size_is_cachable(fs_fs_data_t *ffd, svn_filesize_t size)
@@ -1997,8 +2084,9 @@ rep_read_contents(void *baton,
   if (!rb->rs_list)
     {
       /* Window stream not initialized, yet.  Do it now. */
+      rb->len = rb->rep.expanded_size;
       SVN_ERR(build_rep_list(&rb->rs_list, &rb->base_window,
-                             &rb->src_state, &rb->len, rb->fs, &rb->rep,
+                             &rb->src_state, rb->fs, &rb->rep,
                              rb->filehandle_pool));
 
       /* In case we did read from the fulltext cache before, make the
@@ -2065,7 +2153,6 @@ svn_fs_fs__get_contents(svn_stream_t **c
   else
     {
       fs_fs_data_t *ffd = fs->fsap_data;
-      svn_filesize_t len = rep->expanded_size ? rep->expanded_size : rep->size;
       struct rep_read_baton *rb;
 
       pair_cache_key_t fulltext_cache_key = { 0 };
@@ -2081,7 +2168,7 @@ svn_fs_fs__get_contents(svn_stream_t **c
        * cache it. */
       if (ffd->fulltext_cache && cache_fulltext
           && SVN_IS_VALID_REVNUM(rep->revision)
-          && fulltext_size_is_cachable(ffd, len))
+          && fulltext_size_is_cachable(ffd, rep->expanded_size))
         {
           rb->fulltext_cache = ffd->fulltext_cache;
         }
@@ -2469,9 +2556,7 @@ get_dir_contents(apr_array_header_t **en
       /* Undeltify content before parsing it. Otherwise, we could only
        * parse it byte-by-byte.
        */
-      apr_size_t len = noderev->data_rep->expanded_size
-                     ? (apr_size_t)noderev->data_rep->expanded_size
-                     : (apr_size_t)noderev->data_rep->size;
+      apr_size_t len = noderev->data_rep->expanded_size;
       svn_stringbuf_t *text;
 
       /* The representation is immutable.  Read it normally. */
@@ -2639,16 +2724,27 @@ svn_fs_fs__get_proplist(apr_hash_t **pro
 
   if (noderev->prop_rep && svn_fs_fs__id_txn_used(&noderev->prop_rep->txn_id))
     {
+      svn_error_t *err;
       const char *filename
         = svn_fs_fs__path_txn_node_props(fs, noderev->id, pool);
       proplist = apr_hash_make(pool);
 
       SVN_ERR(svn_stream_open_readonly(&stream, filename, pool, pool));
-      SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, pool));
+      err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, pool);
+      if (err)
+        {
+          svn_string_t *id_str = svn_fs_fs__id_unparse(noderev->id, pool);
+
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          return svn_error_quick_wrapf(err,
+                   _("malformed property list for node-revision '%s' in '%s'"),
+                   id_str->data, filename);
+        }
       SVN_ERR(svn_stream_close(stream));
     }
   else if (noderev->prop_rep)
     {
+      svn_error_t *err;
       fs_fs_data_t *ffd = fs->fsap_data;
       representation_t *rep = noderev->prop_rep;
       pair_cache_key_t key = { 0 };
@@ -2667,7 +2763,16 @@ svn_fs_fs__get_proplist(apr_hash_t **pro
       proplist = apr_hash_make(pool);
       SVN_ERR(svn_fs_fs__get_contents(&stream, fs, noderev->prop_rep, FALSE,
                                       pool));
-      SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, pool));
+      err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, pool);
+      if (err)
+        {
+          svn_string_t *id_str = svn_fs_fs__id_unparse(noderev->id, pool);
+
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          return svn_error_quick_wrapf(err,
+                   _("malformed property list for node-revision '%s'"),
+                   id_str->data);
+        }
       SVN_ERR(svn_stream_close(stream));
 
       if (ffd->properties_cache && SVN_IS_VALID_REVNUM(rep->revision))
@@ -3200,9 +3305,7 @@ block_read_noderev(node_revision_t **nod
   /* read node rev from revision file */
   SVN_ERR(svn_fs_fs__read_noderev(noderev_p, stream,
                                   result_pool, scratch_pool));
-
-  /* Workaround issue #4031: is-fresh-txn-root in revision files. */
-  (*noderev_p)->is_fresh_txn_root = FALSE;
+  SVN_ERR(fixup_node_revision(fs, *noderev_p, scratch_pool));
 
   if (ffd->node_revision_cache)
     SVN_ERR(svn_cache__set(ffd->node_revision_cache, &key, *noderev_p,

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.h Wed May 13 04:51:26 2015
@@ -30,6 +30,18 @@
 
 
 
+/* Resolve a FSFS quirk: if REP in FS is a "PLAIN" representation, its
+ * EXPANDED_SIZE element may be 0, in which case its value has to be taken
+ * from SIZE.
+ *
+ * This function ensures that EXPANDED_SIZE in REP always contains the
+ * actual value. No-op if REP is NULL.  Uses SCRATCH_POOL for temporaries.
+ */
+svn_error_t *
+svn_fs_fs__fixup_expanded_size(svn_fs_t *fs,
+                               representation_t *rep,
+                               apr_pool_t *scratch_pool);
+
 /* Set *NODEREV_P to the node-revision for the node ID in FS.  Do any
    allocations in POOL. */
 svn_error_t *