You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ar...@apache.org on 2012/07/30 08:39:38 UTC

svn commit: r1367002 [4/21] - in /subversion/branches/svn-bisect: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ notes/api-errata/1.7/ notes/http-and-webdav/ ...

Modified: subversion/branches/svn-bisect/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/include/svn_ra.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/include/svn_ra.h (original)
+++ subversion/branches/svn-bisect/subversion/include/svn_ra.h Mon Jul 30 06:39:28 2012
@@ -1406,8 +1406,9 @@ svn_ra_do_diff(svn_ra_session_t *session
  *
  * If @a discover_changed_paths, then each call to @a receiver passes a
  * <tt>const apr_hash_t *</tt> for the receiver's @a changed_paths argument;
- * the hash's keys are all the paths committed in that revision.
- * Otherwise, each call to receiver passes NULL for @a changed_paths.
+ * the hash's keys are all the paths committed in that revision, the hash's
+ * values are <tt>const svn_log_changed_path2_t *</tt> for each committed
+ * path. Otherwise, each call to receiver passes NULL for @a changed_paths.
  *
  * If @a strict_node_history is set, copy history will not be traversed
  * (if any exists) when harvesting the revision logs for each path.

Modified: subversion/branches/svn-bisect/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/include/svn_repos.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/include/svn_repos.h (original)
+++ subversion/branches/svn-bisect/subversion/include/svn_repos.h Mon Jul 30 06:39:28 2012
@@ -516,8 +516,30 @@ svn_repos_fs(svn_repos_t *repos);
  * source filesystem as part of the copy operation; currently, this
  * means deleting copied, unused logfiles for a Berkeley DB source
  * repository.
+ *
+ * If @a incremental is TRUE, make an effort to not re-copy information
+ * already present in the destination. If incremental hotcopy is not
+ * implemented by the filesystem backend, raise SVN_ERR_UNSUPPORTED_FEATURE.
+ *
+ * @since New in 1.8.
  */
 svn_error_t *
+svn_repos_hotcopy2(const char *src_path,
+                   const char *dst_path,
+                   svn_boolean_t clean_logs,
+                   svn_boolean_t incremental,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool);
+
+/** 
+ * Like svn_repos_hotcopy2(), but without the @a incremental parameter
+ * and without cancellation support.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_repos_hotcopy(const char *src_path,
                   const char *dst_path,
                   svn_boolean_t clean_logs,
@@ -742,6 +764,17 @@ const char *
 svn_repos_post_unlock_hook(svn_repos_t *repos,
                            apr_pool_t *pool);
 
+/** Set the environment that @a repos's hooks will inherit to @a hooks_env,
+ * a hash table where keys and values represent names and values of environment
+ * variables. @a hooks_env must live at least as long as @a repos.
+ *
+ * If this function is not called, hooks will run in an empty environment.
+ *
+ * @since New in 1.8. */
+void
+svn_repos_hooks_setenv(svn_repos_t *repos,
+                       apr_hash_t *hooks_env);
+
 /** @} */
 
 /* ---------------------------------------------------------------*/
@@ -2994,6 +3027,10 @@ svn_repos_authz_read(svn_authz_t **authz
  * For compatibility with 1.6, and earlier, @a repos_name can be NULL
  * in which case it is equivalent to a @a repos_name of "".
  *
+ * @note Presently, @a repos_name must byte-for-byte match the repos_name
+ * specified in the authz file; it is treated as an opaque string, and not
+ * as a dirent.
+ *
  * @since New in 1.3.
  */
 svn_error_t *

Modified: subversion/branches/svn-bisect/subversion/include/svn_string.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/include/svn_string.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/include/svn_string.h (original)
+++ subversion/branches/svn-bisect/subversion/include/svn_string.h Mon Jul 30 06:39:28 2012
@@ -383,6 +383,20 @@ svn_boolean_t
 svn_cstring_match_list(const char *str, const apr_array_header_t *list);
 
 /**
+ * Get the next token from @a *str interpreting any char from @a sep as a
+ * token separator.  Separators at the beginning of @a str will be skipped.
+ * Returns a pointer to the beginning of the first token in @a *str or NULL
+ * if no token is left.  Modifies @a str such that the next call will return
+ * the next token.
+ *
+ * Note that the content of @a *str may be modified by this function.
+ *
+ * @since New in 1.8.
+ */
+char *
+svn_cstring_tokenize(const char *sep, char **str);
+
+/**
  * Return the number of line breaks in @a msg, allowing any kind of newline
  * termination (CR, LF, CRLF, or LFCR), even inconsistent.
  *

Modified: subversion/branches/svn-bisect/subversion/include/svn_utf.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/include/svn_utf.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/include/svn_utf.h (original)
+++ subversion/branches/svn-bisect/subversion/include/svn_utf.h Mon Jul 30 06:39:28 2012
@@ -49,12 +49,28 @@ extern "C" {
  * Initialize the UTF-8 encoding/decoding routines.
  * Allocate cached translation handles in a subpool of @a pool.
  *
+ * If @a assume_native_utf8 is TRUE, the native character set is
+ * assumed to be UTF-8, i.e. conversion is a no-op. This is useful
+ * in contexts where the native character set is ASCII but UTF-8
+ * should be used regardless (e.g. for mod_dav_svn which runs within
+ * httpd and always uses the "C" locale).
+ *
  * @note It is optional to call this function, but if it is used, no other
  * svn function may be in use in other threads during the call of this
  * function or when @a pool is cleared or destroyed.
  * Initializing the UTF-8 routines will improve performance.
  *
- * @since New in 1.1.
+ * @since New in 1.8.
+ */
+void
+svn_utf_initialize2(apr_pool_t *pool,
+                    svn_boolean_t assume_native_utf8);
+
+/**
+ * Like svn_utf_initialize but without the ability to force the
+ * native encoding to UTF-8.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  */
 void
 svn_utf_initialize(apr_pool_t *pool);

Modified: subversion/branches/svn-bisect/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/include/svn_wc.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/include/svn_wc.h (original)
+++ subversion/branches/svn-bisect/subversion/include/svn_wc.h Mon Jul 30 06:39:28 2012
@@ -1354,7 +1354,9 @@ typedef struct svn_wc_notify_t {
    * In all other cases, it is @c NULL.  @since New in 1.5 */
   const char *changelist_name;
 
-  /** When @c action is #svn_wc_notify_merge_begin, and both the
+  /** When @c action is #svn_wc_notify_merge_begin or
+   * #svn_wc_notify_foreign_merge_begin or
+   * #svn_wc_notify_merge_record_info_begin, and both the
    * left and right sides of the merge are from the same URL.  In all
    * other cases, it is @c NULL.  @since New in 1.5 */
   svn_merge_range_t *merge_range;
@@ -4047,6 +4049,10 @@ svn_wc_walk_status(svn_wc_context_t *wc_
                    apr_pool_t *scratch_pool);
 
 /**
+ * DEPRECATED -- please use APIs from svn_client.h
+ *
+ * ---
+ *
  * Set @a *editor and @a *edit_baton to an editor that generates
  * #svn_wc_status3_t structures and sends them through @a status_func /
  * @a status_baton.  @a anchor_abspath is a working copy directory
@@ -4108,7 +4114,9 @@ svn_wc_walk_status(svn_wc_context_t *wc_
  * in a subpool of @a result_pool.
  *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_get_status_editor5(const svn_delta_editor_t **editor,
                           void **edit_baton,
@@ -5485,6 +5493,10 @@ typedef svn_error_t *(*svn_wc_dirents_fu
 
 
 /**
+ * DEPRECATED -- please use APIs from svn_client.h
+ *
+ * ---
+ *
  * Set @a *editor and @a *edit_baton to an editor and baton for updating a
  * working copy.
  *
@@ -5558,7 +5570,9 @@ typedef svn_error_t *(*svn_wc_dirents_fu
  * before returning the editor to allow using the primary ra session for this.
  *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_get_update_editor4(const svn_delta_editor_t **editor,
                           void **edit_baton,
@@ -5689,6 +5703,10 @@ svn_wc_get_update_editor(svn_revnum_t *t
                          apr_pool_t *pool);
 
 /**
+ * DEPRECATED -- please use APIs from svn_client.h
+ *
+ * ---
+ *
  * A variant of svn_wc_get_update_editor4().
  *
  * Set @a *editor and @a *edit_baton to an editor and baton for "switching"
@@ -5699,7 +5717,9 @@ svn_wc_get_update_editor(svn_revnum_t *t
  * All other parameters behave as for svn_wc_get_update_editor4().
  *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_get_switch_editor4(const svn_delta_editor_t **editor,
                           void **edit_baton,
@@ -6136,6 +6156,10 @@ svn_wc_canonicalize_svn_prop(const svn_s
  */
 
 /**
+ * DEPRECATED -- please use APIs from svn_client.h
+ *
+ * ---
+ *
  * Return an @a editor/@a edit_baton for diffing a working copy against the
  * repository. The editor is allocated in @a result_pool; temporary
  * calculations are performed in @a scratch_pool.
@@ -6189,7 +6213,9 @@ svn_wc_canonicalize_svn_prop(const svn_s
  * editor.
  *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_get_diff_editor6(const svn_delta_editor_t **editor,
                         void **edit_baton,

Modified: subversion/branches/svn-bisect/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c Mon Jul 30 06:39:28 2012
@@ -230,10 +230,60 @@ unlock_gnome_keyring(const char *keyring
   return TRUE;
 }
 
-/* Implementation of password_get_t that retrieves the password
+
+/* There is a race here: this ensures keyring is unlocked just now,
+   but will it still be unlocked when we use it? */
+static svn_error_t *
+ensure_gnome_keyring_is_unlocked(svn_boolean_t non_interactive,
+                                 apr_hash_t *parameters,
+                                 apr_pool_t *scratch_pool)
+{
+  const char *default_keyring = get_default_keyring_name(scratch_pool);
+
+  if (! non_interactive)
+    {
+      svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
+        apr_hash_get(parameters,
+                     SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
+                     APR_HASH_KEY_STRING);
+      void *unlock_prompt_baton =
+        apr_hash_get(parameters,
+                     SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
+                     APR_HASH_KEY_STRING);
+
+      char *keyring_password;
+
+      if (unlock_prompt_func && check_keyring_is_locked(default_keyring))
+        {
+          SVN_ERR((*unlock_prompt_func)(&keyring_password,
+                                        default_keyring,
+                                        unlock_prompt_baton,
+                                        scratch_pool));
+
+          /* If keyring is locked give up and try the next provider. */
+          if (! unlock_gnome_keyring(default_keyring, keyring_password,
+                                     scratch_pool))
+            return SVN_NO_ERROR;
+        }
+    }
+  else
+    {
+      if (check_keyring_is_locked(default_keyring))
+        {
+          return svn_error_create(SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
+                                  _("GNOME Keyring is locked and "
+                                    "we are non-interactive"));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Implementation of svn_auth__password_get_t that retrieves the password
    from GNOME Keyring. */
-static svn_boolean_t
-password_get_gnome_keyring(const char **password,
+static svn_error_t *
+password_get_gnome_keyring(svn_boolean_t *done,
+                           const char **password,
                            apr_hash_t *creds,
                            const char *realmstring,
                            const char *username,
@@ -244,13 +294,10 @@ password_get_gnome_keyring(const char **
   char *default_keyring = NULL;
   GnomeKeyringResult result;
   GList *items;
-  svn_boolean_t ret = FALSE;
 
-  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
-    return FALSE;
+  *done = FALSE;
 
-  if (! gnome_keyring_is_available())
-    return FALSE;
+  SVN_ERR(ensure_gnome_keyring_is_unlocked(non_interactive, parameters, pool));
 
   default_keyring = get_default_keyring_name(pool);
 
@@ -278,7 +325,7 @@ password_get_gnome_keyring(const char **
               if (len > 0)
                 {
                   *password = apr_pstrmemdup(pool, item->password, len);
-                  ret = TRUE;
+                  *done = TRUE;
                 }
             }
           gnome_keyring_network_password_list_free(items);
@@ -294,13 +341,14 @@ password_get_gnome_keyring(const char **
 
   free(default_keyring);
 
-  return ret;
+  return SVN_NO_ERROR;
 }
 
-/* Implementation of password_set_t that stores the password in
+/* Implementation of svn_auth__password_set_t that stores the password in
    GNOME Keyring. */
-static svn_boolean_t
-password_set_gnome_keyring(apr_hash_t *creds,
+static svn_error_t *
+password_set_gnome_keyring(svn_boolean_t *done,
+                           apr_hash_t *creds,
                            const char *realmstring,
                            const char *username,
                            const char *password,
@@ -312,11 +360,9 @@ password_set_gnome_keyring(apr_hash_t *c
   GnomeKeyringResult result;
   guint32 item_id;
 
-  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
-    return FALSE;
+  *done = FALSE;
 
-  if (! gnome_keyring_is_available())
-    return FALSE;
+  SVN_ERR(ensure_gnome_keyring_is_unlocked(non_interactive, parameters, pool));
 
   default_keyring = get_default_keyring_name(pool);
 
@@ -344,7 +390,8 @@ password_set_gnome_keyring(apr_hash_t *c
 
   free(default_keyring);
 
-  return result == GNOME_KEYRING_RESULT_OK;
+  *done = (result == GNOME_KEYRING_RESULT_OK);
+  return SVN_NO_ERROR;
 }
 
 /* Get cached encrypted credentials from the simple provider's cache. */
@@ -356,43 +403,6 @@ simple_gnome_keyring_first_creds(void **
                                  const char *realmstring,
                                  apr_pool_t *pool)
 {
-  svn_boolean_t non_interactive = apr_hash_get(parameters,
-                                               SVN_AUTH_PARAM_NON_INTERACTIVE,
-                                               APR_HASH_KEY_STRING) != NULL;
-  const char *default_keyring = get_default_keyring_name(pool);
-  if (! non_interactive)
-    {
-      svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
-        apr_hash_get(parameters,
-                     SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
-                     APR_HASH_KEY_STRING);
-      void *unlock_prompt_baton =
-        apr_hash_get(parameters, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
-                     APR_HASH_KEY_STRING);
-
-      char *keyring_password;
-
-      if (unlock_prompt_func && check_keyring_is_locked(default_keyring))
-        {
-          SVN_ERR((*unlock_prompt_func)(&keyring_password,
-                                        default_keyring,
-                                        unlock_prompt_baton,
-                                        pool));
-
-          /* If keyring is locked give up and try the next provider. */
-          if (! unlock_gnome_keyring(default_keyring, keyring_password, pool))
-            return SVN_NO_ERROR;
-        }
-    }
-  else
-    {
-      if (check_keyring_is_locked(default_keyring))
-        {
-          return svn_error_create(SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
-                                  _("GNOME Keyring is locked and "
-                                    "we are non-interactive"));
-        }
-    }
   return svn_auth__simple_first_creds_helper
            (credentials,
             iter_baton, provider_baton,
@@ -411,43 +421,6 @@ simple_gnome_keyring_save_creds(svn_bool
                                 const char *realmstring,
                                 apr_pool_t *pool)
 {
-  svn_boolean_t non_interactive = apr_hash_get(parameters,
-                                               SVN_AUTH_PARAM_NON_INTERACTIVE,
-                                               APR_HASH_KEY_STRING) != NULL;
-  const char *default_keyring = get_default_keyring_name(pool);
-  if (! non_interactive)
-    {
-      svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
-        apr_hash_get(parameters,
-                     SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
-                     APR_HASH_KEY_STRING);
-      void *unlock_prompt_baton =
-        apr_hash_get(parameters, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
-                     APR_HASH_KEY_STRING);
-
-      char *keyring_password;
-
-      if (unlock_prompt_func && check_keyring_is_locked(default_keyring))
-        {
-          SVN_ERR((*unlock_prompt_func)(&keyring_password,
-                                        default_keyring,
-                                        unlock_prompt_baton,
-                                        pool));
-
-          /* If keyring is locked give up and try the next provider. */
-          if (! unlock_gnome_keyring(default_keyring, keyring_password, pool))
-            return SVN_NO_ERROR;
-        }
-    }
-  else
-    {
-      if (check_keyring_is_locked(default_keyring))
-        {
-          return svn_error_create(SVN_ERR_AUTHN_CREDS_NOT_SAVED, NULL,
-                                  _("GNOME Keyring is locked and "
-                                    "we are non-interactive"));
-        }
-    }
   return svn_auth__simple_save_creds_helper
            (saved, credentials,
             provider_baton, parameters,
@@ -518,43 +491,6 @@ ssl_client_cert_pw_gnome_keyring_first_c
                                              const char *realmstring,
                                              apr_pool_t *pool)
 {
-  svn_boolean_t non_interactive = apr_hash_get(parameters,
-                                               SVN_AUTH_PARAM_NON_INTERACTIVE,
-                                               APR_HASH_KEY_STRING) != NULL;
-  const char *default_keyring = get_default_keyring_name(pool);
-  if (! non_interactive)
-    {
-      svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
-        apr_hash_get(parameters,
-                     SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
-                     APR_HASH_KEY_STRING);
-      void *unlock_prompt_baton =
-        apr_hash_get(parameters, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
-                     APR_HASH_KEY_STRING);
-
-      char *keyring_password;
-
-      if (unlock_prompt_func && check_keyring_is_locked(default_keyring))
-        {
-          SVN_ERR((*unlock_prompt_func)(&keyring_password,
-                                        default_keyring,
-                                        unlock_prompt_baton,
-                                        pool));
-
-          /* If keyring is locked give up and try the next provider. */
-          if (! unlock_gnome_keyring(default_keyring, keyring_password, pool))
-            return SVN_NO_ERROR;
-        }
-    }
-  else
-    {
-      if (check_keyring_is_locked(default_keyring))
-        {
-          return svn_error_create(SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
-                                  _("GNOME Keyring is locked and "
-                                    "we are non-interactive"));
-        }
-    }
   return svn_auth__ssl_client_cert_pw_file_first_creds_helper
            (credentials,
             iter_baton, provider_baton,
@@ -574,43 +510,6 @@ ssl_client_cert_pw_gnome_keyring_save_cr
                                             const char *realmstring,
                                             apr_pool_t *pool)
 {
-  svn_boolean_t non_interactive = apr_hash_get(parameters,
-                                               SVN_AUTH_PARAM_NON_INTERACTIVE,
-                                               APR_HASH_KEY_STRING) != NULL;
-  const char *default_keyring = get_default_keyring_name(pool);
-  if (! non_interactive)
-    {
-      svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
-        apr_hash_get(parameters,
-                     SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
-                     APR_HASH_KEY_STRING);
-      void *unlock_prompt_baton =
-        apr_hash_get(parameters, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
-                     APR_HASH_KEY_STRING);
-
-      char *keyring_password;
-
-      if (unlock_prompt_func && check_keyring_is_locked(default_keyring))
-        {
-          SVN_ERR((*unlock_prompt_func)(&keyring_password,
-                                        default_keyring,
-                                        unlock_prompt_baton,
-                                        pool));
-
-          /* If keyring is locked give up and try the next provider. */
-          if (! unlock_gnome_keyring(default_keyring, keyring_password, pool))
-            return SVN_NO_ERROR;
-         }
-    }
-  else
-    {
-      if (check_keyring_is_locked(default_keyring))
-        {
-          return svn_error_create(SVN_ERR_AUTHN_CREDS_NOT_SAVED, NULL,
-                                  _("GNOME Keyring is locked and "
-                                    "we are non-interactive"));
-        }
-    }
   return svn_auth__ssl_client_cert_pw_file_save_creds_helper
            (saved, credentials,
             provider_baton, parameters,

Modified: subversion/branches/svn-bisect/subversion/libsvn_auth_kwallet/kwallet.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_auth_kwallet/kwallet.cpp?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_auth_kwallet/kwallet.cpp (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_auth_kwallet/kwallet.cpp Mon Jul 30 06:39:28 2012
@@ -181,8 +181,9 @@ kwallet_terminate(void *data)
 
 /* Implementation of svn_auth__password_get_t that retrieves
    the password from KWallet. */
-static svn_boolean_t
-kwallet_password_get(const char **password,
+static svn_error_t *
+kwallet_password_get(svn_boolean_t *done,
+                     const char **password,
                      apr_hash_t *creds,
                      const char *realmstring,
                      const char *username,
@@ -190,14 +191,22 @@ kwallet_password_get(const char **passwo
                      svn_boolean_t non_interactive,
                      apr_pool_t *pool)
 {
-  if (non_interactive)
+  QString wallet_name = get_wallet_name(parameters);
+
+  *done = FALSE;
+
+  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
     {
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
-  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
+  if (non_interactive)
     {
-      return FALSE;
+      if (!KWallet::Wallet::isOpen(wallet_name))
+        return SVN_NO_ERROR;
+
+      /* There is a race here: the wallet was open just now, but will
+         it still be open when we come to use it below? */
     }
 
   QCoreApplication *app;
@@ -216,8 +225,6 @@ kwallet_password_get(const char **passwo
                      ki18n("Version control system"),
                      KCmdLineArgs::CmdLineArgKDE);
   KComponentData component_data(KCmdLineArgs::aboutData());
-  svn_boolean_t ret = FALSE;
-  QString wallet_name = get_wallet_name(parameters);
   QString folder = QString::fromUtf8("Subversion");
   QString key =
     QString::fromUtf8(username) + "@" + QString::fromUtf8(realmstring);
@@ -238,7 +245,7 @@ kwallet_password_get(const char **passwo
                   *password = apr_pstrmemdup(pool,
                                              q_password.toUtf8().data(),
                                              q_password.size());
-                  ret = TRUE;
+                  *done = TRUE;
                 }
             }
         }
@@ -246,13 +253,14 @@ kwallet_password_get(const char **passwo
 
   apr_pool_cleanup_register(pool, parameters, kwallet_terminate, NULL);
 
-  return ret;
+  return SVN_NO_ERROR;
 }
 
 /* Implementation of svn_auth__password_set_t that stores
    the password in KWallet. */
-static svn_boolean_t
-kwallet_password_set(apr_hash_t *creds,
+static svn_error_t *
+kwallet_password_set(svn_boolean_t *done,
+                     apr_hash_t *creds,
                      const char *realmstring,
                      const char *username,
                      const char *password,
@@ -260,14 +268,22 @@ kwallet_password_set(apr_hash_t *creds,
                      svn_boolean_t non_interactive,
                      apr_pool_t *pool)
 {
-  if (non_interactive)
+  QString wallet_name = get_wallet_name(parameters);
+
+  *done = FALSE;
+
+  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
     {
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
-  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
+  if (non_interactive)
     {
-      return FALSE;
+      if (!KWallet::Wallet::isOpen(wallet_name))
+        return SVN_NO_ERROR;
+
+      /* There is a race here: the wallet was open just now, but will
+         it still be open when we come to use it below? */
     }
 
   QCoreApplication *app;
@@ -286,9 +302,7 @@ kwallet_password_set(apr_hash_t *creds,
                      ki18n("Version control system"),
                      KCmdLineArgs::CmdLineArgKDE);
   KComponentData component_data(KCmdLineArgs::aboutData());
-  svn_boolean_t ret = FALSE;
   QString q_password = QString::fromUtf8(password);
-  QString wallet_name = get_wallet_name(parameters);
   QString folder = QString::fromUtf8("Subversion");
   KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
   if (wallet)
@@ -307,14 +321,14 @@ kwallet_password_set(apr_hash_t *creds,
             + QString::fromUtf8(realmstring);
           if (wallet->writePassword(key, q_password) == 0)
             {
-              ret = TRUE;
+              *done = TRUE;
             }
         }
     }
 
   apr_pool_cleanup_register(pool, parameters, kwallet_terminate, NULL);
 
-  return ret;
+  return SVN_NO_ERROR;
 }
 
 /* Get cached encrypted credentials from the simple provider's cache. */

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/add.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/add.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/add.c Mon Jul 30 06:39:28 2012
@@ -47,6 +47,7 @@
 
 #include "private/svn_client_private.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_ra_private.h"
 #include "private/svn_magic.h"
 
 #include "svn_private_config.h"
@@ -809,6 +810,11 @@ mkdir_urls(const apr_array_header_t *url
       const char *bname;
       svn_uri_split(&common, &bname, common, pool);
       APR_ARRAY_PUSH(targets, const char *) = bname;
+
+      if (*bname == '\0')
+        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                 _("There is no valid uri above '%s'"),
+                                 common);
     }
   else
     {
@@ -831,6 +837,12 @@ mkdir_urls(const apr_array_header_t *url
           const char *bname;
 
           svn_uri_split(&common, &bname, common, pool);
+
+          if (*bname == '\0')
+             return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                      _("There is no valid uri above '%s'"),
+                                      common);
+
           for (i = 0; i < targets->nelts; i++)
             {
               const char *path = APR_ARRAY_IDX(targets, i, const char *);
@@ -885,6 +897,9 @@ mkdir_urls(const apr_array_header_t *url
                                                  ctx, pool));
 
   /* Fetch RA commit editor */
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
+                        svn_client__get_shim_callbacks(ctx->wc_ctx,
+                                                       NULL, pool)));
   SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                     commit_revprops,
                                     commit_callback,

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/checkout.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/checkout.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/checkout.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/checkout.c Mon Jul 30 06:39:28 2012
@@ -73,7 +73,6 @@ svn_client__checkout_internal(svn_revnum
                               const char *local_abspath,
                               const svn_opt_revision_t *peg_revision,
                               const svn_opt_revision_t *revision,
-                              const svn_client__ra_session_from_path_results *ra_cache,
                               svn_depth_t depth,
                               svn_boolean_t ignore_externals,
                               svn_boolean_t allow_unver_obstructions,
@@ -88,6 +87,10 @@ svn_client__checkout_internal(svn_revnum
   const char *session_url;
   svn_node_kind_t kind;
   const char *uuid, *repos_root;
+  apr_pool_t *session_pool = svn_pool_create(pool);
+  svn_ra_session_t *ra_session;
+  svn_revnum_t tmp_revnum;
+  const char *tmp_session_url;
 
   /* Sanity check.  Without these, the checkout is meaningless. */
   SVN_ERR_ASSERT(local_abspath != NULL);
@@ -100,60 +103,19 @@ svn_client__checkout_internal(svn_revnum
       && (revision->kind != svn_opt_revision_head))
     return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
 
-  {
-    svn_boolean_t have_repos_root_url;
-    svn_boolean_t have_repos_uuid;
-    svn_boolean_t have_session_url;
-    svn_boolean_t have_revnum;
-    svn_boolean_t have_kind;
-
-    if ((have_repos_root_url = (ra_cache && ra_cache->repos_root_url)))
-      repos_root = ra_cache->repos_root_url;
-
-    if ((have_repos_uuid = (ra_cache && ra_cache->repos_uuid)))
-      uuid = ra_cache->repos_uuid;
-
-    if ((have_session_url = (ra_cache && ra_cache->ra_session_url)))
-      session_url = ra_cache->ra_session_url;
-
-    if ((have_revnum = (ra_cache && SVN_IS_VALID_REVNUM(ra_cache->ra_revnum))))
-      revnum = ra_cache->ra_revnum;
-
-    if ((have_kind = (ra_cache && ra_cache->kind != svn_node_unknown)))
-      kind = ra_cache->kind;
-
-    if (! have_repos_root_url || ! have_repos_uuid || ! have_session_url ||
-        ! have_revnum || ! have_kind)
-      {
-        apr_pool_t *session_pool = svn_pool_create(pool);
-        svn_ra_session_t *ra_session;
-        svn_revnum_t tmp_revnum;
-        const char *tmp_session_url;
-
-        /* Get the RA connection. */
-        SVN_ERR(svn_client__ra_session_from_path(&ra_session, &tmp_revnum,
-                                                 &tmp_session_url, url, NULL,
-                                                 peg_revision, revision, ctx,
-                                                 session_pool));
-
-        if (! have_repos_root_url)
-          SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
-
-        if (! have_repos_uuid)
-          SVN_ERR(svn_ra_get_uuid2(ra_session, &uuid, pool));
-
-        if (! have_session_url)
-          session_url = apr_pstrdup(pool, tmp_session_url);
-
-        if (! have_revnum)
-          revnum = tmp_revnum;
-
-        if (! have_kind)
-          SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));
-
-        svn_pool_destroy(session_pool);
-      }
-  }
+  /* Get the RA connection. */
+  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &tmp_revnum,
+                                           &tmp_session_url, url, NULL,
+                                           peg_revision, revision, ctx,
+                                           session_pool));
+
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
+  SVN_ERR(svn_ra_get_uuid2(ra_session, &uuid, pool));
+  session_url = apr_pstrdup(pool, tmp_session_url);
+  revnum = tmp_revnum;
+  SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));
+
+  svn_pool_destroy(session_pool);
 
   if (kind == svn_node_none)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
@@ -253,7 +215,7 @@ svn_client_checkout3(svn_revnum_t *resul
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
 
   return svn_client__checkout_internal(result_rev, URL, local_abspath,
-                                       peg_revision, revision, NULL, depth,
+                                       peg_revision, revision, depth,
                                        ignore_externals,
                                        allow_unver_obstructions, NULL,
                                        ctx, pool);

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/client.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/client.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/client.h Mon Jul 30 06:39:28 2012
@@ -148,7 +148,9 @@ svn_client__repos_locations(const char *
  *
  * Set *OP_URL to the URL that the object PEG_URL@PEG_REVNUM had in
  * revision OP_REVNUM.
- * RA_SESSION is required. */
+ *
+ * RA_SESSION is an open RA session to the correct repository; it may be
+ * temporarily reparented inside this function. */
 svn_error_t *
 svn_client__repos_location(const char **start_url,
                            svn_ra_session_t *ra_session,
@@ -161,8 +163,8 @@ svn_client__repos_location(const char **
 
 
 /* Set *SEGMENTS to an array of svn_location_segment_t * objects, each
-   representing a reposition location segment for the history of PATH
-   (which is relative to RA_SESSION's session URL) in PEG_REVISION
+   representing a reposition location segment for the history of URL
+   in PEG_REVISION
    between END_REVISION and START_REVISION, ordered from oldest
    segment to youngest.  *SEGMENTS may be empty but it will never
    be NULL.
@@ -171,13 +173,16 @@ svn_client__repos_location(const char **
    svn_ra_get_location_segments() interface, which see for the rules
    governing PEG_REVISION, START_REVISION, and END_REVISION.
 
+   RA_SESSION is an RA session open to the repository of URL; it may be
+   temporarily reparented within this function.
+
    CTX is the client context baton.
 
    Use POOL for all allocations.  */
 svn_error_t *
 svn_client__repos_location_segments(apr_array_header_t **segments,
                                     svn_ra_session_t *ra_session,
-                                    const char *path,
+                                    const char *url,
                                     svn_revnum_t peg_revision,
                                     svn_revnum_t start_revision,
                                     svn_revnum_t end_revision,
@@ -185,19 +190,30 @@ svn_client__repos_location_segments(apr_
                                     apr_pool_t *pool);
 
 
-/* Set *ANCESTOR_PATH and *ANCESTOR_REVISION to the youngest common
-   ancestor path (a path relative to the root of the repository) and
-   revision, respectively, of the two locations identified as
-   PATH_OR_URL1@REV1 and PATH_OR_URL2@REV1.  Use the authentication
-   baton cached in CTX to authenticate against the repository.
-   This function assumes that PATH_OR_URL1@REV1 and PATH_OR_URL2@REV1
-   both refer to the same repository.  Use POOL for all allocations. */
+/* Find the common ancestor of two locations in a repository.
+   Ancestry is determined by the 'copy-from' relationship and the normal
+   successor relationship.
+
+   Set *ANCESTOR_RELPATH, *ANCESTOR_URL, and *ANCESTOR_REVISION to the
+   path (relative to the root of the repository, with no leading '/'),
+   URL, and revision, respectively, of the youngest common ancestor of
+   the two locations URL1@REV1 and URL2@REV2.  Set *ANCESTOR_RELPATH and
+   *ANCESTOR_URL to NULL and *ANCESTOR_REVISION to SVN_INVALID_REVNUM if
+   they have no common ancestor.  This function assumes that URL1@REV1
+   and URL2@REV2 both refer to the same repository.
+
+   Use the authentication baton cached in CTX to authenticate against
+   the repository.  Use POOL for all allocations.
+
+   See also svn_client__youngest_common_ancestor().
+*/
 svn_error_t *
-svn_client__get_youngest_common_ancestor(const char **ancestor_path,
+svn_client__get_youngest_common_ancestor(const char **ancestor_relpath,
+                                         const char **ancestor_url,
                                          svn_revnum_t *ancestor_revision,
-                                         const char *path_or_url1,
+                                         const char *url1,
                                          svn_revnum_t rev1,
-                                         const char *path_or_url2,
+                                         const char *url2,
                                          svn_revnum_t rev2,
                                          svn_client_ctx_t *ctx,
                                          apr_pool_t *pool);
@@ -238,11 +254,10 @@ svn_client__ra_session_from_path(svn_ra_
                                  apr_pool_t *pool);
 
 /* Ensure that RA_SESSION's session URL matches SESSION_URL,
-   reparenting that session if necessary.  If reparenting occurs,
-   store the previous session URL in *OLD_SESSION_URL (so that if the
+   reparenting that session if necessary.
+   Store the previous session URL in *OLD_SESSION_URL (so that if the
    reparenting is meant to be temporary, the caller can reparent the
-   session back to where it was); otherwise set *OLD_SESSION_URL to
-   NULL.
+   session back to where it was).
 
    If SESSION_URL is NULL, treat this as a magic value meaning "point
    the RA session to the root of the repository".
@@ -257,8 +272,7 @@ svn_client__ra_session_from_path(svn_ra_
 
        [...]
 
-       if (old_session_url)
-         SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
+       SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
 */
 svn_error_t *
 svn_client__ensure_ra_session_url(const char **old_session_url,
@@ -485,36 +499,6 @@ svn_client__update_internal(svn_revnum_t
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool);
 
-/* Structure holding the results of svn_client__ra_session_from_path()
-   plus the repository root URL and UUID and the node kind for the
-   input URL, REVISION and PEG_REVISION .  See
-   svn_client__ra_session_from_path() for the meaning of these fields.
-   This structure is used by svn_client__checkout_internal() to save
-   one or more round-trips if the client already gathered some of this
-   information.  Not all the fields need to be filled in.  */
-typedef struct svn_client__ra_session_from_path_results
-{
-  /* The repository root URL.  A NULL value means the root URL is
-     unknown.*/
-  const char *repos_root_url;
-
-  /* The repository UUID.  A NULL value means the UUID is unknown.  */
-  const char *repos_uuid;
-
-  /* The actual final resulting URL for the input URL.  This may be
-     different because of copy history.  A NULL value means the
-     resulting URL is unknown.  */
-  const char *ra_session_url;
-
-  /* The actual final resulting revision for the input URL.  An
-     invalid revnum as determined by SVN_IS_VALID_REVNUM() means the
-     revnum is unknown.  */
-  svn_revnum_t ra_revnum;
-
-  /* An optional node kind for the URL.  svn_node_unknown if unknown */
-  svn_node_kind_t kind;
-} svn_client__ra_session_from_path_results;
-
 /* Checkout into LOCAL_ABSPATH a working copy of URL at REVISION, and (if not
    NULL) set RESULT_REV to the checked out revision.
 
@@ -551,7 +535,6 @@ svn_client__checkout_internal(svn_revnum
                               const char *local_abspath,
                               const svn_opt_revision_t *peg_revision,
                               const svn_opt_revision_t *revision,
-                              const svn_client__ra_session_from_path_results *ra_cache,
                               svn_depth_t depth,
                               svn_boolean_t ignore_externals,
                               svn_boolean_t allow_unver_obstructions,
@@ -1090,6 +1073,11 @@ svn_client__get_normalized_stream(svn_st
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool);
 
+/* Return a set of callbacks to use with the Ev2 shims. */
+svn_delta_shim_callbacks_t *
+svn_client__get_shim_callbacks(svn_wc_context_t *wc_ctx,
+                               const char *anchor_abspath,
+                               apr_pool_t *result_pool);
 
 /* Return true if KIND is a revision kind that is dependent on the working
  * copy. Otherwise, return false. */

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/cmdline.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/cmdline.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/cmdline.c Mon Jul 30 06:39:28 2012
@@ -168,7 +168,6 @@ svn_client_args_to_target_array2(apr_arr
   int i;
   svn_boolean_t rel_url_found = FALSE;
   const char *root_url = NULL;
-  svn_error_t *err = SVN_NO_ERROR;
   apr_array_header_t *input_targets =
     apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
   apr_array_header_t *output_targets =
@@ -348,6 +347,7 @@ svn_client_args_to_target_array2(apr_arr
       if (root_url == NULL)
         {
           const char *current_abspath;
+          svn_error_t *err;
 
           SVN_ERR(svn_dirent_get_absolute(&current_abspath, "", pool));
           err = svn_client_get_repos_root(&root_url, NULL /* uuid */,
@@ -391,11 +391,17 @@ svn_client_args_to_target_array2(apr_arr
   else
     *targets_p = output_targets;
 
-  if (reserved_names && ! err)
-    for (i = 0; i < reserved_names->nelts; ++i)
-      err = svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED, err,
-                              _("'%s' ends in a reserved name"),
-                              APR_ARRAY_IDX(reserved_names, i, const char *));
+  if (reserved_names)
+    {
+      svn_error_t *err = SVN_NO_ERROR;
+
+      for (i = 0; i < reserved_names->nelts; ++i)
+        err = svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED, err,
+                                _("'%s' ends in a reserved name"),
+                                APR_ARRAY_IDX(reserved_names, i,
+                                              const char *));
+      return svn_error_trace(err);
+    }
 
-  return svn_error_trace(err);
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/commit.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/commit.c Mon Jul 30 06:39:28 2012
@@ -49,6 +49,7 @@
 
 #include "client.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_ra_private.h"
 #include "private/svn_magic.h"
 
 #include "svn_private_config.h"
@@ -145,19 +146,22 @@ send_file_contents(const char *path,
       if (svn_subst_translation_required(eol_style, eol, keywords,
                                          FALSE, TRUE))
         {
-          svn_boolean_t repair = FALSE;
+          if (eol_style == svn_subst_eol_style_unknown)
+            return svn_error_createf(SVN_ERR_IO_UNKNOWN_EOL, NULL,
+                                    _("%s property on '%s' contains "
+                                      "unrecognized EOL-style '%s'"),
+                                    SVN_PROP_EOL_STYLE, path,
+                                    eol_style_val->data);
 
+          /* We're importing, so translate files with 'native' eol-style to
+           * repository-normal form, not to this platform's native EOL. */
           if (eol_style == svn_subst_eol_style_native)
             eol = SVN_SUBST_NATIVE_EOL_STR;
-          else if (eol_style == svn_subst_eol_style_fixed)
-            repair = TRUE;
-          else if (eol_style != svn_subst_eol_style_none)
-            return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
 
           /* Wrap the working copy stream with a filter to detranslate it. */
           contents = svn_subst_stream_translated(contents,
                                                  eol,
-                                                 repair,
+                                                 TRUE /* repair */,
                                                  keywords,
                                                  FALSE /* expand */,
                                                  pool);
@@ -642,6 +646,7 @@ get_ra_editor(svn_ra_session_t **ra_sess
               apr_pool_t *pool)
 {
   apr_hash_t *commit_revprops;
+  const char *anchor_abspath;
 
   /* Open an RA session to URL. */
   SVN_ERR(svn_client__open_ra_session_internal(ra_session, NULL, base_url,
@@ -666,7 +671,22 @@ get_ra_editor(svn_ra_session_t **ra_sess
   SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
                                            log_msg, ctx, pool));
 
+  /* We need this for the shims. */
+  if (base_dir_abspath)
+    {
+      const char *relpath;
+
+      SVN_ERR(svn_ra_get_path_relative_to_root(*ra_session, &relpath, base_url,
+                                               pool));
+      anchor_abspath = svn_dirent_join(base_dir_abspath, relpath, pool);
+    }
+  else
+    anchor_abspath = NULL;
+
   /* Fetch RA commit editor. */
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(*ra_session,
+                        svn_client__get_shim_callbacks(ctx->wc_ctx,
+                                                       anchor_abspath, pool)));
   SVN_ERR(svn_ra_get_commit_editor3(*ra_session, editor, edit_baton,
                                     commit_revprops, commit_callback,
                                     commit_baton, lock_tokens, keep_locks,
@@ -822,7 +842,7 @@ svn_client_import4(const char *path,
                     ignore_unknown_node_types, ctx, subpool)))
     {
       svn_error_clear(editor->abort_edit(edit_baton, subpool));
-      return err;
+      return svn_error_trace(err);
     }
 
   svn_pool_destroy(subpool);

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/commit_util.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/commit_util.c Mon Jul 30 06:39:28 2012
@@ -416,6 +416,10 @@ bail_on_tree_conflicted_ancestor(svn_wc_
    by recursing deeper into a dir target. (This is used to skip all file
    externals that aren't explicit commit targets.)
 
+   DANGLERS is a hash table mapping const char* absolute paths of a parent
+   to a const char * absolute path of a child. See the comment about
+   danglers at the top of svn_client__harvest_committables().
+
    If CANCEL_FUNC is non-null, call it with CANCEL_BATON to see
    if the user has cancelled the operation.
 
@@ -435,6 +439,7 @@ harvest_committables(svn_wc_context_t *w
                      svn_boolean_t skip_files,
                      svn_boolean_t skip_dirs,
                      svn_boolean_t is_explicit_target,
+                     apr_hash_t *danglers,
                      svn_client__check_url_kind_t check_url_func,
                      void *check_url_baton,
                      svn_cancel_func_t cancel_func,
@@ -627,7 +632,7 @@ harvest_committables(svn_wc_context_t *w
 
           /* Determine from what parent we would be the deleted child */
           SVN_ERR(svn_wc__node_get_origin(NULL, &revision, &repos_relpath,
-                                          NULL, NULL, wc_ctx,
+                                          NULL, NULL, NULL, wc_ctx,
                                           svn_dirent_dirname(local_abspath,
                                                              scratch_pool),
                                           FALSE, scratch_pool, scratch_pool));
@@ -684,7 +689,7 @@ harvest_committables(svn_wc_context_t *w
 
           SVN_ERR(svn_wc__node_get_origin(NULL, &cf_rev,
                                       &cf_relpath, NULL,
-                                      NULL,
+                                      NULL, NULL,
                                       wc_ctx, local_abspath, FALSE,
                                       scratch_pool, scratch_pool));
 
@@ -814,6 +819,45 @@ harvest_committables(svn_wc_context_t *w
         }
     }
 
+  /* Make sure we check for dangling children on additions */
+  if (state_flags && is_added && is_explicit_target && danglers)
+    {
+      /* If a node is added, it's parent must exist in the repository at the
+         time of committing */
+
+      svn_boolean_t parent_added;
+      const char *parent_abspath = svn_dirent_dirname(local_abspath,
+                                                      scratch_pool);
+
+      SVN_ERR(svn_wc__node_is_added(&parent_added, wc_ctx, parent_abspath,
+                                    scratch_pool));
+
+      if (parent_added)
+        {
+          const char *copy_root_abspath;
+          svn_boolean_t parent_is_copy;
+
+          /* The parent is added, so either it is a copy, or a locally added
+           * directory. In either case, we require the op-root of the parent
+           * to be part of the commit. See issue #4059. */
+          SVN_ERR(svn_wc__node_get_origin(&parent_is_copy, NULL, NULL, NULL,
+                                          NULL, &copy_root_abspath,
+                                          wc_ctx, parent_abspath,
+                                          FALSE, scratch_pool, scratch_pool));
+
+          if (parent_is_copy)
+            parent_abspath = copy_root_abspath;
+
+          if (!apr_hash_get(danglers, parent_abspath, APR_HASH_KEY_STRING))
+            {
+              apr_hash_set(danglers,
+                           apr_pstrdup(result_pool, parent_abspath),
+                           APR_HASH_KEY_STRING,
+                           apr_pstrdup(result_pool, local_abspath));
+            }
+        }
+    }
+
   if (db_kind != svn_node_dir || depth <= svn_depth_empty)
     return SVN_NO_ERROR;
 
@@ -863,6 +907,7 @@ harvest_committables(svn_wc_context_t *w
                                        (depth < svn_depth_files),
                                        (depth < svn_depth_immediates),
                                        FALSE, /* IS_EXPLICIT_TARGET */
+                                       danglers,
                                        check_url_func, check_url_baton,
                                        cancel_func, cancel_baton,
                                        notify_func, notify_baton,
@@ -1032,13 +1077,13 @@ svn_client__harvest_committables(svn_cli
    * Since we don't know what's included in the commit until we've
    * harvested all the targets, we can't reliably check this as we
    * go.  So in `danglers', we record named targets whose parents
-   * are unversioned, then after harvesting the total commit group, we
-   * check to make sure those parents are included.
+   * do not yet exist in the repository. Then after harvesting the total
+   * commit group, we check to make sure those parents are included.
    *
-   * Each key of danglers is an unversioned parent.  The (const char *)
-   * value is one of that parent's children which is named as part of
-   * the commit; the child is included only to make a better error
-   * message.
+   * Each key of danglers is a parent which does not exist in the
+   * repository.  The (const char *) value is one of that parent's
+   * children which is named as part of the commit; the child is
+   * included only to make a better error message.
    *
    * (The reason we don't bother to check unnamed -- i.e, implicit --
    * targets is that they can only join the commit if their parents
@@ -1063,10 +1108,8 @@ svn_client__harvest_committables(svn_cli
   for (i = 0; i < targets->nelts; ++i)
     {
       const char *target_abspath;
-      svn_boolean_t is_added;
       svn_node_kind_t kind;
       const char *repos_root_url;
-      svn_error_t *err;
 
       svn_pool_clear(iterpool);
 
@@ -1103,35 +1146,6 @@ svn_client__harvest_committables(svn_cli
                                           target_abspath,
                                           result_pool, iterpool));
 
-      /* Handle an added/replaced node. */
-      SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, target_abspath,
-                                    iterpool));
-      if (is_added)
-        {
-          /* This node is added. Is the parent also added? */
-          const char *parent_abspath = svn_dirent_dirname(target_abspath,
-                                                          iterpool);
-          err = svn_wc__node_is_added(&is_added, ctx->wc_ctx, parent_abspath,
-                                      iterpool);
-          if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-            return svn_error_createf(
-                SVN_ERR_WC_CORRUPT, err,
-                _("'%s' is scheduled for addition within unversioned parent"),
-                svn_dirent_local_style(target_abspath, iterpool));
-          SVN_ERR(err);
-
-          if (is_added)
-            {
-              /* Copy the parent and target into pool; iterpool
-                 lasts only for this loop iteration, and we check
-                 danglers after the loop is over. */
-              apr_hash_set(danglers,
-                           apr_pstrdup(scratch_pool, parent_abspath),
-                           APR_HASH_KEY_STRING,
-                           apr_pstrdup(scratch_pool, target_abspath));
-            }
-        }
-
       /* Handle our TARGET. */
       /* Make sure this isn't inside a working copy subtree that is
        * marked as tree-conflicted. */
@@ -1148,6 +1162,7 @@ svn_client__harvest_committables(svn_cli
                                    depth, just_locked, changelist_hash,
                                    FALSE, FALSE,
                                    TRUE /* IS_EXPLICIT_TARGET */,
+                                   danglers,
                                    check_url_func, check_url_baton,
                                    ctx->cancel_func, ctx->cancel_baton,
                                    ctx->notify_func2, ctx->notify_baton2,
@@ -1170,31 +1185,31 @@ svn_client__harvest_committables(svn_cli
 
       svn_pool_clear(iterpool);
 
-       if (! look_up_committable(*committables, dangling_parent, iterpool))
-         {
-           const char *dangling_child = svn__apr_hash_index_val(hi);
-
-           if (ctx->notify_func2 != NULL)
-             {
-               svn_wc_notify_t *notify;
-
-               notify = svn_wc_create_notify(dangling_child,
-                                             svn_wc_notify_failed_no_parent,
-                                             scratch_pool);
-
-               ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
-             }
-
-           return svn_error_createf(
-                            SVN_ERR_ILLEGAL_TARGET, NULL,
-                            _("'%s' is not under version control "
-                              "and is not part of the commit, "
-                              "yet its child '%s' is part of the commit"),
-                            /* Probably one or both of these is an entry, but
-                               safest to local_stylize just in case. */
-                            svn_dirent_local_style(dangling_parent, iterpool),
-                            svn_dirent_local_style(dangling_child, iterpool));
-         }
+      if (! look_up_committable(*committables, dangling_parent, iterpool))
+        {
+          const char *dangling_child = svn__apr_hash_index_val(hi);
+
+          if (ctx->notify_func2 != NULL)
+            {
+              svn_wc_notify_t *notify;
+
+              notify = svn_wc_create_notify(dangling_child,
+                                            svn_wc_notify_failed_no_parent,
+                                            scratch_pool);
+
+              ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
+            }
+
+          return svn_error_createf(
+                           SVN_ERR_ILLEGAL_TARGET, NULL,
+                           _("'%s' is not known to exist in the repository "
+                             "and is not part of the commit, "
+                             "yet its child '%s' is part of the commit"),
+                           /* Probably one or both of these is an entry, but
+                              safest to local_stylize just in case. */
+                           svn_dirent_local_style(dangling_parent, iterpool),
+                           svn_dirent_local_style(dangling_child, iterpool));
+        }
     }
 
   svn_pool_destroy(iterpool);
@@ -1242,6 +1257,7 @@ harvest_copy_committables(void *baton, v
                                NULL,
                                FALSE, FALSE, /* skip files, dirs */
                                TRUE, /* IS_EXPLICIT_TARGET (don't care) */
+                               NULL,
                                btn->check_url_func,
                                btn->check_url_baton,
                                btn->ctx->cancel_func,

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/copy.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/copy.c Mon Jul 30 06:39:28 2012
@@ -44,6 +44,7 @@
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_ra_private.h"
 #include "private/svn_mergeinfo_private.h"
 
 
@@ -98,7 +99,7 @@ calculate_target_mergeinfo(svn_ra_sessio
 
       SVN_ERR(svn_wc__node_get_origin(NULL, &src_revnum,
                                       &repos_relpath, &repos_root_url,
-                                      NULL,
+                                      NULL, NULL,
                                       ctx->wc_ctx, local_abspath, FALSE,
                                       pool, pool));
 
@@ -113,20 +114,11 @@ calculate_target_mergeinfo(svn_ra_sessio
 
   if (! locally_added)
     {
-      /* Fetch any existing (explicit) mergeinfo.  We'll temporarily
-         reparent to the target URL here, just to keep the code simple.
-         We could, as an alternative, first see if the target URL was a
-         child of the session URL and use the relative "remainder",
-         falling back to this reparenting as necessary.  */
-      const char *old_session_url = NULL;
-      SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
-                                                ra_session, src_url, pool));
+      /* Fetch any existing (explicit) mergeinfo. */
       SVN_ERR(svn_client__get_repos_mergeinfo(&src_mergeinfo, ra_session,
-                                              "", src_revnum,
+                                              src_url, src_revnum,
                                               svn_mergeinfo_inherited,
                                               TRUE, pool));
-      if (old_session_url)
-        SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
     }
 
   *target_mergeinfo = src_mergeinfo;
@@ -981,7 +973,7 @@ repos_to_repos_copy(const apr_array_head
         }
       else
         {
-          const char *old_url = NULL;
+          const char *old_url;
 
           src_rel = NULL;
           SVN_ERR_ASSERT(! is_move);
@@ -1098,6 +1090,9 @@ repos_to_repos_copy(const apr_array_head
                                            message, ctx, pool));
 
   /* Fetch RA commit editor. */
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
+                        svn_client__get_shim_callbacks(ctx->wc_ctx,
+                                                       NULL, pool)));
   SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                     commit_revprops,
                                     commit_callback,
@@ -1410,6 +1405,9 @@ wc_to_repos_copy(const apr_array_header_
                                                FALSE, FALSE, ctx, pool));
 
   /* Fetch RA commit editor. */
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
+                        svn_client__get_shim_callbacks(ctx->wc_ctx,
+                                                       NULL, pool)));
   SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                     commit_revprops,
                                     commit_callback,
@@ -1512,7 +1510,7 @@ repos_to_wc_copy_single(svn_client__copy
                                             pair->src_original,
                                             tmp_abspath,
                                             &pair->src_peg_revision,
-                                            &pair->src_op_revision, NULL,
+                                            &pair->src_op_revision,
                                             svn_depth_infinity,
                                             ignore_externals, FALSE,
                                             &sleep_needed, ctx, pool);
@@ -1567,27 +1565,18 @@ repos_to_wc_copy_single(svn_client__copy
 
   else if (pair->src_kind == svn_node_file)
     {
-      svn_stream_t *fstream;
-      const char *new_text_path;
       apr_hash_t *new_props;
       const char *src_rel;
-      svn_stream_t *new_base_contents;
-
-      SVN_ERR(svn_stream_open_unique(&fstream, &new_text_path, NULL,
-                                     svn_io_file_del_on_pool_cleanup, pool,
-                                     pool));
+      svn_stream_t *new_base_contents = svn_stream_buffered(pool);
 
       SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel,
                                                   pair->src_abspath_or_url,
                                                   pool));
       /* Fetch the file content. While doing so, resolve pair->src_revnum
        * to an actual revision number if it's 'invalid' meaning 'head'. */
-      SVN_ERR(svn_ra_get_file(ra_session, src_rel, pair->src_revnum, fstream,
+      SVN_ERR(svn_ra_get_file(ra_session, src_rel, pair->src_revnum,
+                              new_base_contents,
                               &pair->src_revnum, &new_props, pool));
-      SVN_ERR(svn_stream_close(fstream));
-
-      SVN_ERR(svn_stream_open_readonly(&new_base_contents, new_text_path,
-                                       pool, pool));
       SVN_ERR(svn_wc_add_repos_file4(
          ctx->wc_ctx, dst_abspath,
          new_base_contents, NULL, new_props, NULL,
@@ -2127,7 +2116,7 @@ try_copy(const apr_array_header_t *sourc
                   SVN_ERR(svn_wc__node_get_origin(NULL, &copyfrom_rev,
                                                   &copyfrom_repos_relpath,
                                                   &copyfrom_repos_root_url,
-                                                  NULL,
+                                                  NULL, NULL,
                                                   ctx->wc_ctx,
                                                   pair->src_abspath_or_url,
                                                   TRUE, iterpool, iterpool));

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/delete.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/delete.c Mon Jul 30 06:39:28 2012
@@ -39,6 +39,7 @@
 
 #include "private/svn_client_private.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_ra_private.h"
 
 #include "svn_private_config.h"
 
@@ -187,6 +188,9 @@ single_repos_delete(svn_ra_session_t *ra
                                            log_msg, ctx, pool));
 
   /* Fetch RA commit editor */
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
+                        svn_client__get_shim_callbacks(ctx->wc_ctx,
+                                                       NULL, pool)));
   SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                     commit_revprops,
                                     commit_callback,
@@ -272,6 +276,12 @@ delete_urls_multi_repos(const apr_array_
           APR_ARRAY_PUSH(relpaths_list, const char *) = repos_relpath;
         }
 
+      /* Check we identified a non-root relpath.  Return an RA error
+         code for 1.6 compatibility. */
+      if (!repos_relpath || !*repos_relpath)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 "URL '%s' not within a repository", uri);
+
       /* Now, test to see if the thing actually exists. */
       SVN_ERR(svn_ra_check_path(ra_session, repos_relpath, SVN_INVALID_REVNUM,
                                 &kind, pool));

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/deprecated.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/deprecated.c Mon Jul 30 06:39:28 2012
@@ -864,7 +864,7 @@ svn_client_diff5(const apr_array_header_
   return svn_client_diff6(diff_options, path1, revision1, path2,
                           revision2, relative_to_dir, depth,
                           ignore_ancestry, no_diff_deleted,
-                          show_copies_as_adds, ignore_content_type,
+                          show_copies_as_adds, ignore_content_type, FALSE,
                           use_git_diff_format, header_encoding,
                           outstream, errstream, changelists, ctx, pool);
 }
@@ -992,6 +992,7 @@ svn_client_diff_peg5(const apr_array_hea
                               no_diff_deleted,
                               show_copies_as_adds,
                               ignore_content_type,
+                              FALSE,
                               use_git_diff_format,
                               header_encoding,
                               outstream,

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/diff.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/diff.c Mon Jul 30 06:39:28 2012
@@ -147,18 +147,25 @@ display_mergeinfo_diff(const char *old_m
    If TOKEN is empty, or is already terminated by an EOL marker,
    return TOKEN unmodified. Else, return a new string consisting
    of the concatenation of TOKEN and the system's default EOL marker.
-   The new string is allocated from POOL. */
+   The new string is allocated from POOL.
+   If HAD_EOL is not NULL, indicate in *HAD_EOL if the token had a EOL. */
 static const svn_string_t *
-maybe_append_eol(const svn_string_t *token, apr_pool_t *pool)
+maybe_append_eol(const svn_string_t *token, svn_boolean_t *had_eol,
+                 apr_pool_t *pool)
 {
   const char *curp;
 
+  if (had_eol)
+    *had_eol = FALSE;
+
   if (token->len == 0)
     return token;
 
   curp = token->data + token->len - 1;
   if (*curp == '\r')
     {
+      if (had_eol)
+        *had_eol = TRUE;
       return token;
     }
   else if (*curp != '\n')
@@ -167,6 +174,8 @@ maybe_append_eol(const svn_string_t *tok
     }
   else
     {
+      if (had_eol)
+        *had_eol = TRUE;
       return token;
     }
 }
@@ -665,18 +674,19 @@ display_prop_diffs(const apr_array_heade
         const svn_string_t *tmp;
         const svn_string_t *orig;
         const svn_string_t *val;
+        svn_boolean_t val_has_eol;
 
         /* The last character in a property is often not a newline.
-           Since the diff is not useful anyway for patching properties an
-           eol character is appended when needed to remove those pescious
-           ' \ No newline at end of file' lines. */
+           An eol character is appended to prevent the diff API to add a
+           ' \ No newline at end of file' line. We add 
+           ' \ No newline at end of property' manually if needed. */
         tmp = original_value ? original_value 
                              : svn_string_create_empty(iterpool);
-        orig = maybe_append_eol(tmp, iterpool);
+        orig = maybe_append_eol(tmp, NULL, iterpool);
 
         tmp = propchange->value ? propchange->value :
                                   svn_string_create_empty(iterpool);
-        val = maybe_append_eol(tmp, iterpool);
+        val = maybe_append_eol(tmp, &val_has_eol, iterpool);
 
         SVN_ERR(svn_diff_mem_string_diff(&diff, orig, val, &options,
                                          iterpool));
@@ -695,7 +705,12 @@ display_prop_diffs(const apr_array_heade
                                            svn_dirent_local_style(path,
                                                                   iterpool),
                                            encoding, orig, val, iterpool));
-
+        if (!val_has_eol)
+          {
+            const char *s = "\\ No newline at end of property" APR_EOL_STR;
+            apr_size_t len = strlen(s);
+            SVN_ERR(svn_stream_write(outstream, s, &len));
+          }
       }
     }
   svn_pool_destroy(iterpool);
@@ -762,6 +777,9 @@ struct diff_cmd_baton {
      relative to for output generation (see issue #2723). */
   const char *relative_to_dir;
 
+  /* Whether property differences are ignored. */
+  svn_boolean_t ignore_prop_diff;
+
   /* Whether we're producing a git-style diff. */
   svn_boolean_t use_git_diff_format;
 
@@ -802,6 +820,10 @@ diff_props_changed(svn_wc_notify_state_t
   apr_array_header_t *props;
   svn_boolean_t show_diff_header;
 
+  /* If property differences are ignored, there's nothing to do. */
+  if (diff_cmd_baton->ignore_prop_diff)
+    return SVN_NO_ERROR;
+
   SVN_ERR(svn_categorize_props(propchanges, NULL, NULL, &props,
                                scratch_pool));
 
@@ -1592,7 +1614,7 @@ diff_prepare_repos_repos(const char **ur
                                  *url1, *rev1, *rev2);
       else
         return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
-                                 _("Diff targets '%s and '%s' were not found "
+                                 _("Diff targets '%s' and '%s' were not found "
                                    "in the repository at revisions '%ld' and "
                                    "'%ld'"),
                                  *url1, *url2, *rev1, *rev2);
@@ -1988,7 +2010,7 @@ diff_repos_wc(const char *path_or_url1,
   SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
                                 SVN_RA_CAPABILITY_DEPTH, pool));
 
-  SVN_ERR(svn_wc_get_diff_editor6(&diff_editor, &diff_edit_baton,
+  SVN_ERR(svn_wc__get_diff_editor(&diff_editor, &diff_edit_baton,
                                   ctx->wc_ctx,
                                   anchor_abspath,
                                   target,
@@ -2398,6 +2420,7 @@ svn_client_diff6(const apr_array_header_
                  svn_boolean_t no_diff_deleted,
                  svn_boolean_t show_copies_as_adds,
                  svn_boolean_t ignore_content_type,
+                 svn_boolean_t ignore_prop_diff,
                  svn_boolean_t use_git_diff_format,
                  const char *header_encoding,
                  svn_stream_t *outstream,
@@ -2427,6 +2450,7 @@ svn_client_diff6(const apr_array_header_
 
   diff_cmd_baton.force_empty = FALSE;
   diff_cmd_baton.force_binary = ignore_content_type;
+  diff_cmd_baton.ignore_prop_diff = ignore_prop_diff;
   diff_cmd_baton.relative_to_dir = relative_to_dir;
   diff_cmd_baton.use_git_diff_format = use_git_diff_format;
   diff_cmd_baton.no_diff_deleted = no_diff_deleted;
@@ -2455,6 +2479,7 @@ svn_client_diff_peg6(const apr_array_hea
                      svn_boolean_t no_diff_deleted,
                      svn_boolean_t show_copies_as_adds,
                      svn_boolean_t ignore_content_type,
+                     svn_boolean_t ignore_prop_diff,
                      svn_boolean_t use_git_diff_format,
                      const char *header_encoding,
                      svn_stream_t *outstream,
@@ -2480,6 +2505,7 @@ svn_client_diff_peg6(const apr_array_hea
 
   diff_cmd_baton.force_empty = FALSE;
   diff_cmd_baton.force_binary = ignore_content_type;
+  diff_cmd_baton.ignore_prop_diff = ignore_prop_diff;
   diff_cmd_baton.relative_to_dir = relative_to_dir;
   diff_cmd_baton.use_git_diff_format = use_git_diff_format;
   diff_cmd_baton.no_diff_deleted = no_diff_deleted;

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/export.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/export.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/export.c Mon Jul 30 06:39:28 2012
@@ -402,7 +402,7 @@ copy_versioned_files(const char *from_ab
       const char *repos_relpath;
 
       SVN_ERR(svn_wc__node_get_origin(&is_added, NULL, &repos_relpath,
-                                      NULL, NULL,
+                                      NULL, NULL, NULL,
                                       ctx->wc_ctx, from_abspath, FALSE,
                                       pool, pool));
 
@@ -1020,6 +1020,55 @@ close_file(void *file_baton,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+fetch_kind_func(svn_kind_t *kind,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *scratch_pool)
+{
+  /* We know the root of the edit is a directory. */
+  if (path[0] == '\0')
+    *kind = svn_kind_dir;
+
+  /* ### TODO: We could possibly fetch the kind of the object in question
+         from the server with a second ra_session, but right now this
+         seems to work. */
+  else
+    *kind = svn_kind_unknown;
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fetch_props_func(apr_hash_t **props,
+                 void *baton,
+                 const char *path,
+                 svn_revnum_t base_revision,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  /* Always use empty props, since the node won't have pre-existing props
+     (This is an export, remember?) */
+  *props = apr_hash_make(result_pool);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fetch_base_func(const char **filename,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  /* An export always gets text against the empty stream (i.e, full texts). */
+  *filename = NULL;
+
+  return SVN_NO_ERROR;
+}
+
 
 
 /*** Public Interfaces ***/
@@ -1180,6 +1229,11 @@ svn_client_export5(svn_revnum_t *result_
                                                     &edit_baton,
                                                     pool));
 
+          shim_callbacks->fetch_kind_func = fetch_kind_func;
+          shim_callbacks->fetch_props_func = fetch_props_func;
+          shim_callbacks->fetch_base_func = fetch_base_func;
+          shim_callbacks->fetch_baton = eb;
+
           SVN_ERR(svn_editor__insert_shims(&export_editor, &edit_baton,
                                            export_editor, edit_baton,
                                            shim_callbacks, pool, pool));

Modified: subversion/branches/svn-bisect/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_client/externals.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_client/externals.c Mon Jul 30 06:39:28 2012
@@ -277,7 +277,7 @@ switch_dir_external(const char *local_ab
 
   /* ... Hello, new hotness. */
   SVN_ERR(svn_client__checkout_internal(NULL, url, local_abspath, peg_revision,
-                                        revision, NULL, svn_depth_infinity,
+                                        revision, svn_depth_infinity,
                                         FALSE, FALSE, timestamp_sleep,
                                         ctx, pool));
 
@@ -299,6 +299,9 @@ switch_dir_external(const char *local_ab
                                       external_peg_rev,
                                       external_rev,
                                       pool));
+    /* Issue #4123: We don't need to keep the newly checked out external's
+       DB open. */
+    SVN_ERR(svn_wc__close_db(local_abspath, ctx->wc_ctx, pool));
   }
 
   return SVN_NO_ERROR;
@@ -604,11 +607,12 @@ handle_external_item_change(const struct
                             apr_pool_t *scratch_pool)
 {
   svn_ra_session_t *ra_session;
-  svn_client__ra_session_from_path_results ra_cache = { 0 };
+  svn_revnum_t ra_revnum;
+  const char *ra_session_url;
+  const char *repos_root_url;
+  const char *repos_uuid;
   const char *new_url;
-  svn_node_kind_t kind;
-
-  ra_cache.kind = svn_node_unknown;
+  svn_node_kind_t ext_kind;
 
   SVN_ERR_ASSERT(eb->repos_root_url && parent_dir_url);
   SVN_ERR_ASSERT(new_item != NULL);
@@ -628,34 +632,28 @@ handle_external_item_change(const struct
   /* Determine if the external is a file or directory. */
   /* Get the RA connection. */
   SVN_ERR(svn_client__ra_session_from_path(&ra_session,
-                                           &ra_cache.ra_revnum,
-                                           &ra_cache.ra_session_url,
+                                           &ra_revnum,
+                                           &ra_session_url,
                                            new_url, NULL,
                                            &(new_item->peg_revision),
                                            &(new_item->revision), eb->ctx,
                                            scratch_pool));
 
-  SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid,
-                           scratch_pool));
-  SVN_ERR(svn_ra_get_repos_root2(ra_session, &ra_cache.repos_root_url,
-                                 scratch_pool));
-  SVN_ERR(svn_ra_check_path(ra_session, "", ra_cache.ra_revnum, &kind,
+  SVN_ERR(svn_ra_get_uuid2(ra_session, &repos_uuid, scratch_pool));
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url, scratch_pool));
+  SVN_ERR(svn_ra_check_path(ra_session, "", ra_revnum, &ext_kind,
                             scratch_pool));
 
-  if (svn_node_none == kind)
+  if (svn_node_none == ext_kind)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                              _("URL '%s' at revision %ld doesn't exist"),
-                             ra_cache.ra_session_url,
-                             ra_cache.ra_revnum);
+                             ra_session_url, ra_revnum);
 
-  if (svn_node_dir != kind && svn_node_file != kind)
+  if (svn_node_dir != ext_kind && svn_node_file != ext_kind)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                              _("URL '%s' at revision %ld is not a file "
                                "or a directory"),
-                             ra_cache.ra_session_url,
-                             ra_cache.ra_revnum);
-
-  ra_cache.kind = kind;
+                             ra_session_url, ra_revnum);
 
 
   /* Not protecting against recursive externals.  Detecting them in
@@ -682,7 +680,7 @@ handle_external_item_change(const struct
                                           scratch_pool));
     }
 
-  switch (ra_cache.kind)
+  switch (ext_kind)
     {
       case svn_node_dir:
         SVN_ERR(switch_dir_external(local_abspath, new_url,
@@ -693,20 +691,60 @@ handle_external_item_change(const struct
                                     scratch_pool));
         break;
       case svn_node_file:
-        if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
-          return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                    _("Unsupported external: "
-                      "url of file external '%s' is not in repository '%s'"),
-                    new_url, eb->repos_root_url);
+        if (strcmp(eb->repos_root_url, repos_root_url))
+          {
+            const char *local_repos_root_url;
+            const char *local_repos_uuid;
+            const char *ext_repos_relpath;
+            
+            /* 
+             * The working copy library currently requires that all files
+             * in the working copy have the same repository root URL.
+             * The URL from the file external's definition differs from the
+             * one used by the working copy. As a workaround, replace the
+             * root URL portion of the file external's URL, after making
+             * sure both URLs point to the same repository. See issue #4087.
+             */
+
+            SVN_ERR(svn_wc__node_get_repos_info(&local_repos_root_url,
+                                                &local_repos_uuid,
+                                                eb->ctx->wc_ctx,
+                                                parent_dir_abspath,
+                                                scratch_pool, scratch_pool));
+            ext_repos_relpath = svn_uri_skip_ancestor(repos_root_url,
+                                                      new_url, scratch_pool);
+            if (local_repos_uuid == NULL || local_repos_root_url == NULL ||
+                ext_repos_relpath == NULL ||
+                strcmp(local_repos_uuid, repos_uuid) != 0)
+              return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                        _("Unsupported external: URL of file external '%s' "
+                          "is not in repository '%s'"),
+                        new_url, eb->repos_root_url);
+
+            new_url = svn_path_url_add_component2(local_repos_root_url,
+                                                  ext_repos_relpath,
+                                                  scratch_pool);
+            SVN_ERR(svn_client__ra_session_from_path(&ra_session,
+                                                     &ra_revnum,
+                                                     &ra_session_url,
+                                                     new_url,
+                                                     NULL,
+                                                     &(new_item->peg_revision),
+                                                     &(new_item->revision),
+                                                     eb->ctx, scratch_pool));
+            SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url,
+                                           scratch_pool));
+          }
+
         SVN_ERR(switch_file_external(local_abspath,
                                      new_url,
                                      &new_item->peg_revision,
                                      &new_item->revision,
                                      parent_dir_abspath,
                                      ra_session,
-                                     ra_cache.ra_session_url,
-                                     ra_cache.ra_revnum,
-                                     ra_cache.repos_root_url,
+                                     ra_session_url,
+                                     ra_revnum,
+                                     repos_root_url,
                                      eb->timestamp_sleep, eb->ctx,
                                      scratch_pool));
         break;