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 2010/10/30 16:20:18 UTC

svn commit: r1029078 [1/5] - in /subversion/branches/performance: ./ build/ac-macros/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/tigris/subversion/javahl/ subversio...

Author: stefan2
Date: Sat Oct 30 14:20:17 2010
New Revision: 1029078

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

Modified:
    subversion/branches/performance/   (props changed)
    subversion/branches/performance/build/ac-macros/java.m4
    subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h
    subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
    subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
    subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
    subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
    subversion/branches/performance/subversion/include/svn_client.h
    subversion/branches/performance/subversion/include/svn_wc.h
    subversion/branches/performance/subversion/libsvn_client/deprecated.c
    subversion/branches/performance/subversion/libsvn_client/externals.c
    subversion/branches/performance/subversion/libsvn_client/merge.c
    subversion/branches/performance/subversion/libsvn_client/patch.c
    subversion/branches/performance/subversion/libsvn_client/relocate.c
    subversion/branches/performance/subversion/libsvn_diff/parse-diff.c
    subversion/branches/performance/subversion/libsvn_repos/log.c
    subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c
    subversion/branches/performance/subversion/libsvn_wc/conflicts.c
    subversion/branches/performance/subversion/libsvn_wc/copy.c
    subversion/branches/performance/subversion/libsvn_wc/props.c
    subversion/branches/performance/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/performance/subversion/libsvn_wc/wc_db.c
    subversion/branches/performance/subversion/libsvn_wc/wc_db.h
    subversion/branches/performance/subversion/libsvn_wc/workqueue.c
    subversion/branches/performance/subversion/libsvn_wc/workqueue.h
    subversion/branches/performance/subversion/svn/cl.h
    subversion/branches/performance/subversion/svn/log-cmd.c
    subversion/branches/performance/subversion/svn/main.c
    subversion/branches/performance/subversion/svn/merge-cmd.c
    subversion/branches/performance/subversion/svn/patch-cmd.c
    subversion/branches/performance/subversion/svn/relocate-cmd.c
    subversion/branches/performance/subversion/svn/status-cmd.c
    subversion/branches/performance/subversion/svn/status.c
    subversion/branches/performance/subversion/svn/switch-cmd.c
    subversion/branches/performance/subversion/tests/cmdline/authz_tests.py
    subversion/branches/performance/subversion/tests/cmdline/copy_tests.py
    subversion/branches/performance/subversion/tests/cmdline/export_tests.py
    subversion/branches/performance/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
    subversion/branches/performance/subversion/tests/cmdline/log_tests.py
    subversion/branches/performance/subversion/tests/cmdline/merge_reintegrate_tests.py
    subversion/branches/performance/subversion/tests/cmdline/merge_tests.py
    subversion/branches/performance/subversion/tests/cmdline/merge_tree_conflict_tests.py
    subversion/branches/performance/subversion/tests/cmdline/mergeinfo_tests.py
    subversion/branches/performance/subversion/tests/cmdline/patch_tests.py
    subversion/branches/performance/subversion/tests/cmdline/resolve_tests.py
    subversion/branches/performance/subversion/tests/cmdline/special_tests.py
    subversion/branches/performance/subversion/tests/cmdline/stat_tests.py
    subversion/branches/performance/subversion/tests/cmdline/switch_tests.py
    subversion/branches/performance/subversion/tests/cmdline/tree_conflict_tests.py
    subversion/branches/performance/subversion/tests/libsvn_client/client-test.c
    subversion/branches/performance/subversion/tests/libsvn_fs_base/strings-reps-test.c
    subversion/branches/performance/subversion/tests/libsvn_subr/string-test.c
    subversion/branches/performance/subversion/tests/libsvn_wc/db-test.c
    subversion/branches/performance/subversion/tests/libsvn_wc/entries-compat.c
    subversion/branches/performance/subversion/tests/libsvn_wc/op-depth-test.c
    subversion/branches/performance/tools/diff/diff.c
    subversion/branches/performance/tools/hook-scripts/svnperms.conf.example
    subversion/branches/performance/tools/hook-scripts/svnperms.py
    subversion/branches/performance/win-tests.py

Propchange: subversion/branches/performance/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Oct 30 14:20:17 2010
@@ -37,4 +37,4 @@
 /subversion/branches/tc_url_rev:874351-874483
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
-/subversion/trunk:962911-1027198
+/subversion/trunk:962911-1028883

Modified: subversion/branches/performance/build/ac-macros/java.m4
URL: http://svn.apache.org/viewvc/subversion/branches/performance/build/ac-macros/java.m4?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/build/ac-macros/java.m4 (original)
+++ subversion/branches/performance/build/ac-macros/java.m4 Sat Oct 30 14:20:17 2010
@@ -82,20 +82,48 @@ AC_DEFUN(SVN_FIND_JDK,
   dnl /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Commands
   dnl See http://developer.apple.com/qa/qa2001/qa1170.html
   os_arch="`uname`"
+  if test "$os_arch" = "Darwin"; then
+    OSX_VER=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 | cut -d"." -f1,2`
+
+    if test "$OSX_VER" = "10.4"; then
+      dnl For OS X 10.4, the SDK version is 10.4u instead of 10.4.
+      OSX_VER = "$OSX_VERu"
+    fi
+
+    OSX_SYS_JAVA_FRAMEWORK="/System/Library/Frameworks/JavaVM.framework"
+    OSX_SDK_JAVA_FRAMEWORK="/Developer/SDKs/MacOSX$OSX_VER.sdk/System/Library"
+    OSX_SDK_JAVA_FRAMEWORK="$OSX_SDK_JAVA_FRAMEWORK/Frameworks/JavaVM.framework"
+  fi
+
   if test "$os_arch" = "Darwin" && test "$JDK" = "/usr" &&
      test -d "/Library/Java/Home"; then
-      JDK="/Library/Java/Home"
+    JDK="/Library/Java/Home"
   fi
+
   if test "$os_arch" = "Darwin" && test "$JDK" = "/Library/Java/Home"; then
-      JRE_LIB_DIR="/System/Library/Frameworks/JavaVM.framework/Classes"
+    JRE_LIB_DIR="$OSX_SYS_JAVA_FRAMEWORK/Classes"
   else
-      JRE_LIB_DIR="$JDK/jre/lib"
+    JRE_LIB_DIR="$JDK/jre/lib"
   fi
 
   if test -f "$JDK/include/jni.h"; then
     dnl This *must* be fully expanded, or we'll have problems later in find.
     JNI_INCLUDEDIR="$JDK/include"
     JDK_SUITABLE=yes
+  elif test "$os_arch" = "Darwin" && test -e "$JDK/Headers/jni.h"; then
+    dnl Search the Headers directory in the JDK
+    JNI_INCLUDEDIR="$JDK/Headers"
+    JDK_SUITABLE=yes
+  elif test "$os_arch" = "Darwin" &&
+       test -e "$OSX_SYS_JAVA_FRAMEWORK/Headers/jni.h"; then
+    dnl Search the System framework's Headers directory
+    JNI_INCLUDEDIR="$OSX_SYS_JAVA_FRAMEWORK/Headers"
+    JDK_SUITABLE=yes
+  elif test "$os_arch" = "Darwin" &&
+       test -e "$OSX_SDK_JAVA_FRAMEWORK/Headers/jni.h"; then
+    dnl Search the SDK's System framework's Headers directory
+    JNI_INCLUDEDIR="$OSX_SDK_JAVA_FRAMEWORK/Headers"
+    JDK_SUITABLE=yes
   else
     AC_MSG_WARN([no JNI header files found.])
     if test "$os_arch" = "Darwin"; then
@@ -103,7 +131,7 @@ AC_DEFUN(SVN_FIND_JDK,
     fi
     JDK_SUITABLE=no
   fi
-  AC_MSG_RESULT([$JDK_SUITABLE])
+  AC_MSG_RESULT([$JNI_INCLUDEDIR/jni.h])
 
   if test "$JDK_SUITABLE" = "yes"; then
     JAVA_BIN='$(JDK)/bin'

Modified: subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp Sat Oct 30 14:20:17 2010
@@ -1151,7 +1151,8 @@ jbyteArray SVNClient::revProperty(const 
     return JNIUtil::makeJByteArray((const signed char *)propval->data,
                                    propval->len);
 }
-void SVNClient::relocate(const char *from, const char *to, const char *path)
+void SVNClient::relocate(const char *from, const char *to, const char *path,
+                         bool ignoreExternals)
 {
     SVN::Pool requestPool;
     SVN_JNI_NULL_PTR_EX(path, "path", );
@@ -1171,7 +1172,7 @@ void SVNClient::relocate(const char *fro
         return;
 
     SVN_JNI_ERR(svn_client_relocate2(intPath.c_str(), intFrom.c_str(),
-                                     intTo.c_str(), ctx,
+                                     intTo.c_str(), ignoreExternals, ctx,
                                      requestPool.pool()), );
 }
 
@@ -1460,7 +1461,7 @@ SVNClient::patch(const char *patchPath, 
     // Should parameterize the following, instead of defaulting to FALSE
     SVN_JNI_ERR(svn_client_patch(checkedPatchPath.c_str(),
                                  checkedTargetPath.c_str(),
-                                 dryRun, stripCount, FALSE, reverse,
+                                 dryRun, stripCount, reverse,
                                  ignoreWhitespace, removeTempfiles,
                                  PatchCallback::callback, callback,
                                  ctx, requestPool.pool(),

Modified: subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h Sat Oct 30 14:20:17 2010
@@ -74,7 +74,8 @@ class SVNClient :public SVNBase
              Revision &revisionStart, Revision &revisionEnd,
              bool ignoreMimeType, bool includeMergedRevisions,
              BlameCallback *callback);
-  void relocate(const char *from, const char *to, const char *path);
+  void relocate(const char *from, const char *to, const char *path,
+                bool ignoreExternals);
   void streamFileContent(const char *path, Revision &revision,
                          Revision &pegRevision, OutputStream &outputStream);
   void propertySet(const char *path, const char *name, const char *value,

Modified: subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Sat Oct 30 14:20:17 2010
@@ -1422,7 +1422,8 @@ Java_org_apache_subversion_javahl_SVNCli
 
 JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_SVNClient_relocate
-(JNIEnv *env, jobject jthis, jstring jfrom, jstring jto, jstring jpath)
+(JNIEnv *env, jobject jthis, jstring jfrom, jstring jto, jstring jpath,
+ jboolean jignoreExternals)
 {
   JNIEntry(SVNClient, relocate);
   SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -1443,7 +1444,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  cl->relocate(from, to, path);
+  cl->relocate(from, to, path, jignoreExternals ? true : false);
   return;
 }
 

Modified: subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Sat Oct 30 14:20:17 2010
@@ -798,10 +798,11 @@ public interface ISVNClient
      * @param from      old url
      * @param to        new url
      * @param path      working copy path
+     * @param ignoreExternals if externals are ignored during relocate
      * @throws ClientException
      * @since 1.0
      */
-    void relocate(String from, String to, String path)
+    void relocate(String from, String to, String path, boolean ignoreExternals)
             throws ClientException;
 
     /**

Modified: subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Sat Oct 30 14:20:17 2010
@@ -495,7 +495,8 @@ public class SVNClient implements ISVNCl
     /**
      * @since 1.0
      */
-    public native void relocate(String from, String to, String path)
+    public native void relocate(String from, String to, String path,
+                                boolean ignoreExternals)
             throws ClientException;
 
     /**

Modified: subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java Sat Oct 30 14:20:17 2010
@@ -2125,7 +2125,7 @@ public class SVNClient implements SVNCli
 
         try
         {
-            aSVNClient.relocate(from, to, path);
+            aSVNClient.relocate(from, to, path, true);
         }
         catch (org.apache.subversion.javahl.ClientException ex)
         {

Modified: subversion/branches/performance/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_client.h?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_client.h (original)
+++ subversion/branches/performance/subversion/include/svn_client.h Sat Oct 30 14:20:17 2010
@@ -3068,9 +3068,39 @@ svn_client_diff_summarize_peg(const char
  * If @a dry_run is TRUE, the merge is carried out, and full notification
  * feedback is provided, but the working copy is not modified.
  *
+ * If allow_mixed_rev is @c FALSE, and @a merge_target is a mixed-revision
+ * working copy, raise @c SVN_ERR_CLIENT_NOT_READY_TO_MERGE.
+ * Because users rarely intend to merge into mixed-revision working copies,
+ * it is recommended to set this parameter to FALSE by default unless the
+ * user has explicitly requested a merge into a mixed-revision working copy.
+ *
  * The authentication baton cached in @a ctx is used to communicate with the
  * repository.
  *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_merge4(const char *source1,
+                  const svn_opt_revision_t *revision1,
+                  const char *source2,
+                  const svn_opt_revision_t *revision2,
+                  const char *target_wcpath,
+                  svn_depth_t depth,
+                  svn_boolean_t ignore_ancestry,
+                  svn_boolean_t force,
+                  svn_boolean_t record_only,
+                  svn_boolean_t dry_run,
+                  svn_boolean_t allow_mixed_rev,
+                  const apr_array_header_t *merge_options,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_merge4(), but with @a allow_mixed_rev set to
+ * @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ *
  * @since New in 1.5.
  */
 svn_error_t *
@@ -3172,7 +3202,30 @@ svn_client_merge_reintegrate(const char 
  * list of provided ranges has an `unspecified' or unrecognized
  * `kind', return #SVN_ERR_CLIENT_BAD_REVISION.
  *
- * All other options are handled identically to svn_client_merge3().
+ * All other options are handled identically to svn_client_merge4().
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_merge_peg4(const char *source,
+                      const apr_array_header_t *ranges_to_merge,
+                      const svn_opt_revision_t *peg_revision,
+                      const char *target_wcpath,
+                      svn_depth_t depth,
+                      svn_boolean_t ignore_ancestry,
+                      svn_boolean_t force,
+                      svn_boolean_t record_only,
+                      svn_boolean_t dry_run,
+                      svn_boolean_t allow_mixed_rev,
+                      const apr_array_header_t *merge_options,
+                      svn_client_ctx_t *ctx,
+                      apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_merge_peg4(), but with @a allow_mixed_rev set to
+ * @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
  *
  * @since New in 1.5.
  */
@@ -3423,6 +3476,8 @@ svn_client_upgrade(const char *dir,
  * @param wcroot_dir Working copy root directory
  * @param from Original URL
  * @param to New URL
+ * @param ignore_externals If not set, recurse into external working
+ *        copies after relocating the primary working copy
  * @param ctx svn_client_ctx_t
  * @param pool The pool from which to perform memory allocations
  *
@@ -3432,11 +3487,13 @@ svn_error_t *
 svn_client_relocate2(const char *wcroot_dir,
                      const char *from,
                      const char *to,
+                     svn_boolean_t ignore_externals,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool);
 
 /**
- * Similar to svn_client_relocate2().
+ * Similar to svn_client_relocate2(), but with @a ignore_externals
+ * always TRUE.
  *
  * @note As of the 1.7 API, @a dir is required to be a working copy
  * root directory, and @a recurse is required to be TRUE.
@@ -5258,15 +5315,6 @@ typedef svn_error_t *(*svn_client_patch_
  * stripped from paths obtained from the patch. It is an error if a
  * negative strip count is passed.
  *
- * If @a old_patch_target_names is @c TRUE, use target names from the old
- * side of the patch, rather than using target names from the new side of
- * the patch. For instance, if a unidiff header contains
- *   --- foo.c
- *   +++ foo.c.new
- * and @a old_patch_target_names is @c TRUE, the name "foo.c" will be used
- * for the target, and if @a old_patch_target_names is @c FALSE, the target
- * name "foo.c.new" will be used.
- *
  * If @a reverse is @c TRUE, apply patches in reverse, deleting lines
  * the patch would add and adding lines the patch would delete.
  * This is useful when applying a unidiff which was created with the
@@ -5298,7 +5346,6 @@ svn_client_patch(const char *patch_abspa
                  const char *local_abspath,
                  svn_boolean_t dry_run,
                  int strip_count,
-                 svn_boolean_t old_patch_target_names,
                  svn_boolean_t reverse,
                  svn_boolean_t ignore_whitespace,
                  svn_boolean_t remove_tempfiles,

Modified: subversion/branches/performance/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_wc.h?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_wc.h (original)
+++ subversion/branches/performance/subversion/include/svn_wc.h Sat Oct 30 14:20:17 2010
@@ -3796,9 +3796,11 @@ typedef void (*svn_wc_status_func_t)(voi
  * If @a cancel_func is non-NULL, call it with @a cancel_baton while walking
  * to determine if the client has cancelled the operation.
  *
- * If @a external_func is non-NULL, call it with @a external_baton if an
- * external definition is found while walking @a local_abspath.
- * ### call it with what other parameters?
+ * If @a external_func is non-NULL and an external definition is found
+ * while walking @a local_abspath, call @a external_func with @a
+ * external_baton, with the local abspath on which the definition was
+ * found, and with the current external definition provided as both
+ * the @a old_val and @a new_val parameters of the callback function.
  *
  * This function uses @a scratch_pool for temporary allocations.
  *

Modified: subversion/branches/performance/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/deprecated.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/deprecated.c Sat Oct 30 14:20:17 2010
@@ -1338,6 +1338,27 @@ svn_client_log(const apr_array_header_t 
 /*** From merge.c ***/
 
 svn_error_t *
+svn_client_merge3(const char *source1,
+                  const svn_opt_revision_t *revision1,
+                  const char *source2,
+                  const svn_opt_revision_t *revision2,
+                  const char *target_wcpath,
+                  svn_depth_t depth,
+                  svn_boolean_t ignore_ancestry,
+                  svn_boolean_t force,
+                  svn_boolean_t record_only,
+                  svn_boolean_t dry_run,
+                  const apr_array_header_t *merge_options,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *pool)
+{
+  return svn_client_merge4(source1, revision1, source2, revision2,
+                           target_wcpath, depth, ignore_ancestry, force,
+                           record_only, dry_run, TRUE, merge_options,
+                           ctx, pool);
+}
+
+svn_error_t *
 svn_client_merge2(const char *source1,
                   const svn_opt_revision_t *revision1,
                   const char *source2,
@@ -1376,7 +1397,25 @@ svn_client_merge(const char *source1,
                            dry_run, NULL, ctx, pool);
 }
 
-
+svn_error_t *
+svn_client_merge_peg3(const char *source,
+                      const apr_array_header_t *ranges_to_merge,
+                      const svn_opt_revision_t *peg_revision,
+                      const char *target_wcpath,
+                      svn_depth_t depth,
+                      svn_boolean_t ignore_ancestry,
+                      svn_boolean_t force,
+                      svn_boolean_t record_only,
+                      svn_boolean_t dry_run,
+                      const apr_array_header_t *merge_options,
+                      svn_client_ctx_t *ctx,
+                      apr_pool_t *pool)
+{
+  return svn_client_merge_peg4(source, ranges_to_merge, peg_revision,
+                               target_wcpath, depth, ignore_ancestry, force,
+                               record_only, dry_run, TRUE, merge_options,
+                               ctx, pool);
+}
 
 svn_error_t *
 svn_client_merge_peg2(const char *source,
@@ -2053,5 +2092,5 @@ svn_client_relocate(const char *path,
   if (! recurse)
     svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, 0,
                      _("Non-recursive relocation not supported"));
-  return svn_client_relocate2(path, from, to, ctx, pool);
+  return svn_client_relocate2(path, from, to, TRUE, ctx, pool);
 }

Modified: subversion/branches/performance/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/externals.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/externals.c Sat Oct 30 14:20:17 2010
@@ -230,7 +230,7 @@ switch_dir_external(const char *path,
                                                  subpool));
 
                   err = svn_client_relocate2(path, repos_root_url, repos_root,
-                                             ctx, subpool);
+                                             FALSE, ctx, subpool);
                   /* If the relocation failed because the new URL points
                      to another repository, then we need to relegate and
                      check out a new WC. */

Modified: subversion/branches/performance/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/merge.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/merge.c Sat Oct 30 14:20:17 2010
@@ -8862,6 +8862,73 @@ merge_cousins_and_supplement_mergeinfo(c
   return SVN_NO_ERROR;
 }
 
+/* Perform checks to determine whether of the working copy at TARGET_ABSPATH
+ * can safely be used as a merge target. Checks are performed according to
+ * the ALLOW_MIXED_REV, ALLOW_LOCAL_MODS, and ALLOW_SWITCHED_SUBTREES
+ * parameters. If any checks fail, raise SVN_ERR_CLIENT_NOT_READY_TO_MERGE.
+ *
+ * E.g. if all the ALLOW_* parameters are FALSE, TARGET_ABSPATH must
+ * be a single-revision, pristine, unswitched working copy.
+ * In other words, it must reflect a subtree of the repostiory as found
+ * at single revision -- although sparse checkouts are permitted. */
+static svn_error_t *
+ensure_wc_is_suitable_merge_target(const char *target_abspath,
+                                   svn_client_ctx_t *ctx,
+                                   svn_boolean_t allow_mixed_rev,
+                                   svn_boolean_t allow_local_mods,
+                                   svn_boolean_t allow_switched_subtrees,
+                                   apr_pool_t *scratch_pool)
+{
+  svn_wc_revision_status_t *wc_stat;
+
+  /* Avoid the following status crawl if we don't need it. */
+  if (allow_mixed_rev && allow_local_mods && allow_switched_subtrees)
+    return SVN_NO_ERROR;
+
+  /* Get a WC summary with min/max revisions set to the BASE revision. */
+  SVN_ERR(svn_wc_revision_status2(&wc_stat, ctx->wc_ctx, target_abspath, NULL,
+                                  FALSE, ctx->cancel_func, ctx->cancel_baton,
+                                  scratch_pool, scratch_pool));
+
+  if (! allow_switched_subtrees && wc_stat->switched)
+    return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+                            _("Cannot merge into a working copy "
+                              "with a switched subtree"));
+
+  if (! allow_local_mods && wc_stat->modified)
+    return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+                            _("Cannot merge into a working copy "
+                              "that has local modifications"));
+
+  if (! allow_mixed_rev)
+    {
+      if (! (SVN_IS_VALID_REVNUM(wc_stat->min_rev)
+             && SVN_IS_VALID_REVNUM(wc_stat->max_rev)))
+        {
+          svn_boolean_t is_added;
+
+          /* Allow merge into added nodes. */
+          SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, target_abspath,
+                                        scratch_pool));
+          if (is_added)
+            return SVN_NO_ERROR;
+          else
+            return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+                                    _("Cannot determine revision of working "
+                                      "copy"));
+        }
+
+      if (wc_stat->min_rev != wc_stat->max_rev)
+        return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+                                 _("Cannot merge into mixed-revision working "
+                                   "copy [%lu:%lu]; try updating first"),
+                                   wc_stat->min_rev, wc_stat->max_rev);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 /*-----------------------------------------------------------------------*/
 
 /*** Public APIs ***/
@@ -8877,6 +8944,7 @@ merge_locked(const char *source1,
              svn_boolean_t force,
              svn_boolean_t record_only,
              svn_boolean_t dry_run,
+             svn_boolean_t allow_mixed_rev,
              const apr_array_header_t *merge_options,
              svn_client_ctx_t *ctx,
              apr_pool_t *scratch_pool)
@@ -8952,6 +9020,12 @@ merge_locked(const char *source1,
                               _("Merge target '%s' does not exist in the "
                                 "working copy"), target_abspath));
 
+
+  /* Do not allow merges into mixed-revision working copies. */
+  SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+                                             allow_mixed_rev, TRUE, TRUE,
+                                             scratch_pool));
+
   /* Determine the working copy target's repository root URL. */
   working_rev.kind = svn_opt_revision_working;
   SVN_ERR(svn_client__get_repos_root(&wc_repos_root, target_abspath,
@@ -9150,6 +9224,7 @@ struct merge_baton {
   svn_boolean_t force;
   svn_boolean_t record_only;
   svn_boolean_t dry_run;
+  svn_boolean_t allow_mixed_rev;
   const apr_array_header_t *merge_options;
   svn_client_ctx_t *ctx;
 };
@@ -9163,7 +9238,8 @@ merge_cb(void *baton, apr_pool_t *result
   SVN_ERR(merge_locked(b->source1, b->revision1, b->source2, b->revision2,
                        b->target_abspath, b->depth, b->ignore_ancestry,
                        b->force, b->record_only, b->dry_run,
-                       b->merge_options, b->ctx, scratch_pool));
+                       b->allow_mixed_rev, b->merge_options, b->ctx,
+                       scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -9191,7 +9267,7 @@ get_target_and_lock_abspath(const char *
 }
 
 svn_error_t *
-svn_client_merge3(const char *source1,
+svn_client_merge4(const char *source1,
                   const svn_opt_revision_t *revision1,
                   const char *source2,
                   const svn_opt_revision_t *revision2,
@@ -9201,6 +9277,7 @@ svn_client_merge3(const char *source1,
                   svn_boolean_t force,
                   svn_boolean_t record_only,
                   svn_boolean_t dry_run,
+                  svn_boolean_t allow_mixed_rev,
                   const apr_array_header_t *merge_options,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
@@ -9221,6 +9298,7 @@ svn_client_merge3(const char *source1,
   baton.force = force;
   baton.record_only = record_only;
   baton.dry_run = dry_run;
+  baton.allow_mixed_rev = allow_mixed_rev;
   baton.merge_options = merge_options;
   baton.ctx = ctx;
 
@@ -9235,45 +9313,6 @@ svn_client_merge3(const char *source1,
 }
 
 
-/* If TARGET_WCPATH does not reflect a single-revision, pristine,
-   unswitched working copy -- in other words, a subtree found in a
-   single revision (although sparse checkouts are permitted) -- raise
-   SVN_ERR_CLIENT_NOT_READY_TO_MERGE. */
-static svn_error_t *
-ensure_wc_reflects_repository_subtree(const char *target_abspath,
-                                      svn_client_ctx_t *ctx,
-                                      apr_pool_t *scratch_pool)
-{
-  svn_wc_revision_status_t *wc_stat;
-
-  /* Get a WC summary with min/max revisions set to the BASE revision. */
-  SVN_ERR(svn_wc_revision_status2(&wc_stat, ctx->wc_ctx, target_abspath, NULL,
-                                  FALSE, ctx->cancel_func, ctx->cancel_baton,
-                                  scratch_pool, scratch_pool));
-
-  if (wc_stat->switched)
-    return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
-                            _("Cannot reintegrate into a working copy "
-                              "with a switched subtree"));
-
-  if (wc_stat->modified)
-    return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
-                            _("Cannot reintegrate into a working copy "
-                              "that has local modifications"));
-
-  if (! (SVN_IS_VALID_REVNUM(wc_stat->min_rev)
-         && SVN_IS_VALID_REVNUM(wc_stat->max_rev)))
-    return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
-                            _("Cannot determine revision of working copy"));
-
-  if (wc_stat->min_rev != wc_stat->max_rev)
-    return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
-                            _("Cannot reintegrate into mixed-revision "
-                              "working copy; try updating first"));
-
-  return SVN_NO_ERROR;
-}
-
 /* Check if mergeinfo for a given path is described explicitly or via
    inheritance in a mergeinfo catalog.
 
@@ -10221,8 +10260,11 @@ merge_reintegrate_locked(const char *sou
                              svn_dirent_local_style(target_abspath,
                                                     scratch_pool));
 
-  SVN_ERR(ensure_wc_reflects_repository_subtree(target_abspath, ctx,
-                                                scratch_pool));
+  /* A reintegrate merge requires the merge target to reflect a subtree
+   * of the repository as found at a single revision. */
+  SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+                                             FALSE, FALSE, FALSE,
+                                             scratch_pool));
   SVN_ERR(svn_wc__node_get_base_rev(&target_base_rev, ctx->wc_ctx,
                                     target_abspath, scratch_pool));
 
@@ -10438,6 +10480,7 @@ merge_peg_locked(const char *source,
                  svn_boolean_t force,
                  svn_boolean_t record_only,
                  svn_boolean_t dry_run,
+                 svn_boolean_t allow_mixed_rev,
                  const apr_array_header_t *merge_options,
                  svn_client_ctx_t *ctx,
                  apr_pool_t *scratch_pool)
@@ -10479,6 +10522,10 @@ merge_peg_locked(const char *source,
                               _("Merge target '%s' does not exist in the "
                                 "working copy"), target_abspath));
 
+  SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+                                             allow_mixed_rev, TRUE, TRUE,
+                                             scratch_pool));
+
   /* Determine the working copy target's repository root URL. */
   working_rev.kind = svn_opt_revision_working;
   SVN_ERR(svn_client__get_repos_root(&wc_repos_root, target_abspath,
@@ -10541,6 +10588,7 @@ struct merge_peg_baton {
   svn_boolean_t force;
   svn_boolean_t record_only;
   svn_boolean_t dry_run;
+  svn_boolean_t allow_mixed_rev;
   const apr_array_header_t *merge_options;
   svn_client_ctx_t *ctx;
 };
@@ -10554,13 +10602,14 @@ merge_peg_cb(void *baton, apr_pool_t *re
   SVN_ERR(merge_peg_locked(b->source, b->ranges_to_merge, b->peg_revision,
                            b->target_abspath, b->depth, b->ignore_ancestry,
                            b->force, b->record_only, b->dry_run,
-                           b->merge_options, b->ctx, scratch_pool));
+                           b->allow_mixed_rev, b->merge_options, b->ctx,
+                           scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_client_merge_peg3(const char *source,
+svn_client_merge_peg4(const char *source,
                       const apr_array_header_t *ranges_to_merge,
                       const svn_opt_revision_t *peg_revision,
                       const char *target_wcpath,
@@ -10569,6 +10618,7 @@ svn_client_merge_peg3(const char *source
                       svn_boolean_t force,
                       svn_boolean_t record_only,
                       svn_boolean_t dry_run,
+                      svn_boolean_t allow_mixed_rev,
                       const apr_array_header_t *merge_options,
                       svn_client_ctx_t *ctx,
                       apr_pool_t *pool)
@@ -10592,6 +10642,7 @@ svn_client_merge_peg3(const char *source
   baton.force = force;
   baton.record_only = record_only;
   baton.dry_run = dry_run;
+  baton.allow_mixed_rev = allow_mixed_rev;
   baton.merge_options = merge_options;
   baton.ctx = ctx;
 

Modified: subversion/branches/performance/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/patch.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/patch.c Sat Oct 30 14:20:17 2010
@@ -346,9 +346,7 @@ resolve_target_path(patch_target_t *targ
   target->canon_path_from_patchfile = svn_dirent_internal_style(
                                         path_from_patchfile, result_pool);
 
-  /* We allow properties to be set on the wc root dir.
-   * ### Do we need to check for empty paths here, shouldn't the parser
-   * ### guarentee that the paths returned are non-empty? */
+  /* We allow properties to be set on the wc root dir. */
   if (! prop_changes_only && target->canon_path_from_patchfile[0] == '\0')
     {
       /* An empty patch target path? What gives? Skip this. */
@@ -498,7 +496,7 @@ init_prop_target(prop_patch_target_t **p
   new_prop_target->content_info = content_info;
 
   err = svn_wc_prop_get2(&value, wc_ctx, local_abspath, prop_name, 
-                           result_pool, scratch_pool);
+                         result_pool, scratch_pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
@@ -528,12 +526,40 @@ init_prop_target(prop_patch_target_t **p
   return SVN_NO_ERROR;
 }
 
+/* Return a suitable filename for the target of PATCH.
+ * Examine the ``old'' and ``new'' file names, and choose the file name
+ * with the fewest path components, the shortest basename, and the shortest
+ * total file name length (in that order). In case of a tie, return the new
+ * filename. This heuristic is also used by Larry Wall's UNIX patch (except
+ * that it prompts for a filename in case of a tie). */
+static const char *
+choose_target_filename(const svn_patch_t *patch)
+{
+  apr_size_t old;
+  apr_size_t new;
+
+  old = svn_path_component_count(patch->old_filename);
+  new = svn_path_component_count(patch->new_filename);
+
+  if (old == new)
+    {
+      old = strlen(svn_dirent_basename(patch->old_filename, NULL));
+      new = strlen(svn_dirent_basename(patch->new_filename, NULL));
+
+      if (old == new)
+        {
+          old = strlen(patch->old_filename);
+          new = strlen(patch->new_filename);
+        }
+    }
+
+  return (old < new) ? patch->old_filename : patch->new_filename;
+}
+
 /* Attempt to initialize a *PATCH_TARGET structure for a target file
  * described by PATCH. Use working copy context WC_CTX.
  * STRIP_COUNT specifies the number of leading path components
  * which should be stripped from target paths in the patch.
- * OLD_PATCH_TARGET_NAMES indicates whether the old target's name parsed
- * from the patch file should be preferred over the new target's name.
  * The patch target structure is allocated in RESULT_POOL, but if the target
  * should be skipped, PATCH_TARGET->SKIPPED is set and the target should be
  * treated as not fully initialized, e.g. the caller should not not do any
@@ -545,9 +571,7 @@ static svn_error_t *
 init_patch_target(patch_target_t **patch_target,
                   const svn_patch_t *patch,
                   const char *base_dir,
-                  svn_wc_context_t *wc_ctx,
-                  int strip_count,
-                  svn_boolean_t old_patch_target_names,
+                  svn_wc_context_t *wc_ctx, int strip_count,
                   svn_boolean_t remove_tempfiles,
                   apr_pool_t *result_pool, apr_pool_t *scratch_pool)
 {
@@ -593,8 +617,7 @@ init_patch_target(patch_target_t **patch
   target->prop_targets = apr_hash_make(result_pool);
   target->pool = result_pool;
 
-  SVN_ERR(resolve_target_path(target, old_patch_target_names ?
-                                patch->old_filename : patch->new_filename,
+  SVN_ERR(resolve_target_path(target, choose_target_filename(patch),
                               base_dir, strip_count, prop_changes_only,
                               wc_ctx, result_pool, scratch_pool));
   if (! target->skipped)
@@ -1270,12 +1293,13 @@ copy_lines_to_target(target_content_info
   return SVN_NO_ERROR;
 }
 
-/* Write the diff text of the hunk described by HI to the
- * reject stream of CONTENT_INFO, and mark TARGET as having had rejects.
+/* Write the diff text of HUNK to the reject stream of CONTENT_INFO,
+ * and mark TARGET as having had rejects.
  * Do temporary allocations in POOL. */
 static svn_error_t *
 reject_hunk(patch_target_t *target, target_content_info_t *content_info, 
-            hunk_info_t *hi, const char *prop_name, apr_pool_t *pool)
+            const svn_diff_hunk_t *hunk, const char *prop_name,
+            apr_pool_t *pool)
 {
   const char *hunk_header;
   apr_size_t len;
@@ -1296,18 +1320,18 @@ reject_hunk(patch_target_t *target, targ
       /* ### What about just setting a variable to either "@@" or "##",
        * ### and merging with the else clause below? */
       hunk_header = apr_psprintf(pool, "## -%lu,%lu +%lu,%lu ##%s",
-                                 svn_diff_hunk_get_original_start(hi->hunk),
-                                 svn_diff_hunk_get_original_length(hi->hunk),
-                                 svn_diff_hunk_get_modified_start(hi->hunk),
-                                 svn_diff_hunk_get_modified_length(hi->hunk),
+                                 svn_diff_hunk_get_original_start(hunk),
+                                 svn_diff_hunk_get_original_length(hunk),
+                                 svn_diff_hunk_get_modified_start(hunk),
+                                 svn_diff_hunk_get_modified_length(hunk),
                                  APR_EOL_STR);
     }
   else
     hunk_header = apr_psprintf(pool, "@@ -%lu,%lu +%lu,%lu @@%s",
-                               svn_diff_hunk_get_original_start(hi->hunk),
-                               svn_diff_hunk_get_original_length(hi->hunk),
-                               svn_diff_hunk_get_modified_start(hi->hunk),
-                               svn_diff_hunk_get_modified_length(hi->hunk),
+                               svn_diff_hunk_get_original_start(hunk),
+                               svn_diff_hunk_get_original_length(hunk),
+                               svn_diff_hunk_get_modified_start(hunk),
+                               svn_diff_hunk_get_modified_length(hunk),
                                APR_EOL_STR);
   len = strlen(hunk_header);
   SVN_ERR(svn_stream_write(content_info->reject, hunk_header, &len));
@@ -1320,7 +1344,7 @@ reject_hunk(patch_target_t *target, targ
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_diff_hunk_readline_diff_text(hi->hunk, &hunk_line, &eol_str,
+      SVN_ERR(svn_diff_hunk_readline_diff_text(hunk, &hunk_line, &eol_str,
                                                &eof, iterpool, iterpool));
       if (! eof)
         {
@@ -1384,7 +1408,7 @@ apply_hunk(patch_target_t *target, targe
         {
           /* Seek failed, reject this hunk. */
           hi->rejected = TRUE;
-          SVN_ERR(reject_hunk(target, content_info, hi, prop_name, pool));
+          SVN_ERR(reject_hunk(target, content_info, hi->hunk, prop_name, pool));
           return SVN_NO_ERROR;
         }
     }
@@ -1595,31 +1619,30 @@ close_target_streams(const patch_target_
   apr_hash_index_t *hi;
   target_content_info_t *prop_content_info;
 
-   /* First the streams belonging to properties .. */
-      for (hi = apr_hash_first(pool, target->prop_targets);
-           hi;
-           hi = apr_hash_next(hi))
-        {
-          prop_patch_target_t *prop_target;
-          prop_target = svn__apr_hash_index_val(hi);
-          prop_content_info = prop_target->content_info;
-
-          /* ### If the prop did not exist pre-patching we'll not have a
-           * ### stream to read from. Find a better way to store info on
-           * ### the existence of the target prop. */
-          if (prop_content_info->stream)
-            SVN_ERR(svn_stream_close(prop_content_info->stream));
+  /* First the streams belonging to properties .. */
+  for (hi = apr_hash_first(pool, target->prop_targets);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      prop_patch_target_t *prop_target;
+      prop_target = svn__apr_hash_index_val(hi);
+      prop_content_info = prop_target->content_info;
 
-          SVN_ERR(svn_stream_close(prop_content_info->patched));
-        }
+      /* ### If the prop did not exist pre-patching we'll not have a
+       * ### stream to read from. Find a better way to store info on
+       * ### the existence of the target prop. */
+      if (prop_content_info->stream)
+        SVN_ERR(svn_stream_close(prop_content_info->stream));
 
+      SVN_ERR(svn_stream_close(prop_content_info->patched));
+    }
 
-   /* .. And then streams associted with the file. The reject stream is
-    * shared between all target_content_info structures. */
+  /* .. and then streams associated with the file.
+   * ### We're not closing the reject stream -- it still needed and
+   * ### will be closed later in write_out_rejected_hunks(). */
   if (target->kind_on_disk == svn_node_file)
     SVN_ERR(svn_stream_close(target->content_info->stream));
   SVN_ERR(svn_stream_close(target->content_info->patched));
-  SVN_ERR(svn_stream_close(target->content_info->reject));
 
   return SVN_NO_ERROR;
 }
@@ -1630,8 +1653,6 @@ close_target_streams(const patch_target_
  * in RESULT_POOL. Use WC_CTX as the working copy context.
  * STRIP_COUNT specifies the number of leading path components
  * which should be stripped from target paths in the patch.
- * OLD_PATCH_TARGET_NAMES indicates whether the old filename parsed
- * from the patch file should be preferred over the new filename.
  * REMOVE_TEMPFILES, PATCH_FUNC, and PATCH_BATON as in svn_client_patch().
  * IGNORE_WHITESPACE tells whether whitespace should be considered when
  * doing the matching.
@@ -1641,7 +1662,6 @@ static svn_error_t *
 apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch,
                 const char *abs_wc_path, svn_wc_context_t *wc_ctx,
                 int strip_count,
-                svn_boolean_t old_patch_target_names,
                 svn_boolean_t ignore_whitespace,
                 svn_boolean_t remove_tempfiles,
                 svn_client_patch_func_t patch_func,
@@ -1656,8 +1676,7 @@ apply_one_patch(patch_target_t **patch_t
   static const int MAX_FUZZ = 2;
   apr_hash_index_t *hash_index;
 
-  SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx,
-                            strip_count, old_patch_target_names,
+  SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count,
                             remove_tempfiles, result_pool, scratch_pool));
   if (target->skipped)
     {
@@ -1720,7 +1739,7 @@ apply_one_patch(patch_target_t **patch_t
       if (hi->already_applied)
         continue;
       else if (hi->rejected)
-        SVN_ERR(reject_hunk(target, target->content_info, hi,
+        SVN_ERR(reject_hunk(target, target->content_info, hi->hunk,
                             NULL /* prop_name */, 
                             iterpool));
       else
@@ -1809,7 +1828,7 @@ apply_one_patch(patch_target_t **patch_t
           if (hi->already_applied)
             continue;
           else if (hi->rejected)
-            SVN_ERR(reject_hunk(target, prop_target->content_info, hi,
+            SVN_ERR(reject_hunk(target, prop_target->content_info, hi->hunk,
                                 prop_target->name,
                                 iterpool));
           else
@@ -2129,6 +2148,8 @@ write_out_rejected_hunks(patch_target_t 
                          svn_boolean_t dry_run,
                          apr_pool_t *pool)
 {
+  SVN_ERR(svn_stream_close(target->content_info->reject));
+
   if (! dry_run && (target->had_rejects || target->had_prop_rejects))
     {
       /* Write out rejected hunks, if any. */
@@ -2152,14 +2173,6 @@ install_patched_prop_targets(patch_targe
   apr_hash_index_t *hi;
   apr_pool_t *iterpool;
 
-  if (dry_run)
-    {
-      if (! target->has_text_changes && target->kind_on_disk == svn_node_none)
-        target->added = TRUE;
-
-      return SVN_NO_ERROR;
-    }
-
   iterpool = svn_pool_create(scratch_pool);
 
   for (hi = apr_hash_first(scratch_pool, target->prop_targets);
@@ -2171,19 +2184,22 @@ install_patched_prop_targets(patch_targe
       svn_stream_t *patched_stream;
       svn_stringbuf_t *line;
       svn_stringbuf_t *prop_content;
+      const svn_string_t *prop_val;
       const char *eol_str;
       svn_boolean_t eof;
+      svn_error_t *err;
 
       svn_pool_clear(iterpool);
 
       /* For a deleted prop we only set the value to NULL. */
       if (prop_target->operation == svn_diff_op_deleted)
         {
-          SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
-                                   prop_target->name, NULL, 
-                                   TRUE /* skip_checks */,
-                                   NULL, NULL, /* suppress notification */
-                                   iterpool));
+          if (! dry_run)
+            SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
+                                     prop_target->name, NULL, 
+                                     TRUE /* skip_checks */,
+                                     NULL, NULL, /* suppress notification */
+                                     iterpool));
           continue;
         }
 
@@ -2227,28 +2243,72 @@ install_patched_prop_targets(patch_targe
           && target->kind_on_disk == svn_node_none
           && ! target->added)
         {
-          SVN_ERR(svn_io_file_create(target->local_abspath, "", scratch_pool));
-          SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
-                                       ctx->cancel_func, ctx->cancel_baton,
-                                       NULL, NULL, /* suppress notification */
-                                       iterpool));
+          if (! dry_run)
+            {
+              SVN_ERR(svn_io_file_create(target->local_abspath, "",
+                                         scratch_pool));
+              SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
+                                           ctx->cancel_func, ctx->cancel_baton,
+                                           /* suppress notification */
+                                           NULL, NULL,
+                                           iterpool));
+            }
           target->added = TRUE;
         }
 
-      /* ### How should we handle SVN_ERR_ILLEGAL_TARGET and
-       * ### SVN_ERR_BAD_MIME_TYPE?
-       *
-       * ### stsp: I'd say reject the property hunk.
-       * ###       We should verify all modified prop hunk texts using
-       * ###       svn_wc_canonicalize_svn_prop() before starting the
-       * ###       patching process, to reject them as early as possible. */
-      SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
-                               prop_target->name,
-                               svn_string_create_from_buf(prop_content, 
-                                                          iterpool),
-                               TRUE /* skip_checks */,
-                               NULL, NULL,
-                               iterpool));
+      /* Attempt to set the property, and reject all hunks if this fails. */
+      prop_val = svn_string_create_from_buf(prop_content, iterpool);
+      if (dry_run)
+        {
+          const svn_string_t *canon_propval;
+
+          err = svn_wc_canonicalize_svn_prop(&canon_propval,
+                                             prop_target->name,
+                                             prop_val, target->local_abspath,
+                                             target->db_kind,
+                                             TRUE, /* ### Skipping checks */
+                                             NULL, NULL,
+                                             iterpool);
+        }
+      else
+        {
+          err = (svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
+                                  prop_target->name, prop_val,
+                                  TRUE, /* ### Skipping checks */
+                                  NULL, NULL,
+                                  iterpool));
+        }
+
+      if (err)
+        {
+          /* ### The errors which svn_wc_canonicalize_svn_prop() will
+           * ### return aren't documented. */
+          if (err->apr_err == SVN_ERR_ILLEGAL_TARGET ||
+              err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND ||
+              err->apr_err == SVN_ERR_IO_UNKNOWN_EOL ||
+              err->apr_err == SVN_ERR_BAD_MIME_TYPE ||
+              err->apr_err == SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION)
+            {
+              int i;
+
+              svn_error_clear(err);
+
+              for (i = 0; i < prop_target->content_info->hunks->nelts; i++)
+                {
+                  hunk_info_t *hunk_info;
+
+                  hunk_info = APR_ARRAY_IDX(prop_target->content_info->hunks,
+                                            i, hunk_info_t *);
+                  hunk_info->rejected = TRUE;
+                  SVN_ERR(reject_hunk(target, prop_target->content_info,
+                                      hunk_info->hunk, prop_target->name,
+                                      iterpool));
+                }
+            }
+          else
+            return svn_error_return(err);
+        }
+
     }
 
   svn_pool_destroy(iterpool);
@@ -2535,9 +2595,6 @@ typedef struct {
   /* Number of leading components to strip from patch target paths. */
   int strip_count;
 
-  /* Whether to use the old path from the patch file instead of the new one. */
-  svn_boolean_t old_patch_target_names;
-
   /* Whether to apply the patch in reverse. */
   svn_boolean_t reverse;
 
@@ -2603,7 +2660,6 @@ apply_patches(void *baton,
 
           SVN_ERR(apply_one_patch(&target, patch, btn->abs_wc_path,
                                   btn->ctx->wc_ctx, btn->strip_count,
-                                  btn->old_patch_target_names,
                                   btn->ignore_whitespace,
                                   btn->remove_tempfiles,
                                   btn->patch_func, btn->patch_baton,
@@ -2661,7 +2717,6 @@ svn_client_patch(const char *patch_abspa
                  const char *local_abspath,
                  svn_boolean_t dry_run,
                  int strip_count,
-                 svn_boolean_t old_patch_target_names,
                  svn_boolean_t reverse,
                  svn_boolean_t ignore_whitespace,
                  svn_boolean_t remove_tempfiles,
@@ -2682,7 +2737,6 @@ svn_client_patch(const char *patch_abspa
   baton.dry_run = dry_run;
   baton.ctx = ctx;
   baton.strip_count = strip_count;
-  baton.old_patch_target_names = old_patch_target_names;
   baton.reverse = reverse;
   baton.ignore_whitespace = ignore_whitespace;
   baton.remove_tempfiles = remove_tempfiles;

Modified: subversion/branches/performance/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/relocate.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/relocate.c Sat Oct 30 14:20:17 2010
@@ -125,15 +125,122 @@ validator_func(void *baton,
   return SVN_NO_ERROR;
 }
 
+
+/* Callback of type svn_wc_external_update_t.  Just squirrels away an
+   svn:externals property value into BATON (which is an apr_hash_t *
+   keyed on local absolute path).  */
+static svn_error_t *
+externals_update_func(void *baton,
+                      const char *local_abspath,
+                      const svn_string_t *old_val,
+                      const svn_string_t *new_val,
+                      svn_depth_t depth,
+                      apr_pool_t *scratch_pool)
+{
+  apr_hash_t *externals_hash = baton;
+  apr_pool_t *hash_pool = apr_hash_pool_get(externals_hash);
+
+  apr_hash_set(externals_hash, apr_pstrdup(hash_pool, local_abspath),
+               APR_HASH_KEY_STRING, svn_string_dup(new_val, hash_pool));
+  return SVN_NO_ERROR;
+}
+
+
+/* Callback of type svn_wc_status_func4_t.  Does nothing. */
+static svn_error_t *
+status_noop_func(void *baton,
+                 const char *local_abspath,
+                 const svn_wc_status3_t *status,
+                 apr_pool_t *scratch_pool)
+{
+  return SVN_NO_ERROR;
+}
+
+
+/* Examing the array of svn_wc_external_item2_t's EXT_DESC (parsed
+   from the svn:externals property set on LOCAL_ABSPATH) and determine
+   if the external working copies described by such should be
+   relocated as a side-effect of the relocation of their parent
+   working copy (from OLD_PARENT_REPOS_ROOT_URL to
+   NEW_PARENT_REPOS_ROOT_URL).  If so, attempt said relocation.  */
+static svn_error_t *
+relocate_externals(const char *local_abspath,
+                   apr_array_header_t *ext_desc,
+                   const char *old_parent_repos_root_url,
+                   const char *new_parent_repos_root_url,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *scratch_pool)
+{
+  const char *url;
+  apr_pool_t *iterpool;
+  int i;
+
+  SVN_ERR(svn_client_url_from_path2(&url, local_abspath, ctx,
+                                    scratch_pool, scratch_pool));
+
+  /* Parse an externals definition into an array of external items. */
+
+  iterpool = svn_pool_create(scratch_pool);
+
+  for (i = 0; i < ext_desc->nelts; i++)
+    {
+      svn_wc_external_item2_t *ext_item =
+        APR_ARRAY_IDX(ext_desc, i, svn_wc_external_item2_t *);
+      const char *target_repos_root_url;
+      const char *target_abspath;
+      
+      svn_pool_clear(iterpool);
+
+      /* If this external isn't pulled in via a relative URL, ignore
+         it.  There's no sense in relocating a working copy only to
+         have the next 'svn update' try to point it back to another
+         location. */
+      if (! ((strncmp("../", ext_item->url, 3) == 0) ||
+             (strncmp("^/", ext_item->url, 2) == 0)))
+        continue;
+
+      /* If the external working copy's not-yet-relocated repos root
+         URL matches the primary working copy's pre-relocated
+         repository root URL, try to relocate that external, too.
+         You might wonder why this check is needed, given that we're
+         already limiting ourselves to externals pulled via URLs
+         relative to their primary working copy.  Well, it's because
+         you can use "../" to "crawl up" above one repository's URL
+         space and down into another one.  */
+      SVN_ERR(svn_dirent_get_absolute(&target_abspath,
+                                      svn_dirent_join(local_abspath,
+                                                      ext_item->target_dir,
+                                                      iterpool),
+                                      iterpool));
+      SVN_ERR(svn_client_root_url_from_path(&target_repos_root_url,
+                                            target_abspath, ctx, iterpool));
+
+      if (strcmp(target_repos_root_url, old_parent_repos_root_url) == 0)
+        SVN_ERR(svn_client_relocate2(target_abspath,
+                                     old_parent_repos_root_url,
+                                     new_parent_repos_root_url,
+                                     TRUE, ctx, iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_relocate2(const char *wcroot_dir,
                      const char *from,
                      const char *to,
+                     svn_boolean_t ignore_externals,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
 {
   struct validator_baton_t vb;
   const char *local_abspath;
+  apr_hash_t *externals_hash = NULL;
+  apr_hash_index_t *hi;
+  apr_pool_t *iterpool = NULL;
+  const char *old_repos_root_url, *new_repos_root_url;
 
   /* Populate our validator callback baton, and call the relocate code. */
   vb.ctx = ctx;
@@ -142,8 +249,61 @@ svn_client_relocate2(const char *wcroot_
   vb.pool = pool;
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, wcroot_dir, pool));
+
+  /* If we're ignoring externals, just relocate and get outta here. */
+  if (ignore_externals)
+    {
+      return svn_error_return(svn_wc_relocate4(ctx->wc_ctx, local_abspath,
+                                               from, to, validator_func, &vb,
+                                               pool));
+    }
+
+  /* Fetch our current root URL. */
+  SVN_ERR(svn_client_root_url_from_path(&old_repos_root_url, local_abspath,
+                                        ctx, pool));
+
+  /* Perform the relocation. */
   SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from, to,
                            validator_func, &vb, pool));
 
+  /* Now fetch new current root URL. */
+  SVN_ERR(svn_client_root_url_from_path(&new_repos_root_url, local_abspath,
+                                        ctx, pool));
+
+  externals_hash = apr_hash_make(pool);
+
+  /* Do a status run just to harvest externals definitions. */
+  SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
+                             svn_depth_infinity, FALSE, FALSE, NULL,
+                             status_noop_func, NULL,
+                             externals_update_func, externals_hash,
+                             ctx->cancel_func, ctx->cancel_baton, pool));
+
+  /* No externals?  No problem.  We're done here. */
+  if (! apr_hash_count(externals_hash))
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(pool);
+
+  for (hi = apr_hash_first(pool, externals_hash);
+       hi != NULL;
+       hi = apr_hash_next(hi))
+    {
+      const char *this_abspath = svn__apr_hash_index_key(hi);
+      const svn_string_t *pval = svn__apr_hash_index_val(hi);
+      apr_array_header_t *ext_desc;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_wc_parse_externals_description3(&ext_desc, this_abspath,
+                                                  pval->data, FALSE,
+                                                  iterpool));
+      if (ext_desc->nelts)
+        SVN_ERR(relocate_externals(this_abspath, ext_desc, old_repos_root_url,
+                                   new_repos_root_url, ctx, iterpool));
+    }
+    
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/performance/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_diff/parse-diff.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/performance/subversion/libsvn_diff/parse-diff.c Sat Oct 30 14:20:17 2010
@@ -28,6 +28,7 @@
 #include "svn_error.h"
 #include "svn_io.h"
 #include "svn_pools.h"
+#include "svn_props.h"
 #include "svn_string.h"
 #include "svn_utf.h"
 #include "svn_dirent_uri.h"
@@ -481,19 +482,24 @@ svn_diff_hunk_readline_diff_text(const s
   return SVN_NO_ERROR;
 }
 
-/* Parse PROP_NAME from HEADER as the part after the INDICATOR line. */
+/* Parse *PROP_NAME from HEADER as the part after the INDICATOR line.
+ * Allocate *PROP_NAME in RESULT_POOL.
+ * Set *PROP_NAME to NULL if no valid property name was found. */
 static svn_error_t *
 parse_prop_name(const char **prop_name, const char *header, 
                 const char *indicator, apr_pool_t *result_pool)
 {
-  /* ### This can fail if the filename cannot be represented in the current
-   * ### locale's encoding. */
   SVN_ERR(svn_utf_cstring_to_utf8(prop_name,
                                   header + strlen(indicator),
                                   result_pool));
-
-  /* ### Are we guarenteed that there are no trailing or leading
-   * ### whitespaces in the name? */
+  if (**prop_name == '\0')
+    *prop_name = NULL;
+  else if (! svn_prop_name_is_valid(*prop_name))
+    {
+      svn_stringbuf_t *buf = svn_stringbuf_create(*prop_name, result_pool);
+      svn_stringbuf_strip_whitespace(buf);
+      *prop_name = (svn_prop_name_is_valid(buf->data) ? buf->data : NULL);
+    }
 
   return SVN_NO_ERROR;
 }
@@ -678,20 +684,23 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
           else if (starts_with(line->data, "Added: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Added: ",
-                                      result_pool));
-              *prop_operation = svn_diff_op_added;
+                                      result_pool));  
+              if (*prop_name)
+                *prop_operation = svn_diff_op_added;
             }
           else if (starts_with(line->data, "Deleted: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Deleted: ",
                                       result_pool));
-              *prop_operation = svn_diff_op_deleted;
+              if (*prop_name)
+                *prop_operation = svn_diff_op_deleted;
             }
           else if (starts_with(line->data, "Modified: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Modified: ",
                                       result_pool));
-              *prop_operation = svn_diff_op_modified;
+              if (*prop_name)
+                *prop_operation = svn_diff_op_modified;
             }
           else if (starts_with(line->data, minus)
                    || starts_with(line->data, "diff --git "))
@@ -1266,6 +1275,8 @@ svn_diff_parse_next_patch(svn_patch_t **
       const char *prop_name;
       svn_diff_operation_kind_t prop_operation;
 
+      last_prop_name = NULL;
+
       /* Parse hunks. */
       (*patch)->hunks = apr_array_make(result_pool, 10,
                                        sizeof(svn_diff_hunk_t *));

Modified: subversion/branches/performance/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/log.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/log.c Sat Oct 30 14:20:17 2010
@@ -1034,7 +1034,10 @@ send_log(svn_revnum_t rev,
    memory. */
 #define MAX_OPEN_HISTORIES 32
 
-/* Get the histories for PATHS, and store them in *HISTORIES. */
+/* Get the histories for PATHS, and store them in *HISTORIES.
+
+   If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+   repository locations as fatal -- just ignore them.  */
 static svn_error_t *
 get_path_histories(apr_array_header_t **histories,
                    svn_fs_t *fs,
@@ -1042,6 +1045,7 @@ get_path_histories(apr_array_header_t **
                    svn_revnum_t hist_start,
                    svn_revnum_t hist_end,
                    svn_boolean_t strict_node_history,
+                   svn_boolean_t ignore_missing_locations,
                    svn_repos_authz_func_t authz_read_func,
                    void *authz_read_baton,
                    apr_pool_t *pool)
@@ -1089,7 +1093,18 @@ get_path_histories(apr_array_header_t **
 
       if (i < MAX_OPEN_HISTORIES)
         {
-          SVN_ERR(svn_fs_node_history(&info->hist, root, this_path, pool));
+          svn_error_t *err;
+          err = svn_fs_node_history(&info->hist, root, this_path, pool);
+          if (err
+              && ignore_missing_locations
+              && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+                  err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
+                  err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
+            {
+              svn_error_clear(err);
+              continue;
+            }
+          SVN_ERR(err);
           info->newpool = svn_pool_create(pool);
           info->oldpool = svn_pool_create(pool);
         }
@@ -1336,6 +1351,7 @@ do_logs(svn_fs_t *fs,
         svn_boolean_t discover_changed_paths,
         svn_boolean_t strict_node_history,
         svn_boolean_t include_merged_revisions,
+        svn_boolean_t ignore_missing_locations,
         const apr_array_header_t *revprops,
         svn_boolean_t descending_order,
         svn_log_entry_receiver_t receiver,
@@ -1383,24 +1399,15 @@ handle_merged_revisions(svn_revnum_t rev
   iterpool = svn_pool_create(pool);
   for (i = combined_list->nelts - 1; i >= 0; i--)
     {
-      svn_error_t *err;
       struct path_list_range *pl_range
         = APR_ARRAY_IDX(combined_list, i, struct path_list_range *);
 
       svn_pool_clear(iterpool);
-      err = do_logs(fs, pl_range->paths, pl_range->range.start,
-                    pl_range->range.end, 0, discover_changed_paths,
-                    strict_node_history, TRUE, revprops, TRUE,
-                    receiver, receiver_baton, authz_read_func,
-                    authz_read_baton, iterpool);
-      if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
-                  err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
-                  err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
-        {
-          svn_error_clear(err);
-          continue;
-        }
-      SVN_ERR(err);
+      SVN_ERR(do_logs(fs, pl_range->paths, pl_range->range.start,
+                      pl_range->range.end, 0, discover_changed_paths,
+                      strict_node_history, TRUE, TRUE, revprops, TRUE,
+                      receiver, receiver_baton, authz_read_func,
+                      authz_read_baton, iterpool));
     }
   svn_pool_destroy(iterpool);
 
@@ -1415,6 +1422,9 @@ handle_merged_revisions(svn_revnum_t rev
    the logs back as we find them, else buffer the logs and send them back
    in youngest->oldest order.
 
+   If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+   repository locations as fatal -- just ignore them.
+
    Other parameters are the same as svn_repos_get_logs4().
  */
 static svn_error_t *
@@ -1426,6 +1436,7 @@ do_logs(svn_fs_t *fs,
         svn_boolean_t discover_changed_paths,
         svn_boolean_t strict_node_history,
         svn_boolean_t include_merged_revisions,
+        svn_boolean_t ignore_missing_locations,
         const apr_array_header_t *revprops,
         svn_boolean_t descending_order,
         svn_log_entry_receiver_t receiver,
@@ -1448,8 +1459,8 @@ do_logs(svn_fs_t *fs,
      one of our paths was changed.  So let's go figure out which
      revisions contain real changes to at least one of our paths.  */
   SVN_ERR(get_path_histories(&histories, fs, paths, hist_start, hist_end,
-                             strict_node_history, authz_read_func,
-                             authz_read_baton, pool));
+                             strict_node_history, ignore_missing_locations,
+                             authz_read_func, authz_read_baton, pool));
 
   /* Loop through all the revisions in the range and add any
      where a path was changed to the array, or if they wanted
@@ -1686,7 +1697,7 @@ svn_repos_get_logs4(svn_repos_t *repos,
 
   return do_logs(repos->fs, paths, start, end, limit,
                  discover_changed_paths, strict_node_history,
-                 include_merged_revisions, revprops, descending_order,
-                 receiver, receiver_baton,
+                 include_merged_revisions, FALSE, revprops,
+                 descending_order, receiver, receiver_baton,
                  authz_read_func, authz_read_baton, pool);
 }

Modified: subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c Sat Oct 30 14:20:17 2010
@@ -930,15 +930,6 @@ svn_wc_crawl_revisions5(svn_wc_context_t
       if (err)
         goto abort_report;
 
-      if (!parent_repos_relpath)
-        err = svn_wc__db_scan_base_repos(&parent_repos_relpath, NULL,
-                                         NULL,
-                                         db, parent_abspath,
-                                         scratch_pool, scratch_pool);
-
-      if (err)
-        goto abort_report;
-
       if (strcmp(repos_relpath,
                  svn_relpath_join(parent_repos_relpath, base,
                                   scratch_pool)) != 0)

Modified: subversion/branches/performance/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/conflicts.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/conflicts.c Sat Oct 30 14:20:17 2010
@@ -166,6 +166,8 @@ attempt_deletion(const char *parent_dir,
    ### leave, for example, one of the conflict artifact files deleted but
    ### the entry still referring to it and trying to use it for the next
    ### attempt at resolving.
+
+   ### Does this still apply in the world of WC-NG?  -hkw
 */
 static svn_error_t *
 resolve_conflict_on_node(svn_wc__db_t *db,
@@ -188,11 +190,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
 
   *did_resolve = FALSE;
 
-  SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL,
-                               db, local_abspath, pool, pool));
+  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, pool));
   SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
                                     pool, pool));
 

Modified: subversion/branches/performance/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/copy.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/copy.c Sat Oct 30 14:20:17 2010
@@ -442,10 +442,14 @@ from one valid state to another and must
 Several such changes can be batched together in a bigger txn if we don't
 want clients to be able to see intermediate states.
 
-### TODO: This plan doesn't yet provide well for notification of all copied
-    paths.
+TODO: We will probably want to notify all copied paths rather than just the
+  root path, some time in the future.  It may be difficult to get the list
+  of visited paths directly, because the metadata copying is performed
+  within a single SQL statement.  We could walk the destination tree after
+  copying, taking care to include any 'excluded' nodes but ignore any
+  'deleted' paths that may be left over from a replaced sub-tree.
 
-copy-versioned_node:
+copy_versioned_node:
   # Copy a versioned file/dir SRC_PATH to DST_PATH, recursively.
 
   # This function takes care to copy both the metadata tree and the disk
@@ -475,6 +479,68 @@ copy-versioned_node:
   #     and so subsume the destination into an existing op?  I guess not.
 
 */
+
+/* Copy a versioned file/dir SRC_PATH to DST_PATH, recursively. */
+static svn_error_t *
+copy_versioned_node(svn_wc__db_t *db,
+                    const char *src_abspath,
+                    const char *dst_abspath,
+                    svn_boolean_t metadata_only,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
+                    svn_wc_notify_func2_t notify_func,
+                    void *notify_baton,
+                    apr_pool_t *scratch_pool)
+{
+  svn_skel_t *work_item = NULL;
+
+  /* Prepare a copy of the on-disk tree (if it exists, and whatever its kind),
+   * in a temporary location. */
+  if (! metadata_only)
+    {
+      const char *tmpdir_abspath;
+      const char *tmp_dst_abspath;
+      svn_node_kind_t kind;
+
+      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
+                                             scratch_pool, scratch_pool));
+
+      SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
+                             tmpdir_abspath,
+                             TRUE, /* recursive */
+                             cancel_func, cancel_baton,
+                             scratch_pool));
+      if (tmp_dst_abspath)
+        {
+          SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
+                                             tmp_dst_abspath, dst_abspath,
+                                             scratch_pool, scratch_pool));
+        }
+    }
+
+  /* Copy single NODES row from src_path@src_op_depth to dst_path@dst_depth. */
+  /* Copy all rows of descendent paths in == src_op_depth to == dst_depth. */
+  /* Copy all rows of descendent paths in > src_depth to > dst_depth,
+     adjusting op_depth by (dst_depth - src_depth). */
+  /* Copy ACTUAL_NODE rows (props and any other actual metadata). */
+  SVN_ERR(svn_wc__db_op_copy_tree(db, src_abspath, dst_abspath,
+                                  work_item, scratch_pool));
+
+  SVN_ERR(svn_wc__wq_run(db, dst_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
+
+  /* Notify */
+  if (notify_func)
+    {
+      svn_wc_notify_t *notify
+        = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
+                               scratch_pool);
+      notify->kind = svn_node_dir;
+      (*notify_func)(notify_baton, notify, scratch_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
 #endif
 
 
@@ -494,7 +560,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
   svn_wc__db_t *db = wc_ctx->db;
   svn_wc__db_kind_t src_db_kind;
   const char *dstdir_abspath;
-  
+
   SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
   
@@ -645,6 +711,17 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
                                                         scratch_pool));
     }
 
+#ifdef SVN_WC__OP_DEPTH
+  if (svn_wc__db_same_db(db, src_abspath, dst_abspath, scratch_pool))
+    {
+      SVN_ERR(copy_versioned_node(db, src_abspath, dst_abspath,
+                                  metadata_only,
+                                  cancel_func, cancel_baton,
+                                  notify_func, notify_baton,
+                                  scratch_pool));
+    }
+  else
+#endif
   if (src_db_kind == svn_wc__db_kind_file
       || src_db_kind == svn_wc__db_kind_symlink)
     {

Modified: subversion/branches/performance/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/props.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/props.c Sat Oct 30 14:20:17 2010
@@ -1577,7 +1577,8 @@ svn_wc__merge_props(svn_wc_notify_state_
         SVN_ERR(svn_wc__wq_tmp_build_set_property_conflict_marker(
                                           &work_item,
                                           db, local_abspath,
-                                          svn_dirent_basename(reject_path, NULL),
+                                          svn_dirent_basename(reject_path,
+                                                              NULL),
                                           scratch_pool, scratch_pool));
 
         SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));