subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1344934 [1/4] - in /subversion/branches/ev2-export: ./ build/ build/generator/ subversion/bindings/javahl/native/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ subversion/libsvn_fs_fs/ s...
Date Thu, 31 May 2012 22:29:26 GMT
Author: hwright
Date: Thu May 31 22:29:24 2012
New Revision: 1344934

URL: http://svn.apache.org/viewvc?rev=1344934&view=rev
Log:
On the ev2-export branch:
Bring up-to-date with trunk.

Added:
    subversion/branches/ev2-export/subversion/tests/cmdline/svnsync_authz_tests.py
      - copied unchanged from r1344922, subversion/trunk/subversion/tests/cmdline/svnsync_authz_tests.py
    subversion/branches/ev2-export/subversion/tests/libsvn_wc/wc-queries-test.c
      - copied unchanged from r1344922, subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c
    subversion/branches/ev2-export/tools/dev/mergegraph/save_as_sh.py
      - copied unchanged from r1344922, subversion/trunk/tools/dev/mergegraph/save_as_sh.py
Modified:
    subversion/branches/ev2-export/   (props changed)
    subversion/branches/ev2-export/build.conf
    subversion/branches/ev2-export/build/generator/gen_vcnet_vcproj.py
    subversion/branches/ev2-export/build/transform_sql.py
    subversion/branches/ev2-export/subversion/bindings/javahl/native/InputStream.cpp
    subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.cpp
    subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.h
    subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.h
    subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.cpp
    subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.h
    subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
    subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
    subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h
    subversion/branches/ev2-export/subversion/include/svn_path.h
    subversion/branches/ev2-export/subversion/include/svn_sorts.h
    subversion/branches/ev2-export/subversion/libsvn_client/client.h
    subversion/branches/ev2-export/subversion/libsvn_client/commit.c
    subversion/branches/ev2-export/subversion/libsvn_client/diff.c
    subversion/branches/ev2-export/subversion/libsvn_client/merge.c
    subversion/branches/ev2-export/subversion/libsvn_client/prop_commands.c
    subversion/branches/ev2-export/subversion/libsvn_client/ra.c
    subversion/branches/ev2-export/subversion/libsvn_client/switch.c
    subversion/branches/ev2-export/subversion/libsvn_delta/compat.c
    subversion/branches/ev2-export/subversion/libsvn_fs_fs/dag.c
    subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/ev2-export/subversion/libsvn_repos/dump.c
    subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c
    subversion/branches/ev2-export/subversion/libsvn_subr/hash.c
    subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
    subversion/branches/ev2-export/subversion/libsvn_wc/externals.c
    subversion/branches/ev2-export/subversion/libsvn_wc/merge.c
    subversion/branches/ev2-export/subversion/libsvn_wc/node.c
    subversion/branches/ev2-export/subversion/libsvn_wc/props.c
    subversion/branches/ev2-export/subversion/libsvn_wc/status.c
    subversion/branches/ev2-export/subversion/libsvn_wc/upgrade.c
    subversion/branches/ev2-export/subversion/libsvn_wc/wc-metadata.sql
    subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c
    subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h
    subversion/branches/ev2-export/subversion/svn/cl.h
    subversion/branches/ev2-export/subversion/svn/diff-cmd.c
    subversion/branches/ev2-export/subversion/svn/import-cmd.c
    subversion/branches/ev2-export/subversion/svn/log-cmd.c
    subversion/branches/ev2-export/subversion/svn/main.c
    subversion/branches/ev2-export/subversion/svn/propget-cmd.c
    subversion/branches/ev2-export/subversion/svn/props.c
    subversion/branches/ev2-export/subversion/svnserve/serve.c
    subversion/branches/ev2-export/subversion/tests/cmdline/autoprop_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/changelist_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/diff_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/entries-dump.c
    subversion/branches/ev2-export/subversion/tests/cmdline/getopt_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/merge_reintegrate_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/revert_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/svnsync_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/svnsync_tests_data/svnsync-trunk-A-changes.dump
    subversion/branches/ev2-export/subversion/tests/cmdline/svnsync_tests_data/svnsync-trunk-A-changes.expected.dump
    subversion/branches/ev2-export/subversion/tests/cmdline/svnsync_tests_data/svnsync-trunk-only.dump
    subversion/branches/ev2-export/subversion/tests/cmdline/svnsync_tests_data/svnsync-trunk-only.expected.dump
    subversion/branches/ev2-export/subversion/tests/cmdline/svntest/actions.py
    subversion/branches/ev2-export/subversion/tests/cmdline/svntest/main.py
    subversion/branches/ev2-export/subversion/tests/libsvn_client/client-test.c
    subversion/branches/ev2-export/subversion/tests/libsvn_delta/random-test.c
    subversion/branches/ev2-export/subversion/tests/libsvn_wc/   (props changed)
    subversion/branches/ev2-export/tools/buildbot/slaves/bb-openbsd/svnbuild.sh
    subversion/branches/ev2-export/tools/buildbot/slaves/centos/svnbuild.sh
    subversion/branches/ev2-export/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd
    subversion/branches/ev2-export/tools/dev/mergegraph/mergegraph.py
    subversion/branches/ev2-export/tools/dev/unix-build/Makefile.svn
    subversion/branches/ev2-export/tools/server-side/svnauthz-validate.c
    subversion/branches/ev2-export/win-tests.py

Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
  Merged /subversion/branches/javahl-ra:r1342682
  Merged /subversion/trunk:r1341010-1344922

Modified: subversion/branches/ev2-export/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/build.conf?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/build.conf (original)
+++ subversion/branches/ev2-export/build.conf Thu May 31 22:29:24 2012
@@ -1008,6 +1008,14 @@ sources = op-depth-test.c utils.c
 install = test
 libs = libsvn_client libsvn_test libsvn_wc libsvn_subr apriconv apr
 
+[wc-queries-test]
+description = Test Sqlite query evaluation
+type = exe
+path = subversion/tests/libsvn_wc
+sources = wc-queries-test.c
+install = test
+libs = libsvn_test libsvn_subr apriconv apr sqlite
+
 # ----------------------------------------------------------------------------
 # These are not unit tests at all, they are small programs that exercise
 # parts of the libsvn_delta API from the command line.  They are stuck here
@@ -1177,7 +1185,7 @@ libs = __ALL__
        diff diff3 diff4
        client-test
        tree-conflict-data-test db-test pristine-store-test entries-compat-test
-       op-depth-test dirent_uri-test
+       op-depth-test dirent_uri-test wc-queries-test
        auth-test
        parse-diff-test
        svn-rep-sharing-stats svn-populate-node-origins-index

Modified: subversion/branches/ev2-export/build/generator/gen_vcnet_vcproj.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/build/generator/gen_vcnet_vcproj.py?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/build/generator/gen_vcnet_vcproj.py (original)
+++ subversion/branches/ev2-export/build/generator/gen_vcnet_vcproj.py Thu May 31 22:29:24 2012
@@ -124,10 +124,6 @@ class Generator(gen_win.WinGeneratorBase
       self.write_with_template(fname, 'templates/vcnet_vcxproj.ezt', data)
       self.write_with_template(fname + '.filters', 'templates/vcnet_vcxproj_filters.ezt', data)
 
-  def find_rootpath(self):
-    "Gets the root path as understand by the project system"
-    return "$(SolutionDir)"
-
   def write(self):
     "Write a Solution (.sln)"
 
@@ -203,7 +199,8 @@ class Generator(gen_win.WinGeneratorBase
         if depends[i].fname.startswith(self.projfilesdir):
           path = depends[i].fname[len(self.projfilesdir) + 1:]
         else:
-          path = '$(SolutionDir)' + depends[i].fname
+          path = os.path.join(os.path.relpath('.', self.projfilesdir),
+                              depends[i].fname)
         deplist.append(gen_win.ProjectItem(guid=guids[depends[i].name],
                                            index=i,
                                            path=path,

Modified: subversion/branches/ev2-export/build/transform_sql.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/build/transform_sql.py?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/build/transform_sql.py (original)
+++ subversion/branches/ev2-export/build/transform_sql.py Thu May 31 22:29:24 2012
@@ -49,7 +49,7 @@ class Processor(object):
 
   # a few SQL comments that act as directives for this transform system
   re_format = re.compile('-- *format: *([0-9]+)')
-  re_statement = re.compile('-- *STMT_([A-Z_0-9]+)')
+  re_statement = re.compile('-- *STMT_([A-Z_0-9]+)( +\(([^\)]*)\))?')
   re_include = re.compile('-- *include: *([-a-z]+)')
   re_define = re.compile('-- *define: *([A-Z_0-9]+)')
 
@@ -66,6 +66,13 @@ class Processor(object):
     self.close_define()
     self.output.write('#define STMT_%s %d\n' % (match.group(1),
                                                 self.stmt_count))
+
+    if match.group(3) == None:
+      info = 'NULL'
+    else:
+      info = '"' + match.group(3) + '"'
+    self.output.write('#define STMT_%d_INFO {"STMT_%s", %s}\n' %
+                      (self.stmt_count, match.group(1), info))
     self.output.write('#define STMT_%d \\\n' % (self.stmt_count,))
     self.var_printed = True
 
@@ -103,10 +110,35 @@ class Processor(object):
     for line in input.split('\n'):
       line = line.replace('"', '\\"')
 
+      # IS_STRICT_DESCENDANT_OF()
+
+      # A common operation in the working copy is determining descendants of
+      # a node. To allow Sqlite to use its indexes to provide the answer we
+      # must provide simple less than and greater than operations.
+      #
+      # For relative paths that consist of one or more components like 'subdir'
+      # we can accomplish this by comparing local_relpath with 'subdir/' and
+      # 'subdir0' ('/'+1 = '0')
+      #
+      # For the working copy root this case is less simple and not strictly
+      # valid utf-8/16 (but luckily Sqlite doesn't validate utf-8 nor utf-16).
+      # The binary blob x'FFFF' is higher than any valid utf-8 and utf-16
+      # sequence.
+      #
+      # So for the root we can compare with > '' and < x'FFFF'. (This skips the
+      # root itself and selects all descendants)
+      #
+      ### RH: I implemented this first with a user defined Sqlite function. But
+      ### when I wrote the documentation for it, I found out I could just
+      ### define it this way, without losing the option of just dropping the
+      ### query in a plain sqlite3.
+
       # '/'+1 == '0'
-      line = re.sub(r'IS_STRICT_DESCENDANT_OF[(]([A-Za-z_.]+), ([?][0-9]+)[)]',
-                    r"((\2) != '' AND ((\1) > (\2) || '/') AND ((\1) < (\2) || '0')) ",
-                    line)
+      line = re.sub(
+            r'IS_STRICT_DESCENDANT_OF[(]([A-Za-z_.]+), ([?][0-9]+)[)]',
+            r"(((\1) > (CASE (\2) WHEN '' THEN '' ELSE (\2) || '/' END))" +
+            r" AND ((\1) < CASE (\2) WHEN '' THEN X'FFFF' ELSE (\2) || '0' END))",
+            line)
 
       if line.strip():
         handled = False
@@ -167,6 +199,13 @@ def main(input_filepath, output):
       + ', \\\n'.join('    STMT_%d' % (i,) for i in range(proc.stmt_count))
       + ', \\\n    NULL \\\n  }\n')
 
+    output.write('\n')
+
+    output.write(
+      '#define %s_DECLARE_STATEMENT_INFO(varname) \\\n' % (var_name,)
+      + '  static const char * const varname[][2] = { \\\n'
+      + ', \\\n'.join('    STMT_%d_INFO' % (i) for i in range(proc.stmt_count))
+      + ', \\\n    {NULL, NULL} \\\n  }\n')
 
 if __name__ == '__main__':
   if len(sys.argv) < 2 or len(sys.argv) > 3:

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/InputStream.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/InputStream.cpp?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/InputStream.cpp (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/InputStream.cpp Thu May 31 22:29:24 2012
@@ -99,6 +99,14 @@ svn_error_t *InputStream::read(void *bat
   if (JNIUtil::isJavaExceptionThrown())
     return SVN_NO_ERROR;
 
+  /*
+   * Convert -1 from InputStream.read that means EOF, 0 which is subversion equivalent
+   */
+  if(jread == -1)
+    {
+      jread = 0;
+    }
+
   // Put the Java byte array into a helper object to retrieve the
   // data bytes.
   JNIByteArray outdata(data, true);
@@ -107,7 +115,7 @@ svn_error_t *InputStream::read(void *bat
 
   // Catch when the Java method tells us it read too much data.
   if (jread > (jint) *len)
-    jread = -1;
+    jread = 0;
 
   // In the case of success copy the data back to the Subversion
   // buffer.

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.cpp?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.cpp (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.cpp Thu May 31 22:29:24 2012
@@ -30,7 +30,6 @@
 SVNBase::SVNBase()
     : pool(JNIUtil::getPool())
 {
-  jthis = NULL;
 }
 
 SVNBase::~SVNBase()
@@ -58,17 +57,6 @@ jlong SVNBase::findCppAddrForJObject(job
       if (JNIUtil::isJavaExceptionThrown())
         return 0;
 
-      if (cppAddr)
-        {
-          /* jthis is not guaranteed to be the same between JNI invocations, so
-             we do a little dance here and store the updated version in our
-             object for this invocation.
-
-             findCppAddrForJObject() is, by necessity, called before any other
-             methods on the C++ object, so by doing this we can guarantee a
-             valid jthis pointer for subsequent uses. */
-          (reinterpret_cast<SVNBase *> (cppAddr))->jthis = jthis;
-        }
       return cppAddr;
     }
 }
@@ -82,17 +70,15 @@ void SVNBase::finalize()
   JNIUtil::enqueueForDeletion(this);
 }
 
-void SVNBase::dispose(jfieldID *fid, const char *className)
+void SVNBase::dispose(jobject jthis, jfieldID *fid, const char *className)
 {
-  jobject my_jthis = this->jthis;
-
   delete this;
   JNIEnv *env = JNIUtil::getEnv();
   SVNBase::findCppAddrFieldID(fid, className, env);
   if (*fid == 0)
     return;
 
-  env->SetLongField(my_jthis, *fid, 0);
+  env->SetLongField(jthis, *fid, 0);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 }

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.h (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNBase.h Thu May 31 22:29:24 2012
@@ -49,7 +49,7 @@ class SVNBase
    *
    * @since 1.4.0
    */
-  virtual void dispose() = 0;
+  virtual void dispose(jobject jthis) = 0;
 
   /**
    * This method should never be called, as @c dispose() should be
@@ -80,13 +80,7 @@ class SVNBase
    *
    * @since 1.4.0
    */
-  void dispose(jfieldID *fid, const char *className);
-
-  /**
-   * A pointer to the parent java object.  This is not valid across JNI
-   * method invocations, and so should be set in each one.
-   */
-  jobject jthis;
+  void dispose(jobject jthis, jfieldID *fid, const char *className);
 
  private:
   /**

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.cpp?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.cpp Thu May 31 22:29:24 2012
@@ -86,10 +86,10 @@ SVNClient *SVNClient::getCppObject(jobje
     return (cppAddr == 0 ? NULL : reinterpret_cast<SVNClient *>(cppAddr));
 }
 
-void SVNClient::dispose()
+void SVNClient::dispose(jobject jthis)
 {
     static jfieldID fid = 0;
-    SVNBase::dispose(&fid, JAVA_PACKAGE"/SVNClient");
+    SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/SVNClient");
 }
 
 jstring SVNClient::getAdminDirectoryName()

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNClient.h Thu May 31 22:29:24 2012
@@ -196,7 +196,7 @@ class SVNClient :public SVNBase
   ClientContext &getClientContext();
 
   const char *getLastPath();
-  void dispose();
+  void dispose(jobject jthis);
   static SVNClient *getCppObject(jobject jthis);
   SVNClient(jobject jthis_in);
   virtual ~SVNClient();

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.cpp?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.cpp (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.cpp Thu May 31 22:29:24 2012
@@ -54,10 +54,10 @@ SVNRepos *SVNRepos::getCppObject(jobject
   return (cppAddr == 0 ? NULL : reinterpret_cast<SVNRepos *>(cppAddr));
 }
 
-void SVNRepos::dispose()
+void SVNRepos::dispose(jobject jthis)
 {
   static jfieldID fid = 0;
-  SVNBase::dispose(&fid, JAVA_PACKAGE"/SVNRepos");
+  SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/SVNRepos");
 }
 
 void SVNRepos::cancelOperation()

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.h (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/SVNRepos.h Thu May 31 22:29:24 2012
@@ -69,7 +69,7 @@ class SVNRepos : public SVNBase
   void pack(File &path, ReposNotifyCallback *callback);
   SVNRepos();
   virtual ~SVNRepos();
-  void dispose();
+  void dispose(jobject jthis);
   static SVNRepos *getCppObject(jobject jthis);
 
   static svn_error_t *checkCancel(void *cancelBaton);

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Thu May 31 22:29:24 2012
@@ -75,7 +75,7 @@ Java_org_apache_subversion_javahl_SVNCli
       JNIUtil::throwError(_("bad C++ this"));
       return;
     }
-  cl->dispose();
+  cl->dispose(jthis);
 }
 
 JNIEXPORT void JNICALL

Modified: subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp Thu May 31 22:29:24 2012
@@ -60,7 +60,7 @@ Java_org_apache_subversion_javahl_SVNRep
       JNIUtil::throwError(_("bad C++ this"));
       return;
     }
-  cl->dispose();
+  cl->dispose(jthis);
 }
 
 JNIEXPORT void JNICALL

Modified: subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h Thu May 31 22:29:24 2012
@@ -888,10 +888,6 @@ typedef svn_error_t *(*svn_wc__proplist_
  * If @a propname is not NULL, the passed hash table will only contain
  * the property @a propname.
  *
- * If @a base_props is @c TRUE, get the unmodified BASE properties
- * from the working copy, instead of getting the current (or "WORKING")
- * properties.
- *
  * If @a pristine is not @c TRUE, and @a base_props is FALSE show local
  * modifications to the properties.
  *
@@ -912,7 +908,6 @@ svn_wc__prop_list_recursive(svn_wc_conte
                             const char *local_abspath,
                             const char *propname,
                             svn_depth_t depth,
-                            svn_boolean_t base_props,
                             svn_boolean_t pristine,
                             const apr_array_header_t *changelists,
                             svn_wc__proplist_receiver_t receiver_func,
@@ -921,6 +916,20 @@ svn_wc__prop_list_recursive(svn_wc_conte
                             void *cancel_baton,
                             apr_pool_t *scratch_pool);
 
+/** Obtain a mapping of const char * local_abspaths to const svn_string_t*
+ * property values in *VALUES, of all PROPNAME properties on LOCAL_ABSPATH
+ * and its descendants.
+ *
+ * Allocate the result in RESULT_POOL, and perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__prop_retrieve_recursive(apr_hash_t **values,
+                                svn_wc_context_t *wc_ctx,
+                                const char *local_abspath,
+                                const char *propname,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
 
 /**
  * For use by entries.c and entries-dump.c to read old-format working copies.
@@ -993,20 +1002,20 @@ svn_wc__has_switched_subtrees(svn_boolea
                               const char *trail_url,
                               apr_pool_t *scratch_pool);
 
-/* Set @a *server_excluded_subtrees to a hash mapping <tt>const char *</tt>
+/* Set @a *excluded_subtrees to a hash mapping <tt>const char *</tt>
  * local * absolute paths to <tt>const char *</tt> local absolute paths for
- * every path at or under @a local_abspath in @a wc_ctx which are excluded
- * by the server (e.g. because of authz).
- * If no server-excluded paths are found then @a *server_excluded_subtrees
+ * every path under @a local_abspath in @a wc_ctx which are excluded
+ * by the server (e.g. because of authz) or the users.
+ * If no excluded paths are found then @a *server_excluded_subtrees
  * is set to @c NULL.
  * Allocate the hash and all items therein from @a result_pool.
  */
 svn_error_t *
-svn_wc__get_server_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
-                                     svn_wc_context_t *wc_ctx,
-                                     const char *local_abspath,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool);
+svn_wc__get_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
+                              svn_wc_context_t *wc_ctx,
+                              const char *local_abspath,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
 
 /* Indicate in @a *is_modified whether the working copy has local
  * modifications, using context @a wc_ctx.

Modified: subversion/branches/ev2-export/subversion/include/svn_path.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_path.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_path.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_path.h Thu May 31 22:29:24 2012
@@ -296,6 +296,10 @@ svn_path_is_canonical(const char *path, 
 
 /** Return an integer greater than, equal to, or less than 0, according
  * as @a path1 is greater than, equal to, or less than @a path2.
+ *
+ * This function works like strcmp() except that it orders children in
+ * subdirectories directly after their parents. This allows using the
+ * given ordering for a depth first walk.
  */
 int
 svn_path_compare_paths(const char *path1, const char *path2);

Modified: subversion/branches/ev2-export/subversion/include/svn_sorts.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_sorts.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_sorts.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_sorts.h Thu May 31 22:29:24 2012
@@ -80,6 +80,13 @@ typedef struct svn_sort__item_t {
      apr_array_header_t *array;
      array = svn_sort__hash(hsh, svn_sort_compare_items_as_paths, pool);
    @endcode
+ *
+ * This function works like svn_sort_compare_items_lexically() except that it
+ * orders children in subdirectories directly after their parents. This allows
+ * using the given ordering for a depth first walk, but at a performance
+ * penalty. Code that doesn't need this special behavior for children, e.g. when
+ * sorting files at a single directory level should use
+ * svn_sort_compare_items_lexically() instead.
  */
 int
 svn_sort_compare_items_as_paths(const svn_sort__item_t *a,

Modified: subversion/branches/ev2-export/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/client.h?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/client.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/client.h Thu May 31 22:29:24 2012
@@ -198,6 +198,9 @@ svn_client__repos_location_segments(apr_
    LOC1 and LOC2.  If the locations have no common ancestor (including if
    they don't have the same repository root URL), set *ANCESTOR_P to NULL.
 
+   If SESSION is not NULL, use it for retrieving the common ancestor instead
+   of creating a new session.
+
    Use the authentication baton cached in CTX to authenticate against
    the repository.  Use POOL for all allocations.
 
@@ -207,6 +210,7 @@ svn_error_t *
 svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
                                          const svn_client__pathrev_t *loc1,
                                          const svn_client__pathrev_t *loc2,
+                                         svn_ra_session_t *session,
                                          svn_client_ctx_t *ctx,
                                          apr_pool_t *result_pool,
                                          apr_pool_t *scratch_pool);

Modified: subversion/branches/ev2-export/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/commit.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/commit.c Thu May 31 22:29:24 2012
@@ -276,15 +276,20 @@ import_children(const char *dir_abspath,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *scratch_pool)
 {
-  apr_hash_index_t *hi;
+  apr_array_header_t *sorted_dirents;
+  int i;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-  for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
+  sorted_dirents = svn_sort__hash(dirents, svn_sort_compare_items_lexically,
+                                  scratch_pool);
+  for (i = 0; i < sorted_dirents->nelts; i++)
     {
       const char *local_abspath;
       const char *relpath;
-      const char *base_name = svn__apr_hash_index_key(hi);
-      const svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
+      svn_sort__item_t item = APR_ARRAY_IDX(sorted_dirents, i,
+                                            svn_sort__item_t);
+      const char *base_name = item.key;
+      const svn_io_dirent2_t *dirent = item.value;
 
       svn_pool_clear(iterpool);
 

Modified: subversion/branches/ev2-export/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/diff.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/diff.c Thu May 31 22:29:24 2012
@@ -800,6 +800,9 @@ struct diff_cmd_baton {
   /* The anchor to prefix before wc paths */
   const char *anchor;
 
+  /* Whether the local diff target of a repos->wc diff is a copy. */
+  svn_boolean_t repos_wc_diff_target_is_copy;
+
   /* A hashtable using the visited paths as keys.
    * ### This is needed for us to know if we need to print a diff header for
    * ### a path that has property changes. */
@@ -1132,6 +1135,19 @@ diff_file_changed(svn_wc_notify_state_t 
 {
   struct diff_cmd_baton *diff_cmd_baton = diff_baton;
 
+  /* During repos->wc diff of a copy revision numbers obtained
+   * from the working copy are always SVN_INVALID_REVNUM. */
+  if (diff_cmd_baton->repos_wc_diff_target_is_copy)
+    {
+      if (rev1 == SVN_INVALID_REVNUM &&
+          diff_cmd_baton->revnum1 != SVN_INVALID_REVNUM)
+        rev1 = diff_cmd_baton->revnum1;
+
+      if (rev2 == SVN_INVALID_REVNUM &&
+          diff_cmd_baton->revnum2 != SVN_INVALID_REVNUM)
+        rev2 = diff_cmd_baton->revnum2;
+    }
+
   if (diff_cmd_baton->anchor)
     path = svn_dirent_join(diff_cmd_baton->anchor, path, scratch_pool);
   if (tmpfile1)
@@ -1178,6 +1194,19 @@ diff_file_added(svn_wc_notify_state_t *c
 {
   struct diff_cmd_baton *diff_cmd_baton = diff_baton;
 
+  /* During repos->wc diff of a copy revision numbers obtained
+   * from the working copy are always SVN_INVALID_REVNUM. */
+  if (diff_cmd_baton->repos_wc_diff_target_is_copy)
+    {
+      if (rev1 == SVN_INVALID_REVNUM &&
+          diff_cmd_baton->revnum1 != SVN_INVALID_REVNUM)
+        rev1 = diff_cmd_baton->revnum1;
+
+      if (rev2 == SVN_INVALID_REVNUM &&
+          diff_cmd_baton->revnum2 != SVN_INVALID_REVNUM)
+        rev2 = diff_cmd_baton->revnum2;
+    }
+
   if (diff_cmd_baton->anchor)
     path = svn_dirent_join(diff_cmd_baton->anchor, path, scratch_pool);
 
@@ -2695,6 +2724,163 @@ diff_repos_repos(const svn_wc_diff_callb
 }
 
 
+/* Using CALLBACKS, show a REPOS->WC diff for a file TARGET, which in the
+ * working copy is at FILE2_ABSPATH. KIND1 is the node kind of the repository
+ * target (either svn_node_file or svn_node_none). REV is the revision the
+ * working file is diffed against. RA_SESSION points at the URL of the file
+ * in the repository and is used to get the file's repository-version content,
+ * if necessary. The other parameters are as in diff_repos_wc(). */
+static svn_error_t *
+diff_repos_wc_file_target(const char *target,
+                          const char *file2_abspath,
+                          svn_node_kind_t kind1,
+                          svn_revnum_t rev,
+                          svn_boolean_t reverse,
+                          svn_boolean_t show_copies_as_adds,
+                          const svn_wc_diff_callbacks4_t *callbacks,
+                          void *callback_baton,
+                          svn_ra_session_t *ra_session,
+                          svn_client_ctx_t *ctx,
+                          apr_pool_t *scratch_pool)
+{
+  const char *file1_abspath;
+  svn_stream_t *file1_content;
+  svn_stream_t *file2_content;
+  apr_hash_t *file1_props = NULL;
+  apr_hash_t *file2_props;
+  svn_boolean_t is_copy = FALSE;
+  apr_hash_t *keywords = NULL;
+  svn_string_t *keywords_prop;
+  svn_subst_eol_style_t eol_style;
+  const char *eol_str;
+
+  /* Get content and props of file 1 (the remote file). */
+  SVN_ERR(svn_stream_open_unique(&file1_content, &file1_abspath, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
+  if (kind1 == svn_node_file)
+    {
+      if (show_copies_as_adds)
+        SVN_ERR(svn_wc__node_get_origin(&is_copy, 
+                                        NULL, NULL, NULL, NULL, NULL,
+                                        ctx->wc_ctx, file2_abspath,
+                                        FALSE, scratch_pool, scratch_pool));
+      /* If showing copies as adds, diff against the empty file. */
+      if (!(show_copies_as_adds && is_copy))
+        SVN_ERR(svn_ra_get_file(ra_session, "", rev, file1_content,
+                                NULL, &file1_props, scratch_pool));
+    }
+
+  SVN_ERR(svn_stream_close(file1_content));
+
+  SVN_ERR(svn_wc_prop_list2(&file2_props, ctx->wc_ctx, file2_abspath,
+                            scratch_pool, scratch_pool));
+
+  /* We might have to create a normalised version of the working file. */
+  svn_subst_eol_style_from_value(&eol_style, &eol_str,
+                                 apr_hash_get(file2_props,
+                                              SVN_PROP_EOL_STYLE,
+                                              APR_HASH_KEY_STRING));
+  keywords_prop = apr_hash_get(file2_props, SVN_PROP_KEYWORDS,
+                               APR_HASH_KEY_STRING);
+  if (keywords_prop)
+    SVN_ERR(svn_subst_build_keywords2(&keywords, keywords_prop->data,
+                                      NULL, NULL, 0, NULL,
+                                      scratch_pool));
+  if (svn_subst_translation_required(eol_style, SVN_SUBST_NATIVE_EOL_STR,
+                                     keywords, FALSE, TRUE))
+    {
+      svn_stream_t *working_content;
+      svn_stream_t *normalized_content;
+
+      SVN_ERR(svn_stream_open_readonly(&working_content, file2_abspath,
+                                       scratch_pool, scratch_pool));
+
+      /* Create a temporary file and copy normalised data into it. */
+      SVN_ERR(svn_stream_open_unique(&file2_content, &file2_abspath, NULL,
+                                     svn_io_file_del_on_pool_cleanup,
+                                     scratch_pool, scratch_pool));
+      normalized_content = svn_subst_stream_translated(
+                             file2_content, SVN_SUBST_NATIVE_EOL_STR,
+                             TRUE, keywords, FALSE, scratch_pool);
+      SVN_ERR(svn_stream_copy3(working_content, normalized_content,
+                               ctx->cancel_func, ctx->cancel_baton,
+                               scratch_pool));
+    }
+
+  if (kind1 == svn_node_file && !(show_copies_as_adds && is_copy))
+    {
+      SVN_ERR(callbacks->file_opened(NULL, NULL, target,
+                                     reverse ? SVN_INVALID_REVNUM : rev,
+                                     callback_baton, scratch_pool));
+
+      if (reverse)
+        SVN_ERR(callbacks->file_changed(NULL, NULL, NULL, target,
+                                        file2_abspath, file1_abspath,
+                                        SVN_INVALID_REVNUM, rev,
+                                        apr_hash_get(file2_props,
+                                                     SVN_PROP_MIME_TYPE,
+                                                     APR_HASH_KEY_STRING),
+                                        apr_hash_get(file1_props,
+                                                     SVN_PROP_MIME_TYPE,
+                                                     APR_HASH_KEY_STRING),
+                                        make_regular_props_array(
+                                          file1_props, scratch_pool,
+                                          scratch_pool),
+                                        file2_props,
+                                        callback_baton, scratch_pool));
+      else
+        SVN_ERR(callbacks->file_changed(NULL, NULL, NULL, target,
+                                        file1_abspath, file2_abspath,
+                                        rev, SVN_INVALID_REVNUM,
+                                        apr_hash_get(file1_props,
+                                                     SVN_PROP_MIME_TYPE,
+                                                     APR_HASH_KEY_STRING),
+                                        apr_hash_get(file2_props,
+                                                     SVN_PROP_MIME_TYPE,
+                                                     APR_HASH_KEY_STRING),
+                                        make_regular_props_array(
+                                          file2_props, scratch_pool,
+                                          scratch_pool),
+                                        file1_props,
+                                        callback_baton, scratch_pool));
+    }
+  else
+    {
+      if (reverse)
+        {
+          SVN_ERR(callbacks->file_deleted(NULL, NULL,
+                                          target, file2_abspath, file1_abspath,
+                                          apr_hash_get(file2_props,
+                                                       SVN_PROP_MIME_TYPE,
+                                                       APR_HASH_KEY_STRING),
+                                          NULL,
+                                          make_regular_props_hash(
+                                            file2_props, scratch_pool,
+                                            scratch_pool),
+                                          callback_baton, scratch_pool));
+        }
+      else
+        {
+          SVN_ERR(callbacks->file_added(NULL, NULL, NULL, target,
+                                        file1_abspath, file2_abspath,
+                                        rev, SVN_INVALID_REVNUM,
+                                        NULL,
+                                        apr_hash_get(file2_props,
+                                                     SVN_PROP_MIME_TYPE,
+                                                     APR_HASH_KEY_STRING),
+                                        NULL, SVN_INVALID_REVNUM,
+                                        make_regular_props_array(
+                                          file2_props, scratch_pool,
+                                          scratch_pool),
+                                        NULL,
+                                        callback_baton, scratch_pool));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Perform a diff between a repository path and a working-copy path.
 
    PATH_OR_URL1 may be either a URL or a working copy path.  PATH2 is a
@@ -2735,6 +2921,12 @@ diff_repos_wc(const char *path_or_url1,
   const char *abspath_or_url1;
   const char *abspath2;
   const char *anchor_abspath;
+  svn_node_kind_t kind1;
+  svn_node_kind_t kind2;
+  svn_boolean_t is_copy;
+  svn_revnum_t copyfrom_rev;
+  const char *copy_source_repos_relpath;
+  const char *copy_source_repos_root_url;
 
   SVN_ERR_ASSERT(! svn_path_is_url(path2));
 
@@ -2785,22 +2977,65 @@ diff_repos_wc(const char *path_or_url1,
         }
     }
 
-  /* Establish RA session to path2's anchor */
-  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, anchor_url,
-                                               NULL, NULL, FALSE, TRUE,
-                                               ctx, pool));
-  callback_baton->ra_session = ra_session;
   if (use_git_diff_format)
     {
       SVN_ERR(svn_wc__get_wc_root(&callback_baton->wc_root_abspath,
                                   ctx->wc_ctx, anchor_abspath,
                                   pool, pool));
     }
+
+  /* Open an RA session to URL1 to figure out its node kind. */
+  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, url1,
+                                               NULL, NULL, FALSE, TRUE,
+                                               ctx, pool));
+  /* Resolve the revision to use for URL1. */
+  SVN_ERR(svn_client__get_revision_number(&rev, NULL, ctx->wc_ctx,
+                                          (strcmp(path_or_url1, url1) == 0)
+                                                    ? NULL : abspath_or_url1,
+                                          ra_session, revision1, pool));
+  SVN_ERR(svn_ra_check_path(ra_session, "", rev, &kind1, pool));
+
+  /* Figure out the node kind of the local target. */
+  SVN_ERR(svn_io_check_resolved_path(abspath2, &kind2, pool));
+
+  callback_baton->ra_session = ra_session;
   callback_baton->anchor = anchor;
 
+  if (!reverse)
+    callback_baton->revnum1 = rev;
+  else
+    callback_baton->revnum2 = rev;
+
+  /* Check if our diff target is a copied node. */
+  SVN_ERR(svn_wc__node_get_origin(&is_copy, 
+                                  &copyfrom_rev,
+                                  &copy_source_repos_relpath,
+                                  &copy_source_repos_root_url,
+                                  NULL, NULL,
+                                  ctx->wc_ctx, abspath2,
+                                  FALSE, pool, pool));
+
+  /* If both diff targets can be diffed as files, fetch the appropriate
+   * file content from the repository and generate a diff against the
+   * local version of the file.
+   * However, if comparing the repository version of the file to the BASE
+   * tree version we can use the diff editor to transmit a delta instead
+   * of potentially huge file content. */
+  if ((!rev2_is_base || is_copy) &&
+      (kind1 == svn_node_file || kind1 == svn_node_none)
+       && kind2 == svn_node_file)
+    {
+      SVN_ERR(diff_repos_wc_file_target(target, abspath2, kind1, rev,
+                                        reverse, show_copies_as_adds,
+                                        callbacks, callback_baton,
+                                        ra_session, ctx, pool));
+
+      return SVN_NO_ERROR;
+    }
+
+  /* Use the diff editor to generate the diff. */
   SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
                                 SVN_RA_CAPABILITY_DEPTH, pool));
-
   SVN_ERR(svn_wc__get_diff_editor(&diff_editor, &diff_edit_baton,
                                   ctx->wc_ctx,
                                   anchor_abspath,
@@ -2816,42 +3051,78 @@ diff_repos_wc(const char *path_or_url1,
                                   callbacks, callback_baton,
                                   ctx->cancel_func, ctx->cancel_baton,
                                   pool, pool));
-
-  /* Tell the RA layer we want a delta to change our txn to URL1 */
-  SVN_ERR(svn_client__get_revision_number(&rev, NULL, ctx->wc_ctx,
-                                          (strcmp(path_or_url1, url1) == 0)
-                                                    ? NULL : abspath_or_url1,
-                                          ra_session, revision1, pool));
-
-  if (!reverse)
-    callback_baton->revnum1 = rev;
-  else
-    callback_baton->revnum2 = rev;
+  SVN_ERR(svn_ra_reparent(ra_session, anchor_url, pool));
 
   if (depth != svn_depth_infinity)
     diff_depth = depth;
   else
     diff_depth = svn_depth_unknown;
 
-  SVN_ERR(svn_ra_do_diff3(ra_session,
-                          &reporter, &reporter_baton,
-                          rev,
-                          target,
-                          diff_depth,
-                          ignore_ancestry,
-                          TRUE,  /* text_deltas */
-                          url1,
-                          diff_editor, diff_edit_baton, pool));
-
-  /* Create a txn mirror of path2;  the diff editor will print
-     diffs in reverse.  :-)  */
-  SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, abspath2,
-                                  reporter, reporter_baton,
-                                  FALSE, depth, TRUE, (! server_supports_depth),
-                                  FALSE,
-                                  ctx->cancel_func, ctx->cancel_baton,
-                                  NULL, NULL, /* notification is N/A */
-                                  pool));
+  if (is_copy)
+    {
+      const char *copyfrom_url;
+      const char *copyfrom_parent_url;
+      const char *copyfrom_basename;
+      svn_depth_t copy_depth;
+
+      callback_baton->repos_wc_diff_target_is_copy = TRUE;
+      
+      /* We're diffing a locally copied/moved directory.
+       * Describe the copy source to the reporter instead of the copy itself.
+       * Doing the latter would generate a single add_directory() call to the
+       * diff editor which results in an unexpected diff (the copy would
+       * be shown as deleted). */
+
+      copyfrom_url = apr_pstrcat(pool, copy_source_repos_root_url, "/",
+                                 copy_source_repos_relpath, (char *)NULL);
+      svn_uri_split(&copyfrom_parent_url, &copyfrom_basename,
+                    copyfrom_url, pool);
+      SVN_ERR(svn_ra_reparent(ra_session, copyfrom_parent_url, pool));
+
+      /* Tell the RA layer we want a delta to change our txn to URL1 */ 
+      SVN_ERR(svn_ra_do_diff3(ra_session,
+                              &reporter, &reporter_baton,
+                              rev,
+                              copyfrom_basename,
+                              diff_depth,
+                              ignore_ancestry,
+                              TRUE,  /* text_deltas */
+                              url1,
+                              diff_editor, diff_edit_baton, pool));
+
+      /* Report the copy source. */
+      SVN_ERR(svn_wc__node_get_depth(&copy_depth, ctx->wc_ctx, abspath2,
+                                     pool));
+      SVN_ERR(reporter->set_path(reporter_baton, "", copyfrom_rev,
+                                 copy_depth, FALSE, NULL, pool));
+      
+      /* Finish the report to generate the diff. */
+      SVN_ERR(reporter->finish_report(reporter_baton, pool));
+    }
+  else
+    {
+      /* Tell the RA layer we want a delta to change our txn to URL1 */ 
+      SVN_ERR(svn_ra_do_diff3(ra_session,
+                              &reporter, &reporter_baton,
+                              rev,
+                              target,
+                              diff_depth,
+                              ignore_ancestry,
+                              TRUE,  /* text_deltas */
+                              url1,
+                              diff_editor, diff_edit_baton, pool));
+
+      /* Create a txn mirror of path2;  the diff editor will print
+         diffs in reverse.  :-)  */
+      SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, abspath2,
+                                      reporter, reporter_baton,
+                                      FALSE, depth, TRUE,
+                                      (! server_supports_depth),
+                                      FALSE,
+                                      ctx->cancel_func, ctx->cancel_baton,
+                                      NULL, NULL, /* notification is N/A */
+                                      pool));
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/merge.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/merge.c Thu May 31 22:29:24 2012
@@ -841,8 +841,7 @@ split_mergeinfo_on_revision(svn_mergeinf
                  ranges from *MERGEINFO */
               if (!(*younger_mergeinfo))
                 *younger_mergeinfo = apr_hash_make(pool);
-              apr_hash_set(*younger_mergeinfo,
-                           (const char *)merge_source_path,
+              apr_hash_set(*younger_mergeinfo, merge_source_path,
                            APR_HASH_KEY_STRING, younger_rangelist);
               SVN_ERR(svn_mergeinfo_remove2(mergeinfo, *younger_mergeinfo,
                                             *mergeinfo, TRUE, pool, iterpool));
@@ -888,25 +887,19 @@ omit_mergeinfo_changes(apr_array_header_
    *PROPS is an array of svn_prop_t structures representing regular properties
    to be added to the working copy TARGET_ABSPATH.
 
-   HONOR_MERGEINFO determines whether mergeinfo will be honored by this
-   function (when applicable).
+   The merge source and target are assumed to be in the same repository.
 
-   If mergeinfo is not being honored, SAME_REPOS is true, and
-   REINTEGRATE_MERGE is FALSE do nothing.  Otherwise, if
-   SAME_REPOS is false, then filter out all mergeinfo
-   property additions (Issue #3383) from *PROPS.  If SAME_REPOS is
-   true then filter out mergeinfo property additions to TARGET_ABSPATH when
+   Filter out mergeinfo property additions to TARGET_ABSPATH when
    those additions refer to the same line of history as TARGET_ABSPATH as
    described below.
 
-   If mergeinfo is being honored and SAME_REPOS is true
-   then examine the added mergeinfo, looking at each range (or single rev)
+   Examine the added mergeinfo, looking at each range (or single rev)
    of each source path.  If a source_path/range refers to the same line of
    history as TARGET_ABSPATH (pegged at its base revision), then filter out
    that range.  If the entire rangelist for a given path is filtered then
    filter out the path as well.
 
-   If SAME_REPOS is true, RA_SESSION is an open RA session to the repository
+   RA_SESSION is an open RA session to the repository
    in which both the source and target live, else RA_SESSION is not used. It
    may be temporarily reparented as needed by this function.
 
@@ -917,9 +910,6 @@ omit_mergeinfo_changes(apr_array_header_
 static svn_error_t *
 filter_self_referential_mergeinfo(apr_array_header_t **props,
                                   const char *target_abspath,
-                                  svn_boolean_t honor_mergeinfo,
-                                  svn_boolean_t same_repos,
-                                  svn_boolean_t reintegrate_merge,
                                   svn_ra_session_t *ra_session,
                                   svn_client_ctx_t *ctx,
                                   apr_pool_t *pool)
@@ -931,28 +921,7 @@ filter_self_referential_mergeinfo(apr_ar
   const char *repos_relpath;
   svn_client__pathrev_t target_base;
 
-  /* Issue #3383: We don't want mergeinfo from a foreign repos.
-
-     If this is a merge from a foreign repository we must strip all
-     incoming mergeinfo (including mergeinfo deletions).  Otherwise if
-     this property isn't mergeinfo or is NULL valued (i.e. prop removal)
-     or empty mergeinfo it does not require any special handling.  There
-     is nothing to filter out of empty mergeinfo and the concept of
-     filtering doesn't apply if we are trying to remove mergeinfo
-     entirely.  */
-  if (! same_repos)
-    return svn_error_trace(omit_mergeinfo_changes(props, *props, pool));
-
-  /* If we aren't honoring mergeinfo and this is a merge from the
-     same repository, then get outta here.  If this is a reintegrate
-     merge or a merge from a foreign repository we still need to
-     filter regardless of whether we are honoring mergeinfo or not. */
-  if (! honor_mergeinfo
-      && ! reintegrate_merge)
-    return SVN_NO_ERROR;
-
-  /* If this is a merge from the same repository and PATH itself has been
-     added there is no need to filter. */
+  /* If PATH itself has been added there is no need to filter. */
   SVN_ERR(svn_wc__node_get_origin(&is_copy,  &target_base.rev, &repos_relpath,
                                   &target_base.repos_root_url,
                                   &target_base.repos_uuid, NULL,
@@ -1246,14 +1215,25 @@ prepare_merge_props_changed(const apr_ar
          'forward' or 'reverse' merge and we filter unconditionally. */
       if (merge_b->merge_source.loc1->rev < merge_b->merge_source.loc2->rev
           || !merge_b->merge_source.ancestral)
-        SVN_ERR(filter_self_referential_mergeinfo(&props,
-                                                  local_abspath,
-                                                  HONOR_MERGEINFO(merge_b),
-                                                  merge_b->same_repos,
-                                                  merge_b->reintegrate_merge,
-                                                  merge_b->ra_session2,
-                                                  merge_b->ctx,
-                                                  result_pool));
+        {
+          /* Issue #3383: We don't want mergeinfo from a foreign repos.
+
+             If this is a merge from a foreign repository we must strip all
+             incoming mergeinfo (including mergeinfo deletions).  Otherwise if
+             this property isn't mergeinfo or is NULL valued (i.e. prop removal)
+             or empty mergeinfo it does not require any special handling.  There
+             is nothing to filter out of empty mergeinfo and the concept of
+             filtering doesn't apply if we are trying to remove mergeinfo
+             entirely.  */
+          if (! merge_b->same_repos)
+            SVN_ERR(omit_mergeinfo_changes(&props, props, result_pool));
+          else if (HONOR_MERGEINFO(merge_b) || merge_b->reintegrate_merge)
+            SVN_ERR(filter_self_referential_mergeinfo(&props,
+                                                      local_abspath,
+                                                      merge_b->ra_session2,
+                                                      merge_b->ctx,
+                                                      result_pool));
+        }
     }
   *prop_updates = props;
 
@@ -5814,7 +5794,7 @@ get_mergeinfo_paths(apr_array_header_t *
   int i;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_hash_t *subtrees_with_mergeinfo;
-  apr_hash_t *server_excluded_subtrees;
+  apr_hash_t *excluded_subtrees;
   apr_hash_t *switched_subtrees;
   apr_hash_t *shallow_subtrees;
   apr_hash_t *missing_subtrees;
@@ -5989,16 +5969,15 @@ get_mergeinfo_paths(apr_array_header_t *
        }
     }
 
-  /* Case 6: Paths absent from disk due to server-side exclusion. */
-  SVN_ERR(svn_wc__get_server_excluded_subtrees(&server_excluded_subtrees,
-                                               ctx->wc_ctx,
-                                               target->abspath,
-                                               result_pool, scratch_pool));
-  if (server_excluded_subtrees)
+  /* Case 6: Paths absent from disk due to server or user exclusion. */
+  SVN_ERR(svn_wc__get_excluded_subtrees(&excluded_subtrees,
+                                        ctx->wc_ctx, target->abspath,
+                                        result_pool, scratch_pool));
+  if (excluded_subtrees)
     {
       apr_hash_index_t *hi;
 
-      for (hi = apr_hash_first(scratch_pool, server_excluded_subtrees);
+      for (hi = apr_hash_first(scratch_pool, excluded_subtrees);
            hi;
            hi = apr_hash_next(hi))
         {
@@ -9571,7 +9550,8 @@ merge_locked(const char *source1,
   /* Unless we're ignoring ancestry, see if the two sources are related.  */
   if (! ignore_ancestry)
     SVN_ERR(svn_client__get_youngest_common_ancestor(
-              &yca, source1_loc, source2_loc, ctx, scratch_pool, scratch_pool));
+                    &yca, source1_loc, source2_loc, ra_session1, ctx,
+                    scratch_pool, scratch_pool));
 
   /* Check for a youngest common ancestor.  If we have one, we'll be
      doing merge tracking.
@@ -10489,7 +10469,8 @@ calculate_left_hand_side(svn_client__pat
      actually related, we can't reintegrate if they are not.  Also
      get an initial value for the YCA revision number. */
   SVN_ERR(svn_client__get_youngest_common_ancestor(
-            &yc_ancestor, source_loc, &target->loc, ctx, iterpool, iterpool));
+              &yc_ancestor, source_loc, &target->loc, target_ra_session, ctx,
+              iterpool, iterpool));
   if (! yc_ancestor)
     return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
                              _("'%s@%ld' must be ancestrally related to "
@@ -10654,7 +10635,7 @@ find_reintegrate_merge(merge_source_t **
     SVN_ERR(svn_ra_reparent(target_ra_session, source.loc1->url, scratch_pool));
 
   SVN_ERR(svn_client__get_youngest_common_ancestor(
-            &yc_ancestor, source.loc2, source.loc1,
+            &yc_ancestor, source.loc2, source.loc1, target_ra_session,
             ctx, scratch_pool, scratch_pool));
 
   /* The source side of a reintegrate merge is not 'ancestral', except in
@@ -11464,7 +11445,7 @@ find_symmetric_merge(svn_client__pathrev
             s_t->target_ra_session, ctx, scratch_pool));
 
   SVN_ERR(svn_client__get_youngest_common_ancestor(
-            &s_t->yca, s_t->source, &s_t->target->loc,
+            &s_t->yca, s_t->source, &s_t->target->loc, s_t->source_ra_session,
             ctx, result_pool, result_pool));
 
   /* Find the latest revision of A synced to B and the latest

Modified: subversion/branches/ev2-export/subversion/libsvn_client/prop_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/prop_commands.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/prop_commands.c Thu May 31 22:29:24 2012
@@ -725,7 +725,7 @@ recursive_propget_receiver(void *baton,
    Treat DEPTH as in svn_client_propget3().
 */
 static svn_error_t *
-get_prop_from_wc(apr_hash_t *props,
+get_prop_from_wc(apr_hash_t **props,
                  const char *propname,
                  const char *target_abspath,
                  svn_boolean_t pristine,
@@ -746,12 +746,24 @@ get_prop_from_wc(apr_hash_t *props,
   if (depth == svn_depth_unknown)
     depth = svn_depth_infinity;
 
-  rb.props = props;
+  if (!pristine && depth == svn_depth_infinity
+      && (!changelists || changelists->nelts == 0))
+    {
+      /* Handle this common svn:mergeinfo case more efficient than the target
+         list handling in the recursive retrieval. */
+      SVN_ERR(svn_wc__prop_retrieve_recursive(
+                            props, ctx->wc_ctx, target_abspath, propname,
+                            result_pool, scratch_pool));
+      return SVN_NO_ERROR;
+    }
+
+  *props = apr_hash_make(result_pool);
+  rb.props = *props;
   rb.pool = result_pool;
   rb.wc_ctx = ctx->wc_ctx;
 
   SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, target_abspath,
-                                      propname, depth, FALSE, pristine,
+                                      propname, depth, pristine,
                                       changelists,
                                       recursive_propget_receiver, &rb,
                                       ctx->cancel_func, ctx->cancel_baton,
@@ -784,8 +796,6 @@ svn_client_propget4(apr_hash_t **props,
                                                         target);
   revision = svn_cl__rev_default_to_peg(revision, peg_revision);
 
-  *props = apr_hash_make(result_pool);
-
   if (! svn_path_is_url(target)
       && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
       && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
@@ -822,7 +832,7 @@ svn_client_propget4(apr_hash_t **props,
       else if (err)
         return svn_error_trace(err);
 
-      SVN_ERR(get_prop_from_wc(*props, propname, target,
+      SVN_ERR(get_prop_from_wc(props, propname, target,
                                pristine, kind,
                                depth, changelists, ctx, scratch_pool,
                                result_pool));
@@ -841,6 +851,7 @@ svn_client_propget4(apr_hash_t **props,
 
       SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, scratch_pool));
 
+      *props = apr_hash_make(result_pool);
       SVN_ERR(remote_propget(*props, propname, loc->url, "",
                              kind, loc->rev, ra_session,
                              depth, result_pool, scratch_pool));
@@ -1130,8 +1141,7 @@ svn_client_proplist3(const char *path_or
             }
 
           SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, local_abspath, NULL,
-                                              depth,
-                                              FALSE, pristine, changelists,
+                                              depth, pristine, changelists,
                                               recursive_proplist_receiver, &rb,
                                               ctx->cancel_func,
                                               ctx->cancel_baton, pool));

Modified: subversion/branches/ev2-export/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/ra.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/ra.c Thu May 31 22:29:24 2012
@@ -843,12 +843,12 @@ svn_error_t *
 svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
                                          const svn_client__pathrev_t *loc1,
                                          const svn_client__pathrev_t *loc2,
+                                         svn_ra_session_t *session,
                                          svn_client_ctx_t *ctx,
                                          apr_pool_t *result_pool,
                                          apr_pool_t *scratch_pool)
 {
-  apr_pool_t *sesspool = svn_pool_create(scratch_pool);
-  svn_ra_session_t *session;
+  apr_pool_t *sesspool = NULL;
   apr_hash_t *history1, *history2;
   apr_hash_index_t *hi;
   svn_revnum_t yc_revision = SVN_INVALID_REVNUM;
@@ -863,7 +863,11 @@ svn_client__get_youngest_common_ancestor
     }
 
   /* Open an RA session for the two locations. */
-  SVN_ERR(svn_client_open_ra_session(&session, loc1->url, ctx, sesspool));
+  if (session == NULL)
+    {
+      sesspool = svn_pool_create(scratch_pool);
+      SVN_ERR(svn_client_open_ra_session(&session, loc1->url, ctx, sesspool));
+    }
 
   /* We're going to cheat and use history-as-mergeinfo because it
      saves us a bunch of annoying custom data comparisons and such. */
@@ -879,8 +883,9 @@ svn_client__get_youngest_common_ancestor
                                                SVN_INVALID_REVNUM,
                                                SVN_INVALID_REVNUM,
                                                session, ctx, scratch_pool));
-  /* Close the source and target sessions. */
-  svn_pool_destroy(sesspool);
+  /* Close the ra session if we opened one. */
+  if (sesspool)
+    svn_pool_destroy(sesspool);
 
   /* Loop through the first location's history, check for overlapping
      paths and ranges in the second location's history, and
@@ -959,7 +964,7 @@ svn_client__youngest_common_ancestor(con
                               ctx, scratch_pool));
 
   SVN_ERR(svn_client__get_youngest_common_ancestor(
-            &ancestor, loc1, loc2, ctx, result_pool, scratch_pool));
+            &ancestor, loc1, loc2, session, ctx, result_pool, scratch_pool));
 
   if (ancestor)
     {

Modified: subversion/branches/ev2-export/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/switch.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/switch.c Thu May 31 22:29:24 2012
@@ -208,7 +208,8 @@ switch_internal(svn_revnum_t *result_rev
           /* ### It would be nice if this function could reuse the existing
              ra session instead of opening two for its own use. */
           SVN_ERR(svn_client__get_youngest_common_ancestor(
-                  &yca, switch_loc, target_base_loc, ctx, pool, pool));
+                  &yca, switch_loc, target_base_loc, ra_session, ctx,
+                  pool, pool));
         }
       if (! yca)
         return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,

Modified: subversion/branches/ev2-export/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_delta/compat.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_delta/compat.c Thu May 31 22:29:24 2012
@@ -1494,7 +1494,6 @@ drive_ev1_props(const struct editor_bato
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_hash_t *old_props;
   apr_array_header_t *propdiffs;
-  const char *ev1_relpath;
   int i;
 
   /* If there are no properties to install, then just exit.  */
@@ -1527,8 +1526,6 @@ drive_ev1_props(const struct editor_bato
 
   SVN_ERR(svn_prop_diffs(&propdiffs, change->props, old_props, scratch_pool));
 
-  ev1_relpath = svn_relpath_skip_ancestor(eb->base_relpath, repos_relpath);
-
   for (i = 0; i < propdiffs->nelts; i++)
     {
       /* Note: the array returned by svn_prop_diffs() is an array of

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/dag.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/dag.c Thu May 31 22:29:24 2012
@@ -749,7 +749,6 @@ svn_fs_fs__dag_delete(dag_node_t *parent
                       apr_pool_t *pool)
 {
   node_revision_t *parent_noderev;
-  apr_hash_t *entries;
   svn_fs_t *fs = parent->fs;
   svn_fs_dirent_t *dirent;
   svn_fs_id_t *id;

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c Thu May 31 22:29:24 2012
@@ -4852,9 +4852,16 @@ fetch_all_changes(apr_hash_t *changed_pa
           apr_hash_index_t *hi;
 
           /* a potential child path must contain at least 2 more chars
-             (the path separator plus at least one char for the name)
+             (the path separator plus at least one char for the name).
+             Also, we should not assume that all paths have been normalized
+             i.e. some might have trailing path separators.
           */
-          apr_ssize_t min_child_len = strlen(change->path) + 2;
+          apr_ssize_t change_path_len = strlen(change->path);
+          apr_ssize_t min_child_len = change_path_len == 0
+                                    ? 1
+                                    : change->path[change_path_len-1] == '/'
+                                        ? change_path_len + 1
+                                        : change_path_len + 2;
 
           /* CAUTION: This is the inner loop of an O(n^2) algorithm.
              The number of changes to process may be >> 1000.

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/dump.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/dump.c Thu May 31 22:29:24 2012
@@ -34,6 +34,7 @@
 #include "svn_time.h"
 #include "svn_checksum.h"
 #include "svn_props.h"
+#include "svn_sorts.h"
 
 #include "private/svn_mergeinfo_private.h"
 #include "private/svn_fs_private.h"
@@ -734,14 +735,20 @@ close_directory(void *dir_baton,
 {
   struct dir_baton *db = dir_baton;
   struct edit_baton *eb = db->edit_baton;
-  apr_hash_index_t *hi;
   apr_pool_t *subpool = svn_pool_create(pool);
+  unsigned int i;
+  apr_array_header_t *sorted_entries;
 
-  for (hi = apr_hash_first(pool, db->deleted_entries);
-       hi;
-       hi = apr_hash_next(hi))
+  /* Sort entries lexically instead of as paths. Even though the entries
+   * are full paths they're all in the same directory (see comment in struct
+   * dir_baton definition). So we really want to sort by basename, in which
+   * case the lexical sort function is more efficient. */
+  sorted_entries = svn_sort__hash(db->deleted_entries,
+                                  svn_sort_compare_items_lexically, pool);
+  for (i = 0; i < sorted_entries->nelts; i++)
     {
-      const char *path = svn__apr_hash_index_key(hi);
+      const char *path = APR_ARRAY_IDX(sorted_entries, i,
+                                       svn_sort__item_t).key;
 
       svn_pool_clear(subpool);
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c Thu May 31 22:29:24 2012
@@ -60,15 +60,19 @@ typedef struct parse_context_t
   /* The current line in the file */
   int line;
 
-  /* Cached ungotten character  - streams don't support ungetc()
-     [emulate it] */
+  /* Emulate an ungetc */
   int ungotten_char;
-  svn_boolean_t have_ungotten_char;
 
-  /* Temporary strings, allocated from the temp pool */
+  /* Temporary strings */
   svn_stringbuf_t *section;
   svn_stringbuf_t *option;
   svn_stringbuf_t *value;
+
+  /* Parser buffer for getc() to avoid call overhead into several libraries
+     for every character */
+  char parser_buffer[SVN_STREAM_CHUNK_SIZE]; /* Larger than most config files */
+  size_t buffer_pos; /* Current position within parser_buffer */
+  size_t buffer_size; /* parser_buffer contains this many bytes */
 } parse_context_t;
 
 
@@ -82,23 +86,36 @@ typedef struct parse_context_t
 static APR_INLINE svn_error_t *
 parser_getc(parse_context_t *ctx, int *c)
 {
-  if (ctx->have_ungotten_char)
-    {
-      *c = ctx->ungotten_char;
-      ctx->have_ungotten_char = FALSE;
-    }
-  else
+  do
     {
-      char char_buf;
-      apr_size_t readlen = 1;
+      if (ctx->ungotten_char != EOF)
+        {
+          *c = ctx->ungotten_char;
+          ctx->ungotten_char = EOF;
+        }
+      else if (ctx->buffer_pos < ctx->buffer_size)
+        {
+          *c = ctx->parser_buffer[ctx->buffer_pos];
+          ctx->buffer_pos++;
+        }
+      else
+        {
+          ctx->buffer_pos = 0;
+          ctx->buffer_size = sizeof(ctx->parser_buffer);
 
-      SVN_ERR(svn_stream_read(ctx->stream, &char_buf, &readlen));
+          SVN_ERR(svn_stream_read(ctx->stream, ctx->parser_buffer,
+                                  &(ctx->buffer_size)));
 
-      if (readlen == 1)
-        *c = char_buf;
-      else
-        *c = EOF;
+          if (ctx->buffer_pos < ctx->buffer_size)
+            {
+              *c = ctx->parser_buffer[ctx->buffer_pos];
+              ctx->buffer_pos++;
+            }
+          else
+            *c = EOF;
+        }
     }
+  while (*c == '\r');
 
   return SVN_NO_ERROR;
 }
@@ -111,7 +128,6 @@ static APR_INLINE svn_error_t *
 parser_ungetc(parse_context_t *ctx, int c)
 {
   ctx->ungotten_char = c;
-  ctx->have_ungotten_char = TRUE;
 
   return SVN_NO_ERROR;
 }
@@ -241,7 +257,7 @@ parse_value(int *pch, parse_context_t *c
 
 /* Parse a single option */
 static svn_error_t *
-parse_option(int *pch, parse_context_t *ctx, apr_pool_t *pool)
+parse_option(int *pch, parse_context_t *ctx, apr_pool_t *scratch_pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
   int ch;
@@ -260,7 +276,7 @@ parse_option(int *pch, parse_context_t *
       ch = EOF;
       err = svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
                               "%s:%d: Option must end with ':' or '='",
-                              svn_dirent_local_style(ctx->file, pool),
+                              svn_dirent_local_style(ctx->file, scratch_pool),
                               ctx->line);
     }
   else
@@ -284,7 +300,8 @@ parse_option(int *pch, parse_context_t *
  * starts a section name.
  */
 static svn_error_t *
-parse_section_name(int *pch, parse_context_t *ctx, apr_pool_t *pool)
+parse_section_name(int *pch, parse_context_t *ctx,
+                   apr_pool_t *scratch_pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
   int ch;
@@ -303,7 +320,7 @@ parse_section_name(int *pch, parse_conte
       ch = EOF;
       err = svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
                               "%s:%d: Section header must end with ']'",
-                              svn_dirent_local_style(ctx->file, pool),
+                              svn_dirent_local_style(ctx->file, scratch_pool),
                               ctx->line);
     }
   else
@@ -363,91 +380,101 @@ svn_config__sys_config_path(const char *
 
 svn_error_t *
 svn_config__parse_file(svn_config_t *cfg, const char *file,
-                       svn_boolean_t must_exist, apr_pool_t *pool)
+                       svn_boolean_t must_exist, apr_pool_t *result_pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
-  parse_context_t ctx;
+  parse_context_t *ctx;
   int ch, count;
   svn_stream_t *stream;
+  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
 
-  err = svn_stream_open_readonly(&stream, file, pool, pool);
+  err = svn_stream_open_readonly(&stream, file, scratch_pool, scratch_pool);
 
   if (! must_exist && err && APR_STATUS_IS_ENOENT(err->apr_err))
     {
       svn_error_clear(err);
+      svn_pool_destroy(scratch_pool);
       return SVN_NO_ERROR;
     }
   else
     SVN_ERR(err);
 
-  ctx.cfg = cfg;
-  ctx.file = file;
-  ctx.stream = svn_subst_stream_translated(stream, "\n", TRUE, NULL, FALSE,
-                                           pool);
-  ctx.line = 1;
-  ctx.have_ungotten_char = FALSE;
-  ctx.section = svn_stringbuf_create_empty(pool);
-  ctx.option = svn_stringbuf_create_empty(pool);
-  ctx.value = svn_stringbuf_create_empty(pool);
+  ctx = apr_palloc(scratch_pool, sizeof(*ctx));
+
+  ctx->cfg = cfg;
+  ctx->file = file;
+  ctx->stream = stream;
+  ctx->line = 1;
+  ctx->ungotten_char = EOF;
+  ctx->section = svn_stringbuf_create_empty(scratch_pool);
+  ctx->option = svn_stringbuf_create_empty(scratch_pool);
+  ctx->value = svn_stringbuf_create_empty(scratch_pool);
+  ctx->buffer_pos = 0;
+  ctx->buffer_size = 0;
 
   do
     {
-      SVN_ERR(skip_whitespace(&ctx, &ch, &count));
+      SVN_ERR(skip_whitespace(ctx, &ch, &count));
 
       switch (ch)
         {
         case '[':               /* Start of section header */
           if (count == 0)
-            SVN_ERR(parse_section_name(&ch, &ctx, pool));
+            SVN_ERR(parse_section_name(&ch, ctx, scratch_pool));
           else
             return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
                                      "%s:%d: Section header"
                                      " must start in the first column",
-                                     svn_dirent_local_style(file, pool),
-                                     ctx.line);
+                                     svn_dirent_local_style(file,
+                                                            scratch_pool),
+                                     ctx->line);
           break;
 
         case '#':               /* Comment */
           if (count == 0)
             {
-              SVN_ERR(skip_to_eoln(&ctx, &ch));
-              ++ctx.line;
+              SVN_ERR(skip_to_eoln(ctx, &ch));
+              ++(ctx->line);
             }
           else
             return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
                                      "%s:%d: Comment"
                                      " must start in the first column",
-                                     svn_dirent_local_style(file, pool),
-                                     ctx.line);
+                                     svn_dirent_local_style(file,
+                                                            scratch_pool),
+                                     ctx->line);
           break;
 
         case '\n':              /* Empty line */
-          ++ctx.line;
+          ++(ctx->line);
           break;
 
         case EOF:               /* End of file or read error */
           break;
 
         default:
-          if (svn_stringbuf_isempty(ctx.section))
+          if (svn_stringbuf_isempty(ctx->section))
             return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
                                      "%s:%d: Section header expected",
-                                     svn_dirent_local_style(file, pool),
-                                     ctx.line);
+                                     svn_dirent_local_style(file,
+                                                            scratch_pool),
+                                     ctx->line);
           else if (count != 0)
             return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
                                      "%s:%d: Option expected",
-                                     svn_dirent_local_style(file, pool),
-                                     ctx.line);
+                                     svn_dirent_local_style(file,
+                                                            scratch_pool),
+                                     ctx->line);
           else
-            SVN_ERR(parse_option(&ch, &ctx, pool));
+            SVN_ERR(parse_option(&ch, ctx, scratch_pool));
           break;
         }
     }
   while (ch != EOF);
 
   /* Close the streams (and other cleanup): */
-  return svn_stream_close(ctx.stream);
+  svn_pool_destroy(scratch_pool);
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/hash.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/hash.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/hash.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/hash.c Thu May 31 22:29:24 2012
@@ -565,11 +565,11 @@ svn_hash__get_bool(apr_hash_t *hash, con
 
 /*** Optimized hash function ***/
 
-/* Optimized version of apr_hashfunc_default. It assumes that the CPU has
- * 32-bit multiplications with high throughput of at least 1 operation
- * every 3 cycles. Latency is not an issue. Another optimization is a
- * mildly unrolled main loop and breaking the dependency chain within the
- * loop.
+/* Optimized version of apr_hashfunc_default in APR 1.4.5 and earlier.
+ * It assumes that the CPU has 32-bit multiplications with high throughput
+ * of at least 1 operation every 3 cycles. Latency is not an issue. Another
+ * optimization is a mildly unrolled main loop and breaking the dependency
+ * chain within the loop.
  *
  * Note that most CPUs including Intel Atom, VIA Nano, ARM feature the
  * assumed pipelined multiplication circuitry. They can do one MUL every

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c Thu May 31 22:29:24 2012
@@ -1805,25 +1805,30 @@ revert_restore(svn_wc__db_t *db,
                 }
               else
                 {
-                  svn_boolean_t read_only;
-                  svn_string_t *needs_lock_prop;
+                  if (status == svn_wc__db_status_normal)
+                    {
+                      svn_boolean_t read_only;
+                      svn_string_t *needs_lock_prop;
 
-                  SVN_ERR(svn_io__is_finfo_read_only(&read_only, &finfo,
-                                                     scratch_pool));
+                      SVN_ERR(svn_io__is_finfo_read_only(&read_only, &finfo,
+                                                         scratch_pool));
 
-                  needs_lock_prop = apr_hash_get(props, SVN_PROP_NEEDS_LOCK,
-                                                 APR_HASH_KEY_STRING);
-                  if (needs_lock_prop && !read_only)
-                    {
-                      SVN_ERR(svn_io_set_file_read_only(local_abspath,
-                                                        FALSE, scratch_pool));
-                      notify_required = TRUE;
-                    }
-                  else if (!needs_lock_prop && read_only)
-                    {
-                      SVN_ERR(svn_io_set_file_read_write(local_abspath,
-                                                         FALSE, scratch_pool));
-                      notify_required = TRUE;
+                      needs_lock_prop = apr_hash_get(props, SVN_PROP_NEEDS_LOCK,
+                                                     APR_HASH_KEY_STRING);
+                      if (needs_lock_prop && !read_only)
+                        {
+                          SVN_ERR(svn_io_set_file_read_only(local_abspath,
+                                                            FALSE,
+                                                            scratch_pool));
+                          notify_required = TRUE;
+                        }
+                      else if (!needs_lock_prop && read_only)
+                        {
+                          SVN_ERR(svn_io_set_file_read_write(local_abspath,
+                                                             FALSE,
+                                                             scratch_pool));
+                          notify_required = TRUE;
+                        }
                     }
 
 #if !defined(WIN32) && !defined(__OS2__)

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/externals.c?rev=1344934&r1=1344933&r2=1344934&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/externals.c Thu May 31 22:29:24 2012
@@ -1134,19 +1134,17 @@ is_external_rolled_out(svn_boolean_t *is
                        svn_wc__committable_external_info_t *xinfo,
                        apr_pool_t *scratch_pool)
 {
-  const char *x_repos_relpath;
-  const char *x_repos_root_url;
+  const char *repos_relpath;
+  const char *repos_root_url;
   svn_error_t *err;
 
   *is_rolled_out = FALSE;
 
-  err = svn_wc__node_get_origin(NULL, NULL,
-                                &x_repos_relpath,
-                                &x_repos_root_url,
-                                NULL, NULL,
-                                wc_ctx, xinfo->local_abspath,
-                                FALSE, /* scan_deleted */
-                                scratch_pool, scratch_pool);
+  err = svn_wc__db_base_get_info(NULL, NULL, NULL, &repos_relpath,
+                                 &repos_root_url, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL,
+                                 wc_ctx->db, xinfo->local_abspath,
+                                 scratch_pool, scratch_pool);
 
   if (err)
     {
@@ -1158,8 +1156,8 @@ is_external_rolled_out(svn_boolean_t *is
       SVN_ERR(err);
     }
 
-  *is_rolled_out = (strcmp(xinfo->repos_root_url, x_repos_root_url) == 0 &&
-                    strcmp(xinfo->repos_relpath, x_repos_relpath) == 0);
+  *is_rolled_out = (strcmp(xinfo->repos_root_url, repos_root_url) == 0 &&
+                    strcmp(xinfo->repos_relpath, repos_relpath) == 0);
   return SVN_NO_ERROR;
 }
 



Mime
View raw message