You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gb...@apache.org on 2013/10/13 18:11:00 UTC

svn commit: r1531702 [1/4] - in /subversion/branches/invoke-diff-cmd-feature: ./ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/i...

Author: gbg
Date: Sun Oct 13 16:10:59 2013
New Revision: 1531702

URL: http://svn.apache.org/r1531702
Log:
On the invoke-diff-cmd branch: Merging r1526469 through r1531700.

Added:
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/root_pools.c
      - copied unchanged from r1531700, subversion/trunk/subversion/libsvn_subr/root_pools.c
    subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/logger.c
      - copied unchanged from r1531700, subversion/trunk/subversion/svnserve/logger.c
    subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/logger.h
      - copied unchanged from r1531700, subversion/trunk/subversion/svnserve/logger.h
    subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_subr/root-pools-test.c
      - copied unchanged from r1531700, subversion/trunk/subversion/tests/libsvn_subr/root-pools-test.c
Modified:
    subversion/branches/invoke-diff-cmd-feature/   (props changed)
    subversion/branches/invoke-diff-cmd-feature/CHANGES
    subversion/branches/invoke-diff-cmd-feature/INSTALL
    subversion/branches/invoke-diff-cmd-feature/build.conf
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/CreateJ.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/InfoCallback.h
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.h
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/OperationContext.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/PatchCallback.h
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.h
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.h
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.h
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteFactory.cpp
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
    subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
    subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h
    subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_client.h
    subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_ra.h
    subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_types.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/ra.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/cached_data.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/tree.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/util.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/tree.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/client.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/ra_svn.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cache_config.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cmdline.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/deprecated.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/file.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/sorts.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/utf.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.c
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_private.h
    subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_update_move.c
    subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/cyrus_auth.c
    subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/serve.c
    subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/server.h
    subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/svnserve.c
    subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/move_tests.py
    subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/revert_tests.py
    subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_ra/ra-test.c
    subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_wc/op-depth-test.c
    subversion/branches/invoke-diff-cmd-feature/tools/dev/fsfs-access-map.c

Propchange: subversion/branches/invoke-diff-cmd-feature/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1526469-1531700

Modified: subversion/branches/invoke-diff-cmd-feature/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/CHANGES?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/CHANGES (original)
+++ subversion/branches/invoke-diff-cmd-feature/CHANGES Sun Oct 13 16:10:59 2013
@@ -20,6 +20,8 @@ http://svn.apache.org/repos/asf/subversi
   - General:
 
   - API changes:
+    * New RA callbacks for managing ra_svn tunnels:
+      svn_ra_callbacks2_t::open_tunnel and svn_ra_callbacks2_t::close_tunnel.
 
   - Bindings:
 

Modified: subversion/branches/invoke-diff-cmd-feature/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/INSTALL?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/INSTALL (original)
+++ subversion/branches/invoke-diff-cmd-feature/INSTALL Sun Oct 13 16:10:59 2013
@@ -483,7 +483,7 @@ I.    INTRODUCTION
 
       13. SQLite  (REQUIRED)
 
-      Subversion 1.7 requires SQLite version 3.6.18 or above.  You can meet
+      Subversion 1.8 requires SQLite version 3.7.12 or above.  You can meet
       this dependency several ways:
         * Use an SQLite amalgamation file.
         * Specify an SQLite installation to use.

Modified: subversion/branches/invoke-diff-cmd-feature/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/build.conf?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/build.conf (original)
+++ subversion/branches/invoke-diff-cmd-feature/build.conf Sun Oct 13 16:10:59 2013
@@ -1008,6 +1008,14 @@ sources = revision-test.c
 install = test
 libs = libsvn_test libsvn_subr apr
 
+[root-pools-test]
+description = Test time functions
+type = exe
+path = subversion/tests/libsvn_subr
+sources = root-pools-test.c
+install = test
+libs = libsvn_test libsvn_subr apriconv apr
+
 [skel-test]
 description = Test skels in libsvn_subr
 type = exe
@@ -1131,7 +1139,7 @@ type = exe
 path = subversion/tests/libsvn_ra
 sources = ra-test.c
 install = test
-libs = libsvn_test libsvn_ra libsvn_fs libsvn_delta libsvn_subr
+libs = libsvn_test libsvn_ra libsvn_ra_svn libsvn_fs libsvn_delta libsvn_subr
        apriconv apr
 
 # ----------------------------------------------------------------------------
@@ -1390,7 +1398,8 @@ libs = __ALL__
        skel-test strings-reps-test changes-test locks-test repos-test
        checksum-test compat-test config-test hashdump-test mergeinfo-test
        opt-test packed-data-test path-test prefix-string-test
-       priority-queue-test stream-test string-test time-test utf-test
+       priority-queue-test root-pools-test stream-test
+       string-test time-test utf-test
        error-test error-code-test cache-test spillbuf-test crypto-test
        named_atomic-test named_atomic-proc-test revision-test
        subst_translate-test io-test

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/CreateJ.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/CreateJ.cpp Sun Oct 13 16:10:59 2013
@@ -778,7 +778,7 @@ CreateJ::ClientNotifyInformation(const s
                                "L"JAVA_PACKAGE"/types/NodeKind;"
                                "Ljava/lang/String;"
                                "L"JAVA_PACKAGE"/types/Lock;"
-                               "Ljava/lang/String;"
+                               "Ljava/lang/String;Ljava/util/List;"
                                "L"JAVA_PACKAGE"/ClientNotifyInformation$Status;"
                                "L"JAVA_PACKAGE"/ClientNotifyInformation$Status;"
                                "L"JAVA_PACKAGE"/ClientNotifyInformation$LockStatus;"
@@ -811,7 +811,9 @@ CreateJ::ClientNotifyInformation(const s
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
-  jstring jErr = JNIUtil::makeSVNErrorMessage(wcNotify->err);
+  jstring jErr;
+  jobject jErrStack;
+  JNIUtil::makeSVNErrorMessage(wcNotify->err, &jErr, &jErrStack);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
@@ -867,7 +869,7 @@ CreateJ::ClientNotifyInformation(const s
 
   // call the Java method
   jobject jInfo = env->NewObject(clazz, midCT, jPath, jAction,
-                                 jKind, jMimeType, jLock, jErr,
+                                 jKind, jMimeType, jLock, jErr, jErrStack,
                                  jContentState, jPropState, jLockState,
                                  (jlong) wcNotify->revision, jChangelistName,
                                  jMergeRange, jpathPrefix, jpropName,

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/InfoCallback.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/InfoCallback.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/InfoCallback.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/InfoCallback.h Sun Oct 13 16:10:59 2013
@@ -30,8 +30,6 @@
 #include <jni.h>
 #include "svn_client.h"
 
-struct info_entry;
-
 /**
  * This class holds a Java callback object, which will receive every line of
  * the file for which the callback information is requested.

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.cpp Sun Oct 13 16:10:59 2013
@@ -403,16 +403,6 @@ void JNIUtil::raiseThrowable(const char 
   env->DeleteLocalRef(clazz);
 }
 
-jstring JNIUtil::makeSVNErrorMessage(svn_error_t *err)
-{
-  if (err == NULL)
-    return NULL;
-  std::string buffer;
-  assembleErrorMessage(err, 0, APR_SUCCESS, buffer);
-  jstring jmessage = makeJString(buffer.c_str());
-  return jmessage;
-}
-
 void
 JNIUtil::throwNativeException(const char *className, const char *msg,
                               const char *source, int aprErr)
@@ -514,8 +504,91 @@ JNIUtil::putErrorsInTrace(svn_error_t *e
 }
 
 namespace {
-jobject construct_Jmessage_stack(
-    const JNIUtil::error_message_stack_t& message_stack)
+struct MessageStackItem
+{
+  apr_status_t m_code;
+  std::string m_message;
+  bool m_generic;
+
+  MessageStackItem(apr_status_t code, const char* message,
+                   bool generic = false)
+    : m_code(code),
+      m_message(message),
+      m_generic(generic)
+    {}
+};
+typedef std::vector<MessageStackItem> ErrorMessageStack;
+
+/*
+ * Build the error message from the svn error into buffer.  This
+ * method iterates through all the chained errors
+ *
+ * @param err               the subversion error
+ * @param buffer            the buffer where the formated error message will
+ *                          be stored
+ * @return An array of error codes and messages
+ */
+ErrorMessageStack assemble_error_message(
+    svn_error_t *err, std::string &result)
+{
+  // buffer for a single error message
+  char errbuf[1024];
+  apr_status_t parent_apr_err = 0;
+  ErrorMessageStack message_stack;
+
+  /* Pretty-print the error */
+  /* Note: we can also log errors here someday. */
+
+  for (int depth = 0; err;
+       ++depth, parent_apr_err = err->apr_err, err = err->child)
+    {
+      /* When we're recursing, don't repeat the top-level message if its
+       * the same as before. */
+      if (depth == 0 || err->apr_err != parent_apr_err)
+        {
+          const char *message;
+          /* Is this a Subversion-specific error code? */
+          if ((err->apr_err > APR_OS_START_USEERR)
+              && (err->apr_err <= APR_OS_START_CANONERR))
+            message = svn_strerror(err->apr_err, errbuf, sizeof(errbuf));
+          /* Otherwise, this must be an APR error code. */
+          else
+            {
+              /* Messages coming from apr_strerror are in the native
+                 encoding, it's a good idea to convert them to UTF-8. */
+              apr_strerror(err->apr_err, errbuf, sizeof(errbuf));
+              svn_error_t* utf8_err =
+                svn_utf_cstring_to_utf8(&message, errbuf, err->pool);
+              if (utf8_err)
+                {
+                  /* Use fuzzy transliteration instead. */
+                  svn_error_clear(utf8_err);
+                  message = svn_utf_cstring_from_utf8_fuzzy(errbuf, err->pool);
+                }
+            }
+
+          message_stack.push_back(
+              MessageStackItem(err->apr_err, message, true));
+        }
+      if (err->message)
+        {
+          message_stack.push_back(
+              MessageStackItem(err->apr_err, err->message));
+        }
+    }
+
+  for (ErrorMessageStack::const_iterator it = message_stack.begin();
+       it != message_stack.end(); ++it)
+    {
+      if (!it->m_generic)
+        result += "svn: ";
+      result += it->m_message;
+      result += '\n';
+    }
+  return message_stack;
+}
+
+jobject construct_Jmessage_stack(const ErrorMessageStack& message_stack)
 {
   JNIEnv *env = JNIUtil::getEnv();
   env->PushLocalFrame(LOCAL_FRAME_SIZE);
@@ -544,8 +617,7 @@ jobject construct_Jmessage_stack(
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
-  for (JNIUtil::error_message_stack_t::const_iterator
-         it = message_stack.begin();
+  for (ErrorMessageStack::const_iterator it = message_stack.begin();
        it != message_stack.end(); ++it)
     {
       jobject jmessage = JNIUtil::makeJString(it->m_message.c_str());
@@ -567,12 +639,37 @@ jobject construct_Jmessage_stack(
 }
 } // anonymous namespace
 
+std::string JNIUtil::makeSVNErrorMessage(svn_error_t *err,
+                                         jstring *jerror_message,
+                                         jobject *jmessage_stack)
+{
+  if (jerror_message)
+    *jerror_message = NULL;
+  if (jmessage_stack)
+    *jmessage_stack = NULL;
+
+  std::string buffer;
+  err = svn_error_purge_tracing(err);
+  if (err == NULL || err->apr_err == 0
+      || !(jerror_message || jmessage_stack))
+  return buffer;
+
+  ErrorMessageStack message_stack = assemble_error_message(err, buffer);
+  if (jerror_message)
+    *jerror_message = makeJString(buffer.c_str());
+  if (jmessage_stack)
+    *jmessage_stack = construct_Jmessage_stack(message_stack);
+  return buffer;
+}
+
 void JNIUtil::handleSVNError(svn_error_t *err)
 {
-  std::string msg;
-  error_message_stack_t message_stack;
-  assembleErrorMessage(svn_error_purge_tracing(err),
-                       0, APR_SUCCESS, msg, &message_stack);
+  jstring jmessage;
+  jobject jstack;
+  std::string msg = makeSVNErrorMessage(err, &jmessage, &jstack);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
   const char *source = NULL;
 #ifdef SVN_DEBUG
 #ifndef SVN_ERR__TRACING
@@ -616,17 +713,10 @@ void JNIUtil::handleSVNError(svn_error_t
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
-  jstring jmessage = makeJString(msg.c_str());
-  if (isJavaExceptionThrown())
-    POP_AND_RETURN_NOTHING();
   jstring jsource = makeJString(source);
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
-  jobject jmessageStack = construct_Jmessage_stack(message_stack);
-  if (isJavaExceptionThrown())
-    POP_AND_RETURN_NOTHING();
-
   jmethodID mid = env->GetMethodID(clazz, "<init>",
                                    "(Ljava/lang/String;"
                                    "Ljava/lang/String;I"
@@ -634,7 +724,7 @@ void JNIUtil::handleSVNError(svn_error_t
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
   jobject nativeException = env->NewObject(clazz, mid, jmessage, jsource,
-                                           jint(err->apr_err), jmessageStack);
+                                           jint(err->apr_err), jstack);
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
@@ -1044,71 +1134,6 @@ jbyteArray JNIUtil::makeJByteArray(const
 }
 
 /**
- * Build the error message from the svn error into buffer.  This
- * method calls itselft recursively for all the chained errors
- *
- * @param err               the subversion error
- * @param depth             the depth of the call, used for formating
- * @param parent_apr_err    the apr of the previous level, used for formating
- * @param buffer            the buffer where the formated error message will
- *                          be stored
- * @param message_stack     an array of error codes and messages
- */
-void JNIUtil::assembleErrorMessage(svn_error_t *err, int depth,
-                                   apr_status_t parent_apr_err,
-                                   std::string &buffer,
-                                   error_message_stack_t* message_stack)
-{
-  // buffer for a single error message
-  char errbuf[1024];
-
-  /* Pretty-print the error */
-  /* Note: we can also log errors here someday. */
-
-  /* When we're recursing, don't repeat the top-level message if its
-   * the same as before. */
-  if (depth == 0 || err->apr_err != parent_apr_err)
-    {
-      const char *message;
-      /* Is this a Subversion-specific error code? */
-      if ((err->apr_err > APR_OS_START_USEERR)
-          && (err->apr_err <= APR_OS_START_CANONERR))
-        message = svn_strerror(err->apr_err, errbuf, sizeof(errbuf));
-      /* Otherwise, this must be an APR error code. */
-      else
-        {
-          /* Messages coming from apr_strerror are in the native
-             encoding, it's a good idea to convert them to UTF-8. */
-          apr_strerror(err->apr_err, errbuf, sizeof(errbuf));
-          svn_error_t* utf8_err =
-            svn_utf_cstring_to_utf8(&message, errbuf, err->pool);
-          if (utf8_err)
-            {
-              /* Use fuzzy transliteration instead. */
-              svn_error_clear(utf8_err);
-              message = svn_utf_cstring_from_utf8_fuzzy(errbuf, err->pool);
-            }
-        }
-
-      if (message_stack)
-        message_stack->push_back(
-            message_stack_item(err->apr_err, message, true));
-      buffer.append(message);
-      buffer.append("\n");
-    }
-  if (err->message)
-    {
-      if (message_stack)
-        message_stack->push_back(
-            message_stack_item(err->apr_err, err->message));
-      buffer.append(_("svn: ")).append(err->message).append("\n");
-    }
-
-  if (err->child)
-    assembleErrorMessage(err->child, depth + 1, err->apr_err, buffer);
-}
-
-/**
  * Throw a Java NullPointerException.  Used when input parameters
  * which should not be null are that.
  *

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/JNIUtil.h Sun Oct 13 16:10:59 2013
@@ -122,7 +122,9 @@ class JNIUtil
    */
   static void handleSVNError(svn_error_t *err);
 
-  static jstring makeSVNErrorMessage(svn_error_t *err);
+  static std::string makeSVNErrorMessage(svn_error_t *err,
+                                         jstring *jerror_message,
+                                         jobject *jmessage_stack);
 
   /**
    * Create and throw a java.lang.Throwable instance.
@@ -150,31 +152,12 @@ class JNIUtil
   enum { formatBufferSize = 2048 };
   enum { noLog, errorLog, exceptionLog, entryLog } LogLevel;
 
-  struct message_stack_item
-  {
-    apr_status_t m_code;
-    std::string m_message;
-    bool m_generic;
-
-    message_stack_item(apr_status_t code, const char* message,
-                       bool generic = false)
-      : m_code(code),
-        m_message(message),
-        m_generic(generic)
-      {}
-  };
-  typedef std::vector<message_stack_item> error_message_stack_t;
-
   /**
    * Mutex that secures the global configuration object.
    */
   static JNIMutex *g_configMutex;
 
  private:
-  static void assembleErrorMessage(svn_error_t *err, int depth,
-                                   apr_status_t parent_apr_err,
-                                   std::string &buffer,
-                                   error_message_stack_t* message_stack = NULL);
   static void putErrorsInTrace(svn_error_t *err,
                                std::vector<jobject> &stackTrace);
   /**

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/OperationContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/OperationContext.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/OperationContext.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/OperationContext.cpp Sun Oct 13 16:10:59 2013
@@ -328,6 +328,9 @@ OperationContext::progress(apr_off_t pro
     apr_pool_t *pool)
 {
   jobject jctx = (jobject) baton;
+  if (!jctx)
+    return;
+
   JNIEnv *env = JNIUtil::getEnv();
 
   // Create a local frame for our references

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/PatchCallback.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/PatchCallback.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/PatchCallback.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/PatchCallback.h Sun Oct 13 16:10:59 2013
@@ -30,8 +30,6 @@
 #include <jni.h>
 #include "svn_client.h"
 
-struct info_entry;
-
 /**
  * This class holds a Java callback object, which will receive every line of
  * the file for which the callback information is requested.

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.cpp Sun Oct 13 16:10:59 2013
@@ -137,17 +137,51 @@ RemoteSession::open(jint jretryAttempts,
       initialized = true;
     }
 
-  jobject jthis_out = NULL;
   RemoteSession* session = new RemoteSession(
-      &jthis_out, jretryAttempts, url, uuid,
-      configDirectory,
-      usernameStr, passwordStr, prompter, jprogress);
+      jretryAttempts, url, uuid, configDirectory,
+      usernameStr, passwordStr, prompter);
   if (JNIUtil::isJavaExceptionThrown() || !session)
     {
       delete session;
-      jthis_out = NULL;
+      return NULL;
     }
-  return jthis_out;
+
+  // Create java session object
+  JNIEnv *env = JNIUtil::getEnv();
+
+  jclass clazz = env->FindClass(JAVA_CLASS_REMOTE_SESSION);
+  if (JNIUtil::isJavaExceptionThrown())
+    {
+      delete session;
+      return NULL;
+    }
+
+  static jmethodID ctor = 0;
+  if (ctor == 0)
+    {
+      ctor = env->GetMethodID(clazz, "<init>", "(J)V");
+      if (JNIUtil::isJavaExceptionThrown())
+        {
+          delete session;
+          return NULL;
+        }
+    }
+
+  jobject jremoteSession = env->NewObject(clazz, ctor, session->getCppAddr());
+  if (JNIUtil::isJavaExceptionThrown())
+    {
+      delete session;
+      return NULL;
+    }
+
+  session->m_context->activate(jremoteSession, jprogress);
+  if (JNIUtil::isJavaExceptionThrown())
+    {
+      delete session;
+      jremoteSession = NULL;
+    }
+
+  return jremoteSession;
 }
 
 
@@ -163,37 +197,15 @@ namespace{
   typedef std::pair<attempt_set::iterator, bool> attempt_insert;
 } // anonymous namespace
 
-RemoteSession::RemoteSession(jobject* jthis_out, int retryAttempts,
+RemoteSession::RemoteSession(int retryAttempts,
                              const char* url, const char* uuid,
                              const char* configDirectory,
                              const char*  username, const char*  password,
-                             Prompter*& prompter, jobject jprogress)
+                             Prompter*& prompter)
   : m_session(NULL), m_context(NULL)
 {
-  // Create java session object
-  JNIEnv *env = JNIUtil::getEnv();
-
-  jclass clazz = env->FindClass(JAVA_CLASS_REMOTE_SESSION);
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
-
-  static jmethodID ctor = 0;
-  if (ctor == 0)
-    {
-      ctor = env->GetMethodID(clazz, "<init>", "(J)V");
-      if (JNIUtil::isJavaExceptionThrown())
-        return;
-    }
-
-  jlong cppAddr = this->getCppAddr();
-
-  jobject jremoteSession = env->NewObject(clazz, ctor, cppAddr);
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
-
   m_context = new RemoteSessionContext(
-      jremoteSession, pool, configDirectory,
-      username, password, prompter, jprogress);
+      pool, configDirectory, username, password, prompter);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -232,6 +244,8 @@ RemoteSession::RemoteSession(jobject* jt
 
   if (cycle_detected)
     {
+      JNIEnv *env = JNIUtil::getEnv();
+
       jstring exmsg = JNIUtil::makeJString(
           apr_psprintf(pool.getPool(),
                        _("Redirect cycle detected for URL '%s'"),
@@ -257,6 +271,8 @@ RemoteSession::RemoteSession(jobject* jt
 
   if (corrected_url)
     {
+      JNIEnv *env = JNIUtil::getEnv();
+
       jstring exmsg = JNIUtil::makeJString(_("Too many redirects"));
       if (JNIUtil::isJavaExceptionThrown())
         return;
@@ -282,8 +298,6 @@ RemoteSession::RemoteSession(jobject* jt
       env->Throw(static_cast<jthrowable>(ex));
       return;
     }
-
-  *jthis_out = jremoteSession;
 }
 
 RemoteSession::~RemoteSession()

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSession.h Sun Oct 13 16:10:59 2013
@@ -113,11 +113,11 @@ class RemoteSession : public SVNBase
 
   private:
     friend class CommitEditor;
-    RemoteSession(jobject*, int retryAttempts,
+    RemoteSession(int retryAttempts,
                   const char* url, const char* uuid,
                   const char* configDirectory,
                   const char* username, const char* password,
-                  Prompter*& prompter, jobject jprogress);
+                  Prompter*& prompter);
 
     svn_ra_session_t* m_session;
     RemoteSessionContext* m_context;

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.cpp Sun Oct 13 16:10:59 2013
@@ -29,13 +29,11 @@
 #include "JNIUtil.h"
 #include "Prompter.h"
 
-#define STRING_RETURN_SIGNATURE "()Ljava/lang/String;"
 
 RemoteSessionContext::RemoteSessionContext(
-    jobject contextHolder, SVN::Pool &pool,
-    const char* configDirectory,
-    const char*  usernameStr, const char*  passwordStr,
-    Prompter* prompter, jobject jprogress)
+    SVN::Pool &pool, const char* configDirectory,
+    const char* usernameStr, const char* passwordStr,
+    Prompter* prompter)
   : OperationContext(pool), m_raCallbacks(NULL)
 {
   setConfigDirectory(configDirectory);
@@ -48,32 +46,6 @@ RemoteSessionContext::RemoteSessionConte
   setPrompt(prompter);
 
   /*
-   * Attach session context java object
-   */
-  static jfieldID ctxFieldID = 0;
-  attachJavaObject(contextHolder,
-      "L"JAVA_PACKAGE"/remote/RemoteSession$RemoteSessionContext;",
-      "sessionContext", &ctxFieldID);
-
-  /*
-   * Set the progress callback
-   */
-  JNIEnv *env = JNIUtil::getEnv();
-
-  jclass clazz = env->GetObjectClass(m_jctx);
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
-
-  jmethodID mid = env->GetMethodID(
-      clazz, "setProgressCallback",
-      "(L"JAVA_PACKAGE"/callback/ProgressCallback;)V");
-  if (JNIUtil::isJavaExceptionThrown() || mid == 0)
-    return;
-
-  env->CallVoidMethod(m_jctx, mid, jprogress);
-  env->DeleteLocalRef(jprogress);
-
-  /*
    * Setup callbacks
    */
   SVN_JNI_ERR(svn_ra_create_callbacks(&m_raCallbacks, m_pool->getPool()), );
@@ -81,7 +53,7 @@ RemoteSessionContext::RemoteSessionConte
   m_raCallbacks->auth_baton = getAuthBaton(pool);
   m_raCallbacks->cancel_func = checkCancel;
   m_raCallbacks->get_client_string = clientName;
-  m_raCallbacks->progress_baton = m_jctx;
+  m_raCallbacks->progress_baton = NULL;
   m_raCallbacks->progress_func = progress;
 
   /*
@@ -102,6 +74,36 @@ RemoteSessionContext::~RemoteSessionCont
 {
 }
 
+void RemoteSessionContext::activate(jobject jremoteSession, jobject jprogress)
+{
+  /*
+   * Attach session context java object
+   */
+  static jfieldID ctxFieldID = 0;
+  attachJavaObject(jremoteSession,
+      "L"JAVA_PACKAGE"/remote/RemoteSession$RemoteSessionContext;",
+      "sessionContext", &ctxFieldID);
+
+  /*
+   * Set the progress callback
+   */
+  JNIEnv *env = JNIUtil::getEnv();
+
+  jclass clazz = env->GetObjectClass(m_jctx);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  jmethodID mid = env->GetMethodID(
+      clazz, "setProgressCallback",
+      "(L"JAVA_PACKAGE"/callback/ProgressCallback;)V");
+  if (JNIUtil::isJavaExceptionThrown() || mid == 0)
+    return;
+
+  env->CallVoidMethod(m_jctx, mid, jprogress);
+  env->DeleteLocalRef(jprogress);
+  m_raCallbacks->progress_baton = m_jctx;
+}
+
 void *
 RemoteSessionContext::getCallbackBaton()
 {

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/RemoteSessionContext.h Sun Oct 13 16:10:59 2013
@@ -34,11 +34,12 @@
 class RemoteSessionContext : public OperationContext
 {
   public:
-    RemoteSessionContext(jobject contextHolder, SVN::Pool &pool,
+    RemoteSessionContext(SVN::Pool &pool,
                          const char* jconfigDirectory,
                          const char* jusername, const char* jpassword,
-                         Prompter* prompter, jobject jprogress);
+                         Prompter* prompter);
     virtual ~RemoteSessionContext();
+    void activate(jobject jremoteSession, jobject jprogress);
     void * getCallbackBaton();
     svn_ra_callbacks2_t* getCallbacks();
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.cpp Sun Oct 13 16:10:59 2013
@@ -1419,16 +1419,11 @@ jobject SVNClient::revProperties(const c
     return CreateJ::PropertyMap(props, subPool.getPool());
 }
 
-struct info_baton
-{
-    std::vector<info_entry> infoVect;
-    apr_pool_t *pool;
-};
-
 void
-SVNClient::info2(const char *path, Revision &revision, Revision &pegRevision,
-                 svn_depth_t depth, StringArray &changelists,
-                 InfoCallback *callback)
+SVNClient::info2(const char *path,
+                 Revision &revision, Revision &pegRevision, svn_depth_t depth,
+                 svn_boolean_t fetchExcluded, svn_boolean_t fetchActualOnly,
+                 StringArray &changelists, InfoCallback *callback)
 {
     SVN_JNI_NULL_PTR_EX(path, "path", );
 
@@ -1443,7 +1438,7 @@ SVNClient::info2(const char *path, Revis
     SVN_JNI_ERR(svn_client_info3(checkedPath.c_str(),
                                  pegRevision.revision(),
                                  revision.revision(),
-                                 depth, FALSE, TRUE,
+                                 depth, fetchExcluded, fetchActualOnly,
                                  changelists.array(subPool),
                                  InfoCallback::callback, callback,
                                  ctx, subPool.getPool()), );

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/SVNClient.h Sun Oct 13 16:10:59 2013
@@ -66,9 +66,10 @@ class SVNClient :public SVNBase
   void patch(const char *patchPath, const char *targetPath, bool dryRun,
              int stripCount, bool reverse, bool ignoreWhitespace,
              bool removeTempfiles, PatchCallback *callback);
-  void info2(const char *path, Revision &revision, Revision &pegRevision,
-             svn_depth_t depth, StringArray &changelists,
-             InfoCallback *callback);
+  void info2(const char *path,
+             Revision &revision, Revision &pegRevision, svn_depth_t depth,
+             svn_boolean_t fetchExcluded, svn_boolean_t fetchActualOnly,
+             StringArray &changelists, InfoCallback *callback);
   void unlock(Targets &targets, bool force);
   void lock(Targets &targets, const char *comment, bool force);
   jobject revProperties(const char *path, Revision &revision);

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Sun Oct 13 16:10:59 2013
@@ -1795,8 +1795,9 @@ Java_org_apache_subversion_javahl_SVNCli
 JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_SVNClient_info2
 (JNIEnv *env, jobject jthis, jstring jpath, jobject jrevision,
- jobject jpegRevision, jobject jdepth, jobject jchangelists,
- jobject jinfoCallback)
+ jobject jpegRevision, jobject jdepth,
+ jboolean jfetchExcluded, jboolean jfetchActualOnly,
+ jobject jchangelists, jobject jinfoCallback)
 {
   JNIEntry(SVNClient, info2);
   SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -1823,6 +1824,7 @@ Java_org_apache_subversion_javahl_SVNCli
 
   InfoCallback callback(jinfoCallback);
   cl->info2(path, revision, pegRevision, EnumMapper::toDepth(jdepth),
+            svn_boolean_t(jfetchExcluded), svn_boolean_t(jfetchActualOnly),
             changelists, &callback);
 }
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteFactory.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteFactory.cpp?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteFactory.cpp (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteFactory.cpp Sun Oct 13 16:10:59 2013
@@ -36,15 +36,14 @@
 
 JNIEXPORT jobject JNICALL
 Java_org_apache_subversion_javahl_remote_RemoteFactory_open(
-    JNIEnv *env, jclass jclass, jint jretryAttempts,
+    JNIEnv *env, jclass jclazz, jint jretryAttempts,
     jstring jurl, jstring juuid,
     jstring jconfigDirectory,
     jstring jusername, jstring jpassword,
     jobject jprompter, jobject jprogress)
 {
   //JNI macros need jthis but this is a static call
-  jobject jthis = NULL;
-  JNIEntry(Remotefactory, open);
+  JNIEntryStatic(RemoteFactory, open);
 
   /*
    * Create RemoteSession C++ object and return its java wrapper to the caller

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java Sun Oct 13 16:10:59 2013
@@ -23,10 +23,12 @@
 
 package org.apache.subversion.javahl;
 
+import org.apache.subversion.javahl.types.*;
+import org.apache.subversion.javahl.callback.ClientNotifyCallback;
+
+import java.util.List;
 import java.util.Map;
 import java.util.EventObject;
-import org.apache.subversion.javahl.callback.ClientNotifyCallback;
-import org.apache.subversion.javahl.types.*;
 
 /**
  * The event passed to the {@link ClientNotifyCallback#onNotify}
@@ -41,7 +43,7 @@ public class ClientNotifyInformation ext
     // http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf
     // http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/version.html#6678
     // http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
 
     /**
      * The {@link Action} which triggered this event.
@@ -69,6 +71,12 @@ public class ClientNotifyInformation ext
     private String errMsg;
 
     /**
+     * A detailed stack of error messages for the item.
+     * @see ClientException
+     */
+    private List<ClientException.ErrorMessage> errMsgStack;
+
+    /**
      * The {@link Status} of the content of the item.
      */
     private Status contentState;
@@ -157,6 +165,7 @@ public class ClientNotifyInformation ext
         this.mimeType = mimeType;
         this.lock = lock;
         this.errMsg = errMsg;
+        this.errMsgStack = null;
         this.contentState = contentState;
         this.propState = propState;
         this.lockState = lockState;
@@ -176,6 +185,34 @@ public class ClientNotifyInformation ext
     }
 
     /**
+     * This constructor will be called only by the native code.
+     *
+     * In addition to all the other parameters, sets the detailed
+     * message stack.
+     */
+    protected ClientNotifyInformation(String path, Action action, NodeKind kind,
+                             String mimeType, Lock lock, String errMsg,
+                             List<ClientException.ErrorMessage> errMsgStack,
+                             Status contentState, Status propState,
+                             LockStatus lockState, long revision,
+                             String changelistName, RevisionRange mergeRange,
+                             String pathPrefix, String propName,
+                             Map<String, String> revProps, long oldRevision,
+                             long hunkOriginalStart, long hunkOriginalLength,
+                             long hunkModifiedStart, long hunkModifiedLength,
+                             long hunkMatchedLine, int hunkFuzz)
+    {
+        this(path, action, kind, mimeType, lock, errMsg,
+             contentState, propState, lockState, revision,
+             changelistName, mergeRange, pathPrefix, propName,
+             revProps, oldRevision,
+             hunkOriginalStart, hunkOriginalLength,
+             hunkModifiedStart, hunkModifiedLength,
+             hunkMatchedLine, hunkFuzz);
+        this.errMsgStack = errMsgStack;
+    }
+
+    /**
      * @return The path of the item, which is the source of the event.
      */
     public String getPath()
@@ -224,6 +261,14 @@ public class ClientNotifyInformation ext
     }
 
     /**
+     * @return Details about the error message for the item.
+     */
+    public List<ClientException.ErrorMessage> getErrMsgDetails()
+    {
+        return errMsgStack;
+    }
+
+    /**
      * @return The {@link Status} of the content of the item.
      */
     public Status getContentState()

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Sun Oct 13 16:10:59 2013
@@ -1133,7 +1133,56 @@ public interface ISVNClient
             throws ClientException;
 
     /**
+     * Invoke <code>callback</code> to return information
+     * <code>pathOrUrl</code> in <code>revision</code>.  The
+     * information returned is system-generated metadata, not the sort
+     * of "property" metadata created by users.
+     * <p>
+     * If both revision arguments are either <code>null</code> or
+     * {@link Revision#START}, then information will be pulled solely
+     * from the working copy; no network connections will be made.
+     * <p>
+     * Otherwise, information will be pulled from a repository.  The
+     * actual node revision selected is determined by the
+     * <code>pathOrUrl</code> as it exists in
+     * <code>pegRevision</code>.  If <code>pegRevision</code> is
+     * {@link Revision#START}, then it defaults to {@link
+     * Revision#HEAD} for URLs or {@link Revision#WORKING} for WC
+     * targets.
+     * <p>
+     * If <code>pathOrUrl</code> is not a local path, then if
+     * <code>revision</code> is {@link Revision#PREVIOUS} (or some
+     * other kind that requires a local path), an error will be
+     * returned, because the desired revision cannot be determined.
+     * <p>
+     * If <code>pathOrUrl</code> is a file, just invoke the callback on it.  If it
+     * is a directory, then descend according to <code>depth</code>.
+     * <p>
+     * @param pathOrUrl     the path or the url of the item
+     * @param revision      the revision of the item to return
+     * @param pegRevision   the revision to interpret pathOrUrl
+     * @param depth         the depth to recurse
+     * @param fetchExcluded when <code>true</code>, retreive
+     * information about nodes that are excluded from the working copy
+     * @param fetchActualOnly when <code>true</code>, retreive
+     * information about node that are not versioned, but are still
+     * tree conflicted.
+     * @param changelists   if non-null, filter paths using changelists
+     * @param callback      a callback to receive the infos retrieved
+     * @since 1.9
+     */
+    void info2(String pathOrUrl,
+               Revision revision, Revision pegRevision, Depth depth,
+               boolean fertchExcluded, boolean fetchActualOnly,
+               Collection<String> changelists, InfoCallback callback)
+        throws ClientException;
+
+    /**
      * Retrieve information about repository or working copy items.
+     * <p>
+     * Behaves like the 1.9 version, with <code>fetchExcluded</code>
+     * set to <code>false</code> and <code>fetchActualOnly</code> set
+     * to <code>true</code>.
      * @param pathOrUrl     the path or the url of the item
      * @param revision      the revision of the item to return
      * @param pegRevision   the revision to interpret pathOrUrl

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Sun Oct 13 16:10:59 2013
@@ -662,10 +662,21 @@ public class SVNClient implements ISVNCl
 
     public native void info2(String pathOrUrl, Revision revision,
                              Revision pegRevision, Depth depth,
+                             boolean fetchExcluded, boolean fetchActualOnly,
                              Collection<String> changelists,
                              InfoCallback callback)
             throws ClientException;
 
+    public void info2(String pathOrUrl, Revision revision,
+                      Revision pegRevision, Depth depth,
+                      Collection<String> changelists,
+                      InfoCallback callback)
+            throws ClientException
+    {
+        info2(pathOrUrl, revision, pegRevision, depth,
+              false, true, changelists, callback);
+    }
+
     public native void patch(String patchPath, String targetPath,
                              boolean dryRun, int stripCount, boolean reverse,
                              boolean ignoreWhitespace, boolean removeTempfiles,

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Sun Oct 13 16:10:59 2013
@@ -4002,8 +4002,8 @@ public class BasicTests extends SVNTests
     {
        final List<Info> infos = new ArrayList<Info>();
 
-        client.info2(pathOrUrl, revision, pegRevision, depth, changelists,
-                     new InfoCallback () {
+       client.info2(pathOrUrl, revision, pegRevision, depth, true, true,
+                     changelists, new InfoCallback () {
             public void singleInfo(Info info)
             { infos.add(info); }
         });

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Sun Oct 13 16:10:59 2013
@@ -128,6 +128,43 @@ public class SVNRemoteTests extends SVNT
         session.dispose();
     }
 
+    public void testSessionGC() throws Exception
+    {
+        int svnErrorCode = 0;
+        try {
+            try {
+                String prefix = getTestRepoUrl().substring(
+                    0, 1 + getTestRepoUrl().lastIndexOf("/"));
+                new RemoteFactory(
+                    super.conf.getAbsolutePath(),
+                    USERNAME, PASSWORD,
+                    new DefaultPromptUserPassword(), null)
+                    .openRemoteSession(prefix + "repositorydoesnotexisthere");
+            }
+            finally
+            {
+                for(int i = 0; i < 100; i++)
+                {
+                    Runtime.getRuntime().gc(); // GC should run finalize
+
+                    // Do something
+                    byte[] memEater = new byte[1024 * 1024];
+                    Arrays.fill(memEater, (byte) i);
+
+                    // Do some more javahl activity (this url is OK)
+                    final ISVNRemote session = getSession();
+                    session.getLatestRevision();
+                    session.dispose();
+                }
+            }
+        }
+        catch (ClientException ex)
+        {
+            svnErrorCode = ex.getAllMessages().get(0).getCode();
+        }
+        assertEquals(180001, svnErrorCode);
+    }
+
     public void testDatedRev() throws Exception
     {
         ISVNRemote session = getSession();

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h Sun Oct 13 16:10:59 2013
@@ -429,6 +429,40 @@ svn__decompress(svn_stringbuf_t *in,
 
 /** @} */
 
+/**
+ * @defgroup svn_root_pools Recycle-able root pools API
+ * @{
+ */
+
+/* Opaque thread-safe container for unused / recylcleable root pools.
+ *
+ * Recyling root pools (actually, their allocators) circumvents a
+ * scalability bottleneck in the OS memory management when multi-threaded
+ * applications frequently create and destroy allocators.
+ */
+typedef struct svn_root_pools__t svn_root_pools__t;
+
+/* Create a new root pools container and return it in *POOLS.
+ */
+svn_error_t *
+svn_root_pools__create(svn_root_pools__t **pools);
+
+/* Return a currently unused pool from POOLS.  If POOLS is empty, create a
+ * new root pool and return that.  The pool returned is not thread-safe.
+ */
+apr_pool_t *
+svn_root_pools__acquire_pool(svn_root_pools__t *pools);
+
+/* Clear and release the given root POOL and put it back into POOLS.
+ * If that fails, destroy POOL.
+ */
+void
+svn_root_pools__release_pool(apr_pool_t *pool,
+                             svn_root_pools__t *pools);
+
+/** @} */
+
+
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_client.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_client.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_client.h Sun Oct 13 16:10:59 2013
@@ -1018,6 +1018,24 @@ typedef struct svn_client_ctx_t
    *
    * @Since New in 1.9. */
   apr_off_t progress;
+
+  /** Open-tunnel callback
+   * If not @c null, this callback will be invoked to create an ra_svn
+   * connection that needs a tunnel, overriding any tunnel definitions
+   * in the client config file. This callback is used only for ra_svn
+   * and ignored by the other RA modules.
+   * @since New in 1.9.
+   */
+  svn_ra_open_tunnel_func_t open_tunnel_func;
+
+  /** Close-tunnel callback
+   * If not @c null, this callback will be invoked when the pool that
+   * owns the connection created by the open_tunnel callback is
+   * cleared or destroyed. This callback is used only for ra_svn and
+   * ignored by the other RA modules.
+   * @since New in 1.9.
+   */
+  svn_ra_close_tunnel_func_t close_tunnel_func;
 } svn_client_ctx_t;
 
 /** Initialize a client context.

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_ra.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_ra.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_ra.h Sun Oct 13 16:10:59 2013
@@ -270,6 +270,49 @@ typedef svn_error_t *(*svn_ra_replay_rev
   apr_hash_t *rev_props,
   apr_pool_t *pool);
 
+
+/**
+ * Callback function for opening a tunnel in ra_svn.
+ *
+ * Given the @a tunnel_name, tunnel @a user and server @a hostname and
+ * @a port, return a new ra_svn connection in @a conn. The returned
+ * connection must be allocated from @a pool.
+ *
+ * @a request and @a response are the standard input and output,
+ * respectively, of the process on the other end of the tunnel.
+ *
+ * @a tunnel_baton will be passed on to the close-unnel callback.
+ *
+ * @a open_baton is the baton as originally passed to ra_open.
+ *
+ * @since New in 1.9.
+ */
+typedef svn_error_t *(*svn_ra_open_tunnel_func_t)(
+    apr_file_t **request, apr_file_t **response,
+    void **tunnel_baton, void *open_baton,
+    const char *tunnel_name, const char *user,
+    const char *hostname, int port,
+    apr_pool_t *pool);
+
+/**
+ * Callback function for closing a tunnel in ra_svn.
+ *
+ * This function will be called when the pool that owns the tunnel
+ * connection is cleared or destroyed. It receives the @a baton that
+ * was created by the open-tunnel callback, and the same
+ * @a tunnel_name, @a user, @a hostname and @a port parameters.
+ *
+ * @a tunel_baton was returned by the open-tunnel callback.
+ *
+ * @a open_baton is the baton as originally passed to ra_open.
+ *
+ * @since New in 1.9.
+ */
+typedef svn_error_t *(*svn_ra_close_tunnel_func_t)(
+    void *tunnel_baton, void *open_baton,
+    const char *tunnel_name, const char *user,
+    const char *hostname, int port);
+
 
 /**
  * The update Reporter.
@@ -538,6 +581,24 @@ typedef struct svn_ra_callbacks2_t
    */
   svn_ra_get_wc_contents_func_t get_wc_contents;
 
+  /** Open-tunnel callback
+   * If not @c null, this callback will be invoked to create an ra_svn
+   * connection that needs a tunnel, overriding any tunnel definitions
+   * in the client config file. This callback is used only for ra_svn
+   * and ignored by the other RA modules.
+   * @since New in 1.9.
+   */
+  svn_ra_open_tunnel_func_t open_tunnel;
+
+  /** Close-tunnel callback
+   * If not @c null, this callback will be invoked when the pool that
+   * owns the connection created by the open_tunnel callback is
+   * cleared or destroyed. This callback is used only for ra_svn and
+   * ignored by the other RA modules.
+   * @since New in 1.9.
+   */
+  svn_ra_close_tunnel_func_t close_tunnel;
+
 } svn_ra_callbacks2_t;
 
 /** Similar to svn_ra_callbacks2_t, except that the progress

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_types.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_types.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_types.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_types.h Sun Oct 13 16:10:59 2013
@@ -70,7 +70,8 @@ extern "C" {
  */
 #ifndef SVN_EXPERIMENTAL
 # if !defined(SWIGPERL) && !defined(SWIGPYTHON) && !defined(SWIGRUBY)
-#  if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__==3 && __GNUC_MINOR__>=1))
+#  if !defined(__clang__) && defined(__GNUC__) \
+      && (__GNUC__ >= 4 || (__GNUC__==3 && __GNUC_MINOR__>=1))
 #   define SVN_EXPERIMENTAL __attribute__((warning("experimental function used")))
 #  elif defined(_MSC_VER) && _MSC_VER >= 1300
 #   define SVN_EXPERIMENTAL __declspec(deprecated("experimental function used"))

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/ra.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/ra.c Sun Oct 13 16:10:59 2013
@@ -350,6 +350,8 @@ svn_client__open_ra_session_internal(svn
   cbtable->get_client_string = get_client_string;
   if (base_dir_abspath)
     cbtable->get_wc_contents = get_wc_contents;
+  cbtable->open_tunnel = ctx->open_tunnel_func;
+  cbtable->close_tunnel = ctx->close_tunnel_func;
 
   cb->commit_items = commit_items;
   cb->ctx = ctx;

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/cached_data.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/cached_data.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/cached_data.h Sun Oct 13 16:10:59 2013
@@ -138,4 +138,4 @@ svn_fs_fs__get_changes(apr_array_header_
                        svn_revnum_t rev,
                        apr_pool_t *pool);
 
-#endif
\ No newline at end of file
+#endif

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.c Sun Oct 13 16:10:59 2013
@@ -2706,15 +2706,16 @@ write_final_changed_path_info(apr_off_t 
   SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, pool));
 
   /* all moves specify the "copy-from-rev" as REV-1 */
-  for (hi = apr_hash_first(pool, changed_paths); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_path_change2_t *change;
-      apr_hash_this(hi, NULL, NULL, (void **)&change);
+  if (svn_fs_fs__supports_move(fs))
+    for (hi = apr_hash_first(pool, changed_paths); hi; hi = apr_hash_next(hi))
+      {
+        svn_fs_path_change2_t *change;
+        apr_hash_this(hi, NULL, NULL, (void **)&change);
 
-      if (   (change->change_kind == svn_fs_path_change_move)
-          || (change->change_kind == svn_fs_path_change_movereplace))
-        change->copyfrom_rev = new_rev - 1;
-    }
+        if (   (change->change_kind == svn_fs_path_change_move)
+            || (change->change_kind == svn_fs_path_change_movereplace))
+          change->copyfrom_rev = new_rev - 1;
+      }
 
   SVN_ERR(svn_fs_fs__write_changes(svn_stream_from_aprfile2(file, TRUE, pool),
                                    fs, changed_paths, TRUE, pool));
@@ -3091,7 +3092,10 @@ commit_body(void *baton, apr_pool_t *poo
   SVN_ERR(svn_fs_fs__txn_changes_fetch(&changed_paths, cb->fs, txn_id,
                                        pool));
 
-  SVN_ERR(verify_moves(cb->fs, txn_id, old_rev, changed_paths, pool));
+  /* ensure that no change in this txn or any txn committed since the start
+   * of this txn violates our move semantics */
+  if (svn_fs_fs__supports_move(cb->fs))
+    SVN_ERR(verify_moves(cb->fs, txn_id, old_rev, changed_paths, pool));
 
   /* Get the next node_id and copy_id to use. */
   if (ffd->format < SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/transaction.h Sun Oct 13 16:10:59 2013
@@ -280,4 +280,4 @@ svn_fs_fs__begin_txn(svn_fs_txn_t **txn_
                      apr_uint32_t flags,
                      apr_pool_t *pool);
 
-#endif
\ No newline at end of file
+#endif

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/tree.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/tree.c Sun Oct 13 16:10:59 2013
@@ -2423,34 +2423,44 @@ is_changed_node(svn_boolean_t *changed,
   svn_fs_root_t *copy_from_root1, *copy_from_root2;
   const char *copy_from_path1, *copy_from_path2;
 
-  *changed = TRUE;
-
   SVN_ERR(svn_fs_fs__revision_root(&rev_root, root->fs, revision, pool));
 
   /* Get the NODE for FROM_PATH in FROM_ROOT.*/
   SVN_ERR(get_dag(&node, root, path, TRUE, pool));
   SVN_ERR(get_dag(&rev_node, rev_root, path, TRUE, pool));
 
-  /* different ID -> got changed*/
+  /* different ID -> got changed */
   if (!svn_fs_fs__id_eq(svn_fs_fs__dag_get_id(node),
                         svn_fs_fs__dag_get_id(rev_node)))
-    return SVN_NO_ERROR;
+    {
+      *changed = TRUE;
+       return SVN_NO_ERROR;
+    }
 
-  /* some node. might still be a lazy copy */
+  /* same node. might still be a lazy copy with separate history */
   SVN_ERR(fs_closest_copy(&copy_from_root1, &copy_from_path1, root,
                           path, pool));
   SVN_ERR(fs_closest_copy(&copy_from_root2, &copy_from_path2, rev_root,
                           path, pool));
 
-  if ((copy_from_root1 == NULL) != (copy_from_root2 == NULL))
-    return SVN_NO_ERROR;
-
-  if (copy_from_root1)
-    if (   copy_from_root1->rev != copy_from_root2->rev
-        || strcmp(copy_from_path1, copy_from_path2))
-      return SVN_NO_ERROR;
+  if (copy_from_root1 == NULL && copy_from_root2 == NULL)
+    {
+      /* never copied -> same line of history */
+      *changed = FALSE;
+    }
+  else if (copy_from_root1 != NULL && copy_from_root2 != NULL)
+    {
+      /* both got copied. At the same time & location? */
+      *changed = (copy_from_root1->rev != copy_from_root2->rev)
+                 || strcmp(copy_from_path1, copy_from_path2);
+    }
+  else
+    {
+      /* one is a copy while the other one is not
+       * -> different lines of history */
+      *changed = TRUE;
+    }
 
-  *changed = FALSE;
   return SVN_NO_ERROR;
 }
 
@@ -2503,6 +2513,13 @@ copy_helper(svn_fs_root_t *from_root,
           svn_error_t *err = is_changed_node(&changed, from_root,
                                              from_path, txn_id->revision,
                                              pool);
+
+          /* Only "not found" is considered to be caused by out-of-date-ness.
+             Everything else means something got very wrong ... */
+          if (err && err->apr_err != SVN_ERR_FS_NOT_FOUND)
+            return svn_error_trace(err);
+
+          /* here error means "out of data" */
           if (err || changed)
             {
               svn_error_clear(err);

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/util.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/util.h Sun Oct 13 16:10:59 2013
@@ -365,4 +365,4 @@ svn_fs_fs__item_offset(apr_off_t *absolu
 svn_boolean_t
 svn_fs_fs__supports_move(svn_fs_t *fs);
 
-#endif
\ No newline at end of file
+#endif

Propchange: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/libsvn_fs_x:r1526469-1531700

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/tree.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_x/tree.c Sun Oct 13 16:10:59 2013
@@ -132,6 +132,12 @@ static svn_error_t *make_txn_root(svn_fs
                                   apr_uint32_t flags,
                                   apr_pool_t *pool);
 
+static svn_error_t *x_closest_copy(svn_fs_root_t **root_p,
+                                   const char **path_p,
+                                   svn_fs_root_t *root,
+                                   const char *path,
+                                   apr_pool_t *pool);
+
 
 /*** Node Caching ***/
 
@@ -2344,6 +2350,65 @@ typedef enum copy_type_t
   copy_type_move
 } copy_type_t;
 
+/* Set CHANGES to TRUE if PATH in ROOT is unchanged in REVISION if the
+   same files system.  If the content is identical, parent path copies and
+   deletions still count as changes.  Use POOL for temporary allocations.
+   Not that we will return an error if PATH does not exist in ROOT or
+   REVISION- */
+static svn_error_t *
+is_changed_node(svn_boolean_t *changed,
+                svn_fs_root_t *root,
+                const char *path,
+                svn_revnum_t revision,
+                apr_pool_t *pool)
+{
+  dag_node_t *node, *rev_node;
+  svn_fs_root_t *rev_root;
+  svn_fs_root_t *copy_from_root1, *copy_from_root2;
+  const char *copy_from_path1, *copy_from_path2;
+
+  SVN_ERR(svn_fs_x__revision_root(&rev_root, root->fs, revision, pool));
+
+  /* Get the NODE for FROM_PATH in FROM_ROOT.*/
+  SVN_ERR(get_dag(&node, root, path, TRUE, pool));
+  SVN_ERR(get_dag(&rev_node, rev_root, path, TRUE, pool));
+
+  /* different ID -> got changed */
+  if (!svn_fs_x__id_eq(svn_fs_x__dag_get_id(node),
+                       svn_fs_x__dag_get_id(rev_node)))
+    {
+      *changed = TRUE;
+       return SVN_NO_ERROR;
+    }
+
+  /* same node. might still be a lazy copy with separate history */
+  SVN_ERR(x_closest_copy(&copy_from_root1, &copy_from_path1, root,
+                         path, pool));
+  SVN_ERR(x_closest_copy(&copy_from_root2, &copy_from_path2, rev_root,
+                         path, pool));
+
+  if (copy_from_root1 == NULL && copy_from_root2 == NULL)
+    {
+      /* never copied -> same line of history */
+      *changed = FALSE;
+    }
+  else if (copy_from_root1 != NULL && copy_from_root2 != NULL)
+    {
+      /* both got copied. At the same time & location? */
+      *changed = (copy_from_root1->rev != copy_from_root2->rev)
+                 || strcmp(copy_from_path1, copy_from_path2);
+    }
+  else
+    {
+      /* one is a copy while the other one is not
+       * -> different lines of history */
+      *changed = TRUE;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 /* Copy the node at FROM_PATH under FROM_ROOT to TO_PATH under
    TO_ROOT.  COPY_TYPE determines whether then the copy is recorded in
    the copies table and whether it is being marked as a move.
@@ -2381,10 +2446,36 @@ copy_helper(svn_fs_root_t *from_root,
       (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
        _("Copy immutable tree not supported"));
 
-  if (copy_type == copy_type_move && from_root->rev != txn_id->revision)
-    return svn_error_create
-      (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-       _("Move from non-HEAD revision not currently supported"));
+  /* move support comes with a number of conditions ... */
+  if (copy_type == copy_type_move)
+    {
+      /* if we don't copy from the TXN's base rev, check that the path has
+         not been touched in that revision range */
+      if (from_root->rev != txn_id->revision)
+        {
+          svn_boolean_t changed = TRUE;
+          svn_error_t *err = is_changed_node(&changed, from_root,
+                                             from_path, txn_id->revision,
+                                             pool);
+
+          /* Only "not found" is considered to be caused by out-of-date-ness.
+             Everything else means something got very wrong ... */
+          if (err && err->apr_err != SVN_ERR_FS_NOT_FOUND)
+            return svn_error_trace(err);
+
+          /* here error means "out of data" */
+          if (err || changed)
+            {
+              svn_error_clear(err);
+              return svn_error_create(SVN_ERR_FS_OUT_OF_DATE, NULL,
+                                      _("Move-from node is out-of-date"));
+            }
+
+          /* always move from the txn's base rev */
+          SVN_ERR(svn_fs_x__revision_root(&from_root, from_root->fs,
+                                          txn_id->revision, pool));
+        }
+    }
 
   /* Get the NODE for FROM_PATH in FROM_ROOT.*/
   SVN_ERR(get_dag(&from_node, from_root, from_path, TRUE, pool));

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/client.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/client.c Sun Oct 13 16:10:59 2013
@@ -561,14 +561,42 @@ static svn_error_t *parse_url(const char
   return SVN_NO_ERROR;
 }
 
+/* This structure is used as a baton for the pool cleanup function to
+   store tunnel parameters used by the close-tunnel callback. */
+struct tunnel_data_t {
+  void *tunnel_baton;
+  void *open_baton;
+  const char *tunnel_name;
+  const char *user;
+  const char *hostname;
+  int port;
+  svn_ra_close_tunnel_func_t close_tunnel;
+};
+
+/* Pool cleanup function that invokes the close-tunel callback. */
+static apr_status_t close_tunnel_cleanup(void *baton)
+{
+  const struct tunnel_data_t *const td = baton;
+  svn_error_t *const err =
+    svn_error_root_cause(td->close_tunnel(td->tunnel_baton, td->open_baton,
+                                          td->tunnel_name, td->user,
+                                          td->hostname, td->port));
+  const apr_status_t ret = (err ? err->apr_err : 0);
+  svn_error_clear(err);
+  return ret;
+}
+
 /* Open a session to URL, returning it in *SESS_P, allocating it in POOL.
    URI is a parsed version of URL.  CALLBACKS and CALLBACKS_BATON
-   are provided by the caller of ra_svn_open. If tunnel_argv is non-null,
-   it points to a program argument list to use when invoking the tunnel agent.
+   are provided by the caller of ra_svn_open. If TUNNEL_NAME is not NULL,
+   it is the name of the tunnel type parsed from the URL scheme.
+   If TUNNEL_ARGV is not NULL, it points to a program argument list to use
+   when invoking the tunnel agent.
 */
 static svn_error_t *open_session(svn_ra_svn__session_baton_t **sess_p,
                                  const char *url,
                                  const apr_uri_t *uri,
+                                 const char *tunnel_name,
                                  const char **tunnel_argv,
                                  const svn_ra_callbacks2_t *callbacks,
                                  void *callbacks_baton,
@@ -583,19 +611,51 @@ static svn_error_t *open_session(svn_ra_
 
   sess = apr_palloc(pool, sizeof(*sess));
   sess->pool = pool;
-  sess->is_tunneled = (tunnel_argv != NULL);
+  sess->is_tunneled = (tunnel_name != NULL);
   sess->url = apr_pstrdup(pool, url);
   sess->user = uri->user;
   sess->hostname = uri->hostname;
   sess->realm_prefix = apr_psprintf(pool, "<svn://%s:%d>", uri->hostname,
                                     uri->port);
+  sess->tunnel_name = tunnel_name;
   sess->tunnel_argv = tunnel_argv;
   sess->callbacks = callbacks;
   sess->callbacks_baton = callbacks_baton;
   sess->bytes_read = sess->bytes_written = 0;
 
-  if (tunnel_argv)
-    SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
+  if (tunnel_name)
+    {
+      if (!callbacks->open_tunnel)
+        SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
+      else
+        {
+          void *tunnel_baton;
+          apr_file_t *request;
+          apr_file_t *response;
+          SVN_ERR(callbacks->open_tunnel(&request, &response, &tunnel_baton,
+                                         callbacks_baton, tunnel_name,
+                                         uri->user, uri->hostname, uri->port,
+                                         pool));
+          if (callbacks->close_tunnel)
+            {
+              struct tunnel_data_t *const td = apr_palloc(pool, sizeof(*td));
+              td->tunnel_baton = tunnel_baton;
+              td->open_baton = callbacks_baton;
+              td->tunnel_name = apr_pstrdup(pool, tunnel_name);
+              td->user = apr_pstrdup(pool, uri->user);
+              td->hostname = apr_pstrdup(pool, uri->hostname);
+              td->port = uri->port;
+              td->close_tunnel = callbacks->close_tunnel;
+              apr_pool_cleanup_register(pool, td, close_tunnel_cleanup,
+                                        apr_pool_cleanup_null);
+            }
+
+          conn = svn_ra_svn_create_conn3(NULL, response, request,
+                                         SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
+                                         0, 0, pool);
+          SVN_ERR(svn_ra_svn__skip_leading_garbage(conn, pool));
+        }
+    }
   else
     {
       SVN_ERR(make_connection(uri->hostname, uri->port, &sock, pool));
@@ -738,7 +798,7 @@ static svn_error_t *ra_svn_open(svn_ra_s
 
   parse_tunnel(url, &tunnel, pool);
 
-  if (tunnel)
+  if (tunnel && !callbacks->open_tunnel)
     SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,
                               pool));
   else
@@ -755,7 +815,7 @@ static svn_error_t *ra_svn_open(svn_ra_s
 
   /* We open the session in a subpool so we can get rid of it if we
      reparent with a server that doesn't support reparenting. */
-  SVN_ERR(open_session(&sess, url, &uri, tunnel_argv,
+  SVN_ERR(open_session(&sess, url, &uri, tunnel, tunnel_argv,
                        callbacks, callback_baton, sess_pool));
   session->priv = sess;
 
@@ -791,7 +851,7 @@ static svn_error_t *ra_svn_reparent(svn_
   sess_pool = svn_pool_create(ra_session->pool);
   err = parse_url(url, &uri, sess_pool);
   if (! err)
-    err = open_session(&new_sess, url, &uri, sess->tunnel_argv,
+    err = open_session(&new_sess, url, &uri, sess->tunnel_name, sess->tunnel_argv,
                        sess->callbacks, sess->callbacks_baton, sess_pool);
   /* We destroy the new session pool on error, since it is allocated in
      the main session pool. */

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/ra_svn.h?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_ra_svn/ra_svn.h Sun Oct 13 16:10:59 2013
@@ -127,6 +127,7 @@ struct svn_ra_svn__session_baton_t {
   const char *user;
   const char *hostname; /* The remote hostname. */
   const char *realm_prefix;
+  const char *tunnel_name;
   const char **tunnel_argv;
   const svn_ra_callbacks2_t *callbacks;
   void *callbacks_baton;

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cache_config.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cache_config.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cache_config.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cache_config.c Sun Oct 13 16:10:59 2013
@@ -23,6 +23,7 @@
 #include <apr_atomic.h>
 
 #include "svn_cache_config.h"
+#include "private/svn_atomic.h"
 #include "private/svn_cache.h"
 
 #include "svn_pools.h"
@@ -69,30 +70,27 @@ svn_cache_config_get(void)
   return &cache_settings;
 }
 
-/* Access the process-global (singleton) membuffer cache. The first call
- * will automatically allocate the cache using the current cache config.
- * NULL will be returned if the desired cache size is 0 or if the cache
- * could not be created for some reason.
+/* Initializer function as required by svn_atomic__init_once.  Allocate
+ * the process-global (singleton) membuffer cache and return it in the
+ * svn_membuffer_t * in *BATON.  UNUSED_POOL is unused and should be NULL.
  */
-svn_membuffer_t *
-svn_cache__get_global_membuffer_cache(void)
+static svn_error_t *
+initialize_cache(void *baton, apr_pool_t *unused_pool)
 {
-  static svn_membuffer_t * volatile cache = NULL;
+  svn_membuffer_t **cache_p = baton;
+  svn_membuffer_t *cache = NULL;
 
   apr_uint64_t cache_size = cache_settings.cache_size;
-  if (!cache && cache_size)
+  if (cache_size)
     {
       svn_error_t *err;
 
-      svn_membuffer_t *old_cache = NULL;
-      svn_membuffer_t *new_cache = NULL;
-
       /* auto-allocate cache */
       apr_allocator_t *allocator = NULL;
       apr_pool_t *pool = NULL;
 
       if (apr_allocator_create(&allocator))
-        return NULL;
+        return SVN_NO_ERROR;
 
       /* Ensure that we free partially allocated data if we run OOM
        * before the cache is complete: If the cache cannot be allocated
@@ -112,11 +110,11 @@ svn_cache__get_global_membuffer_cache(vo
        */
       apr_pool_create_ex(&pool, NULL, NULL, allocator);
       if (pool == NULL)
-        return NULL;
+        return SVN_NO_ERROR;
       apr_allocator_owner_set(allocator, pool);
 
       err = svn_cache__membuffer_cache_create(
-          &new_cache,
+          &cache,
           (apr_size_t)cache_size,
           (apr_size_t)(cache_size / 5),
           0,
@@ -129,33 +127,40 @@ svn_cache__get_global_membuffer_cache(vo
        */
       if (err)
         {
-          /* Memory and error cleanup */
-          svn_error_clear(err);
+          /* Memory cleanup */
           svn_pool_destroy(pool);
 
-          /* Prevent future attempts to create the cache. However, an
-           * existing cache instance (see next comment) remains valid.
-           */
+          /* Document that we actually don't have a cache. */
           cache_settings.cache_size = 0;
 
-          /* The current caller won't get the cache object.
-           * However, a concurrent call might have succeeded in creating
-           * the cache object. That call and all following ones will then
-           * use the successfully created cache instance.
-           */
-          return NULL;
+          return svn_error_trace(err);
         }
 
-      /* Handle race condition: if we are the first to create a
-       * cache object, make it our global singleton. Otherwise,
-       * discard the new cache and keep the existing one.
-       *
-       * Cast is necessary because of APR bug:
-       * https://issues.apache.org/bugzilla/show_bug.cgi?id=50731
-       */
-      old_cache = apr_atomic_casptr((volatile void **)&cache, new_cache, NULL);
-      if (old_cache != NULL)
-        svn_pool_destroy(pool);
+      /* done */
+      *cache_p = cache;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Access the process-global (singleton) membuffer cache. The first call
+ * will automatically allocate the cache using the current cache config.
+ * NULL will be returned if the desired cache size is 0 or if the cache
+ * could not be created for some reason.
+ */
+svn_membuffer_t *
+svn_cache__get_global_membuffer_cache(void)
+{
+  static svn_membuffer_t *cache = NULL;
+  static svn_atomic_t initialized = 0;
+
+  svn_error_t *err
+    = svn_atomic__init_once(&initialized, initialize_cache, &cache, NULL);
+  if (err)
+    {
+      /* no caches today ... */
+      svn_error_clear(err);
+      return NULL;
     }
 
   return cache;

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cmdline.c?rev=1531702&r1=1531701&r2=1531702&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/cmdline.c Sun Oct 13 16:10:59 2013
@@ -67,11 +67,17 @@
 
 #include "win32_crashrpt.h"
 
+#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1400)
+/* Before Visual Studio 2005, the C runtime didn't handle encodings for the
+   for the stdio output handling. */
+#define CMDLINE_USE_CUSTOM_ENCODING
+
 /* The stdin encoding. If null, it's the same as the native encoding. */
 static const char *input_encoding = NULL;
 
 /* The stdout encoding. If null, it's the same as the native encoding. */
 static const char *output_encoding = NULL;
+#endif
 
 
 int
@@ -113,7 +119,7 @@ svn_cmdline_init(const char *progname, F
 #endif
 
 #ifdef WIN32
-#if _MSC_VER < 1400
+#ifdef CMDLINE_USE_CUSTOM_ENCODING
   /* Initialize the input and output encodings. */
   {
     static char input_encoding_buffer[16];
@@ -127,7 +133,7 @@ svn_cmdline_init(const char *progname, F
                  "CP%u", (unsigned) GetConsoleOutputCP());
     output_encoding = output_encoding_buffer;
   }
-#endif /* _MSC_VER < 1400 */
+#endif /* CMDLINE_USE_CUSTOM_ENCODING */
 
 #ifdef SVN_USE_WIN32_CRASHHANDLER
   if (!getenv("SVN_CMDLINE_DISABLE_CRASH_HANDLER"))
@@ -257,10 +263,12 @@ svn_cmdline_cstring_from_utf8(const char
                               const char *src,
                               apr_pool_t *pool)
 {
-  if (output_encoding == NULL)
-    return svn_utf_cstring_from_utf8(dest, src, pool);
-  else
+#ifdef CMDLINE_USE_CUSTOM_ENCODING
+  if (output_encoding != NULL)
     return svn_utf_cstring_from_utf8_ex2(dest, src, output_encoding, pool);
+#endif
+
+  return svn_utf_cstring_from_utf8(dest, src, pool);
 }
 
 
@@ -278,10 +286,12 @@ svn_cmdline_cstring_to_utf8(const char *
                             const char *src,
                             apr_pool_t *pool)
 {
-  if (input_encoding == NULL)
-    return svn_utf_cstring_to_utf8(dest, src, pool);
-  else
+#ifdef CMDLINE_USE_CUSTOM_ENCODING
+  if (input_encoding != NULL)
     return svn_utf_cstring_to_utf8_ex2(dest, src, input_encoding, pool);
+#endif
+
+  return svn_utf_cstring_to_utf8(dest, src, pool);
 }
 
 
@@ -394,10 +404,12 @@ svn_cmdline_fflush(FILE *stream)
 
 const char *svn_cmdline_output_encoding(apr_pool_t *pool)
 {
+#ifdef CMDLINE_USE_CUSTOM_ENCODING
   if (output_encoding)
     return apr_pstrdup(pool, output_encoding);
-  else
-    return SVN_APR_LOCALE_CHARSET;
+#endif
+
+  return SVN_APR_LOCALE_CHARSET;
 }
 
 int