You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/28 19:35:26 UTC

svn commit: r1002283 [2/10] - in /subversion/branches/javahl-ra: ./ build/ notes/ notes/http-and-webdav/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/tig...

Modified: subversion/branches/javahl-ra/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_wc.h?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_wc.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_wc.h Tue Sep 28 17:35:22 2010
@@ -1258,10 +1258,12 @@ typedef struct svn_wc_notify_t {
    * hunk the notification is for. They are line-based
    * offsets and lengths parsed from the unidiff hunk header.
    * @since New in 1.7. */
+  /* @{ */
   svn_linenum_t hunk_original_start;
   svn_linenum_t hunk_original_length;
   svn_linenum_t hunk_modified_start;
   svn_linenum_t hunk_modified_length;
+  /* @} */
 
   /** The line at which a hunk was matched (and applied).
    * @since New in 1.7. */
@@ -5093,7 +5095,6 @@ svn_wc_process_committed(const char *pat
  *
  * No locks or logs are created, nor are any animals harmed in the
  * process unless @a restore_files is TRUE.  No cleanup is necessary.
- * The working copy is accessed using @a wc_ctx.
  *
  * After all revisions are reported, @a reporter->finish_report() is
  * called, which immediately causes the RA layer to update the working
@@ -5365,10 +5366,6 @@ svn_wc_get_actual_target(const char *pat
  * whenever external changes are encountered, giving the callback a chance
  * to store the external information for processing.
  *
- * If @a fetch_func is non-NULL, then use it (with @a fetch_baton) as
- * a fallback for retrieving repository files whenever 'copyfrom' args
- * are sent into editor->add_file().
- *
  * If @a diff3_cmd is non-NULL, then use it as the diff3 command for
  * any merging; otherwise, use the built-in merge code.
  *
@@ -5419,8 +5416,6 @@ svn_wc_get_update_editor4(const svn_delt
                           svn_boolean_t allow_unver_obstructions,
                           const char *diff3_cmd,
                           const apr_array_header_t *preserved_exts,
-                          svn_wc_get_file_t fetch_func,
-                          void *fetch_baton,
                           svn_wc_conflict_resolver_func_t conflict_func,
                           void *conflict_baton,
                           svn_wc_external_update_t external_func,
@@ -5434,7 +5429,8 @@ svn_wc_get_update_editor4(const svn_delt
 
 /** Similar to svn_wc_get_update_editor4, but uses access batons and relative
  * path instead of a working copy context-abspath pair and
- * svn_wc_traversal_info_t instead of an externals callback.
+ * svn_wc_traversal_info_t instead of an externals callback.  Also, 
+ * @a fetch_func and @a fetch_baton are ignored.
  *
  * If @a ti is non-NULL, record traversal info in @a ti, for use by
  * post-traversal accessors such as svn_wc_edited_externals().
@@ -5546,8 +5542,6 @@ svn_wc_get_switch_editor4(const svn_delt
                           svn_boolean_t allow_unver_obstructions,
                           const char *diff3_cmd,
                           const apr_array_header_t *preserved_exts,
-                          svn_wc_get_file_t fetch_func,
-                          void *fetch_baton,
                           svn_wc_conflict_resolver_func_t conflict_func,
                           void *conflict_baton,
                           svn_wc_external_update_t external_func,
@@ -5561,8 +5555,7 @@ svn_wc_get_switch_editor4(const svn_delt
 
 /** Similar to svn_wc_get_switch_editor4, but uses access batons and relative
  * path instead of a working copy context and svn_wc_traversal_info_t instead
- * of an externals callback. This function doesn't support an external file
- * fetcher.
+ * of an externals callback.
  *
  * If @a ti is non-NULL, record traversal info in @a ti, for use by
  * post-traversal accessors such as svn_wc_edited_externals().
@@ -6797,13 +6790,13 @@ typedef svn_error_t *(*svn_wc_relocation
                                                       const char *uuid,
                                                       const char *url);
 
-/** Change repository references at @a local_abspath and all it's children.
- * The pre-change URL should be @a from, and the post-change URL will be
- * @a to.  @a validator (and its baton, @a validator_baton), will be called
- * for the newly generated base URL and calculated repo root.
+/** Recursively change repository references at @a wcroot_abspath
+ * (which is the root directory of a working copy).  The pre-change
+ * URL should be @a from, and the post-change URL will be @a to.  @a
+ * validator (and its baton, @a validator_baton), will be called for
+ * the newly generated base URL and calculated repo root.
  *
- * If @a recurse is @c FALSE, none of the children of @a local_abspath will
- * be changed.  @a wc_ctx is an working copy context.
+ * @a wc_ctx is an working copy context.
  *
  * @a scratch_pool will be used for temporary allocations.
  *
@@ -6811,10 +6804,9 @@ typedef svn_error_t *(*svn_wc_relocation
  */
 svn_error_t *
 svn_wc_relocate4(svn_wc_context_t *wc_ctx,
-                 const char *local_abspath,
+                 const char *wcroot_abspath,
                  const char *from,
                  const char *to,
-                 svn_boolean_t recurse,
                  svn_wc_relocation_validator3_t validator,
                  void *validator_baton,
                  apr_pool_t *scratch_pool);
@@ -6822,8 +6814,12 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
 /** Similar to svn_wc_relocate4(), but with a #svn_wc_adm_access_t /
  * relative path parameter pair.
  *
+ * @note As of the 1.7 API, @a path is required to be a working copy
+ * root directory, and @a recurse is required to be TRUE.
+ *
  * @since New in 1.5.
- * @deprecated Provided for backwards compatibility with the 1.6 API.
+ * @deprecated Provided for limited backwards compatibility with the
+ * 1.6 API.
  */
 SVN_DEPRECATED
 svn_error_t *

Modified: subversion/branches/javahl-ra/subversion/libsvn_auth_kwallet/kwallet.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_auth_kwallet/kwallet.cpp?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_auth_kwallet/kwallet.cpp (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_auth_kwallet/kwallet.cpp Tue Sep 28 17:35:22 2010
@@ -47,20 +47,13 @@
 
 #include <dbus/dbus.h>
 #include <QtCore/QCoreApplication>
-#include <QtCore/QList>
-#include <QtCore/QMap>
 #include <QtCore/QString>
-#include <QtGui/QApplication>
-#include <QtGui/QX11Info>
 
 #include <kaboutdata.h>
 #include <kcmdlineargs.h>
 #include <kcomponentdata.h>
 #include <klocalizedstring.h>
 #include <kwallet.h>
-#include <kwindowsystem.h>
-#include <netwm.h>
-#include <netwm_def.h>
 
 
 /*-----------------------------------------------------------------------*/
@@ -68,28 +61,6 @@
 /*-----------------------------------------------------------------------*/
 
 
-#define INITIALIZE_APPLICATION                                            \
-  if (apr_hash_get(parameters,                                            \
-                   "svn:auth:qapplication-safe",                          \
-                   APR_HASH_KEY_STRING))                                  \
-    {                                                                     \
-      QApplication *app;                                                  \
-      if (! qApp)                                                         \
-        {                                                                 \
-          int argc = 1;                                                   \
-          app = new QApplication(argc, (char *[1]) {(char *) "svn"});     \
-        }                                                                 \
-    }                                                                     \
-  else                                                                    \
-    {                                                                     \
-      QCoreApplication *app;                                              \
-      if (! qApp)                                                         \
-        {                                                                 \
-          int argc = 1;                                                   \
-          app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"}); \
-        }                                                                 \
-    }
-
 static const char *
 get_application_name(apr_hash_t *parameters,
                      apr_pool_t *pool)
@@ -139,99 +110,22 @@ get_wallet_name(apr_hash_t *parameters)
     }
 }
 
-static pid_t
-get_parent_pid(pid_t pid,
-               apr_pool_t *pool)
-{
-  pid_t parent_pid = 0;
-
-#ifdef __linux__
-  svn_stream_t *stat_file_stream;
-  svn_string_t *stat_file_string;
-  const char *preceeding_space, *following_space, *parent_pid_string;
-
-  const char *path = apr_psprintf(pool, "/proc/%ld/stat", long(pid));
-  svn_error_t *err = svn_stream_open_readonly(&stat_file_stream, path, pool, pool);
-  if (err == SVN_NO_ERROR)
-    {
-      err = svn_string_from_stream(&stat_file_string, stat_file_stream, pool, pool);
-      if (err == SVN_NO_ERROR)
-        {
-          if ((preceeding_space = strchr(stat_file_string->data, ' ')))
-            {
-              if ((preceeding_space = strchr(preceeding_space + 1, ' ')))
-                {
-                  if ((preceeding_space = strchr(preceeding_space + 1, ' ')))
-                    {
-                      if ((following_space = strchr(preceeding_space + 1, ' ')))
-                        {
-                          parent_pid_string = apr_pstrndup(pool,
-                                                           preceeding_space + 1,
-                                                           following_space - preceeding_space);
-                          parent_pid = atol(parent_pid_string);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-  if (err)
-    {
-      svn_error_clear(err);
-    }
-#endif
-
-  return parent_pid;
-}
-
 static WId
-get_wid(apr_hash_t *parameters,
-        apr_pool_t *pool)
+get_wid(void)
 {
   WId wid = 1;
+  const char *wid_env_string = getenv("WINDOWID");
 
-  if (apr_hash_get(parameters,
-                   "svn:auth:qapplication-safe",
-                   APR_HASH_KEY_STRING))
-    {
-      QMap<pid_t, WId> process_info_list;
-      QList<WId> windows(KWindowSystem::windows());
-      QList<WId>::const_iterator i;
-      for (i = windows.begin(); i != windows.end(); i++)
-        {
-          process_info_list[NETWinInfo(QX11Info::display(),
-                                       *i,
-                                       QX11Info::appRootWindow(),
-                                       NET::WMPid).pid()] = *i;
-        }
-
-      apr_pool_t *iterpool = svn_pool_create(pool);
-      pid_t pid = getpid();
-      while (pid != 0)
-        {
-          svn_pool_clear(iterpool);
-          if (process_info_list.contains(pid))
-            {
-              wid = process_info_list[pid];
-              break;
-            }
-          pid = get_parent_pid(pid, iterpool);
-        }
-      svn_pool_destroy(iterpool);
-    }
-
-  if (wid == 1)
+  if (wid_env_string)
     {
-      const char *wid_env_string = getenv("WINDOWID");
-      if (wid_env_string)
-        {
-          long wid_env = atol(wid_env_string);
-          if (wid_env != 0)
-            {
-              wid = wid_env;
-            }
-        }
+      apr_int64_t wid_env;
+      svn_error_t *err;
+      
+      err = svn_cstring_atoi64(&wid_env, wid_env_string);
+      if (err)
+        svn_error_clear(err);
+      else
+        wid = (WId)wid_env;
     }
 
   return wid;
@@ -239,8 +133,7 @@ get_wid(apr_hash_t *parameters,
 
 static KWallet::Wallet *
 get_wallet(QString wallet_name,
-           apr_hash_t *parameters,
-           apr_pool_t *pool)
+           apr_hash_t *parameters)
 {
   KWallet::Wallet *wallet =
     static_cast<KWallet::Wallet *> (apr_hash_get(parameters,
@@ -250,8 +143,7 @@ get_wallet(QString wallet_name,
                                  "kwallet-opening-failed",
                                  APR_HASH_KEY_STRING))
     {
-      wallet = KWallet::Wallet::openWallet(wallet_name,
-                                           pool ? get_wid(parameters, pool) : 1,
+      wallet = KWallet::Wallet::openWallet(wallet_name, get_wid(),
                                            KWallet::Wallet::Synchronous);
     }
   if (wallet)
@@ -277,7 +169,7 @@ kwallet_terminate(void *data)
   apr_hash_t *parameters = static_cast<apr_hash_t *> (data);
   if (apr_hash_get(parameters, "kwallet-initialized", APR_HASH_KEY_STRING))
     {
-      KWallet::Wallet *wallet = get_wallet(NULL, parameters, NULL);
+      KWallet::Wallet *wallet = get_wallet(NULL, parameters);
       delete wallet;
       apr_hash_set(parameters,
                    "kwallet-initialized",
@@ -308,7 +200,12 @@ kwallet_password_get(const char **passwo
       return FALSE;
     }
 
-  INITIALIZE_APPLICATION
+  QCoreApplication *app;
+  if (! qApp)
+    {
+      int argc = 1;
+      app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"});
+    }
 
   KCmdLineArgs::init(1,
                      (char *[1]) {(char *) "svn"},
@@ -326,7 +223,7 @@ kwallet_password_get(const char **passwo
     QString::fromUtf8(username) + "@" + QString::fromUtf8(realmstring);
   if (! KWallet::Wallet::keyDoesNotExist(wallet_name, folder, key))
     {
-      KWallet::Wallet *wallet = get_wallet(wallet_name, parameters, pool);
+      KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
       if (wallet)
         {
           apr_hash_set(parameters,
@@ -373,7 +270,12 @@ kwallet_password_set(apr_hash_t *creds,
       return FALSE;
     }
 
-  INITIALIZE_APPLICATION
+  QCoreApplication *app;
+  if (! qApp)
+    {
+      int argc = 1;
+      app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"});
+    }
 
   KCmdLineArgs::init(1,
                      (char *[1]) {(char *) "svn"},
@@ -388,7 +290,7 @@ kwallet_password_set(apr_hash_t *creds,
   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, pool);
+  KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
   if (wallet)
     {
       apr_hash_set(parameters,
@@ -525,6 +427,7 @@ static const svn_auth_provider_t kwallet
 };
 
 /* Public API */
+extern "C" {
 void
 svn_auth_get_kwallet_ssl_client_cert_pw_provider
     (svn_auth_provider_object_t **provider,
@@ -536,3 +439,4 @@ svn_auth_get_kwallet_ssl_client_cert_pw_
   po->vtable = &kwallet_ssl_client_cert_pw_provider;
   *provider = po;
 }
+}

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/checkout.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/checkout.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/checkout.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/checkout.c Tue Sep 28 17:35:22 2010
@@ -71,10 +71,11 @@ initialize_area(svn_revnum_t *result_rev
                              repos_root, uuid, revnum, depth, pool));
   /* Have update fix the incompleteness. */
   return svn_error_return(svn_client__update_internal(result_rev, local_abspath,
-                                    revision, depth, TRUE, ignore_externals,
-                                    allow_unver_obstructions,
-                                    use_sleep, FALSE, innercheckout,
-                                    ctx, pool));
+                                                      revision, depth, TRUE,
+                                                      ignore_externals,
+                                                      allow_unver_obstructions,
+                                                      use_sleep, innercheckout,
+                                                      ctx, pool));
 }
 
 
@@ -219,7 +220,7 @@ svn_client__checkout_internal(svn_revnum
                                                 revision, depth, TRUE,
                                                 ignore_externals,
                                                 allow_unver_obstructions,
-                                                use_sleep, FALSE, innercheckout,
+                                                use_sleep, innercheckout,
                                                 ctx, pool);
             }
           else

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/cleanup.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/cleanup.c Tue Sep 28 17:35:22 2010
@@ -129,6 +129,11 @@ svn_client_upgrade(const char *path,
   info_baton.last_repos = NULL;
   info_baton.last_uuid = NULL;
 
+  if (svn_path_is_url(path))
+    return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                              _("'%s' is not a local path"),
+                                              path));
+
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
   SVN_ERR(svn_wc_upgrade(ctx->wc_ctx, local_abspath,
                          fetch_repos_info, &info_baton,

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/client.h?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/client.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/client.h Tue Sep 28 17:35:22 2010
@@ -490,12 +490,6 @@ svn_client__make_local_parents(const cha
    that obstruct items added from the repos are tolerated; if FALSE,
    these obstructions cause the update to fail.
 
-   If SEND_COPYFROM_ARGS is true, then request that the server not
-   send file contents when adding files that have been created by
-   explicit copying; instead, just send copyfrom-args to add_file(),
-   and possibly follow up with an apply_textdelta() against the copied
-   file.
-
    If INNERUPDATE is true, no anchor check is performed on the update target.
 */
 svn_error_t *
@@ -507,7 +501,6 @@ svn_client__update_internal(svn_revnum_t
                             svn_boolean_t ignore_externals,
                             svn_boolean_t allow_unver_obstructions,
                             svn_boolean_t *timestamp_sleep,
-                            svn_boolean_t send_copyfrom_args,
                             svn_boolean_t innerupdate,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool);

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/copy.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/copy.c Tue Sep 28 17:35:22 2010
@@ -1866,7 +1866,6 @@ static svn_error_t *
 try_copy(const apr_array_header_t *sources,
          const char *dst_path_in,
          svn_boolean_t is_move,
-         svn_boolean_t force,
          svn_boolean_t make_parents,
          svn_boolean_t ignore_externals,
          const apr_hash_t *revprop_table,
@@ -2203,7 +2202,6 @@ svn_client_copy6(const apr_array_header_
 
   err = try_copy(sources, dst_path,
                  FALSE /* is_move */,
-                 TRUE /* force, set to avoid deletion check */,
                  make_parents,
                  ignore_externals,
                  revprop_table,
@@ -2236,7 +2234,6 @@ svn_client_copy6(const apr_array_header_
                          ? svn_uri_join(dst_path, src_basename, subpool)
                          : svn_dirent_join(dst_path, src_basename, subpool),
                      FALSE /* is_move */,
-                     TRUE /* force, set to avoid deletion check */,
                      make_parents,
                      ignore_externals,
                      revprop_table,
@@ -2253,7 +2250,6 @@ svn_client_copy6(const apr_array_header_
 svn_error_t *
 svn_client_move6(const apr_array_header_t *src_paths,
                  const char *dst_path,
-                 svn_boolean_t force,
                  svn_boolean_t move_as_child,
                  svn_boolean_t make_parents,
                  const apr_hash_t *revprop_table,
@@ -2289,7 +2285,6 @@ svn_client_move6(const apr_array_header_
 
   err = try_copy(sources, dst_path,
                  TRUE /* is_move */,
-                 force,
                  make_parents,
                  FALSE,
                  revprop_table,
@@ -2319,7 +2314,6 @@ svn_client_move6(const apr_array_header_
                          ? svn_uri_join(dst_path, src_basename, pool)
                          : svn_dirent_join(dst_path, src_basename, pool),
                      TRUE /* is_move */,
-                     force,
                      make_parents,
                      FALSE,
                      revprop_table,

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/deprecated.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/deprecated.c Tue Sep 28 17:35:22 2010
@@ -620,7 +620,7 @@ svn_client_move5(svn_commit_info_t **com
   cb.info = commit_info_p;
   cb.pool = pool;
 
-  return svn_client_move6(src_paths, dst_path, force, move_as_child,
+  return svn_client_move6(src_paths, dst_path, move_as_child,
                           make_parents, revprop_table,
                           capture_commit_info, &cb, ctx, pool);
 }
@@ -637,6 +637,7 @@ svn_client_move4(svn_commit_info_t **com
     apr_array_make(pool, 1, sizeof(const char *));
   APR_ARRAY_PUSH(src_paths, const char *) = src_path;
 
+
   return svn_client_move5(commit_info_p, src_paths, dst_path, force, FALSE,
                           FALSE, NULL, ctx, pool);
 }
@@ -2039,3 +2040,18 @@ svn_client_mergeinfo_log_eligible(const 
                                   svn_depth_empty, revprops, ctx,
                                   pool);
 }
+
+/*** From relocate.c ***/
+svn_error_t *
+svn_client_relocate(const char *path,
+                    const char *from,
+                    const char *to,
+                    svn_boolean_t recurse,
+                    svn_client_ctx_t *ctx,
+                    apr_pool_t *pool)
+{
+  if (! recurse)
+    svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, 0,
+                     _("Non-recursive relocation not supported"));
+  return svn_client_relocate2(path, from, to, ctx, pool);
+}

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/externals.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/externals.c Tue Sep 28 17:35:22 2010
@@ -205,7 +205,7 @@ switch_dir_external(const char *path,
                                                   revision, svn_depth_unknown,
                                                   FALSE, FALSE, FALSE,
                                                   timestamp_sleep, TRUE,
-                                                  TRUE, ctx, subpool));
+                                                  ctx, subpool));
               svn_pool_destroy(subpool);
               return SVN_NO_ERROR;
             }
@@ -229,8 +229,8 @@ switch_dir_external(const char *path,
                   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root,
                                                  subpool));
 
-                  err = svn_client_relocate(path, repos_root_url, repos_root,
-                                            TRUE, ctx, subpool);
+                  err = svn_client_relocate2(path, repos_root_url, repos_root,
+                                             ctx, subpool);
                   /* If the relocation failed because the new URL points
                      to another repository, then we need to relegate and
                      check out a new WC. */

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/list.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/list.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/list.c Tue Sep 28 17:35:22 2010
@@ -63,14 +63,23 @@ get_dir_contents(apr_uint32_t dirent_fie
   apr_hash_t *tmpdirents;
   apr_pool_t *iterpool = svn_pool_create(pool);
   apr_array_header_t *array;
+  svn_error_t *err;
   int i;
 
   if (depth == svn_depth_empty)
     return SVN_NO_ERROR;
 
-  /* Get the directory's entries, but not its props. */
-  SVN_ERR(svn_ra_get_dir2(ra_session, &tmpdirents, NULL, NULL,
-                          dir, rev, dirent_fields, pool));
+  /* Get the directory's entries, but not its props.  Ignore any
+     not-authorized errors.  */
+  err = svn_ra_get_dir2(ra_session, &tmpdirents, NULL, NULL,
+                        dir, rev, dirent_fields, pool);
+  if (err && ((err->apr_err == SVN_ERR_RA_NOT_AUTHORIZED) ||
+              (err->apr_err == SVN_ERR_RA_DAV_FORBIDDEN)))
+    {
+      svn_error_clear(err);
+      return SVN_NO_ERROR;
+    }
+  SVN_ERR(err);
 
   if (ctx->cancel_func)
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/patch.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/patch.c Tue Sep 28 17:35:22 2010
@@ -532,6 +532,8 @@ init_prop_target(prop_patch_target_t **p
  * described by PATCH. Use working copy context WC_CTX.
  * STRIP_COUNT specifies the number of leading path components
  * which should be stripped from target paths in the patch.
+ * OLD_PATCH_TARGET_NAMES indicates whether the old target's name parsed
+ * from the patch file should be preferred over the new target's name.
  * The patch target structure is allocated in RESULT_POOL, but if the target
  * should be skipped, PATCH_TARGET->SKIPPED is set and the target should be
  * treated as not fully initialized, e.g. the caller should not not do any
@@ -543,7 +545,9 @@ static svn_error_t *
 init_patch_target(patch_target_t **patch_target,
                   const svn_patch_t *patch,
                   const char *base_dir,
-                  svn_wc_context_t *wc_ctx, int strip_count,
+                  svn_wc_context_t *wc_ctx,
+                  int strip_count,
+                  svn_boolean_t old_patch_target_names,
                   svn_boolean_t remove_tempfiles,
                   apr_pool_t *result_pool, apr_pool_t *scratch_pool)
 {
@@ -589,7 +593,8 @@ init_patch_target(patch_target_t **patch
   target->prop_targets = apr_hash_make(result_pool);
   target->pool = result_pool;
 
-  SVN_ERR(resolve_target_path(target, patch->new_filename,
+  SVN_ERR(resolve_target_path(target, old_patch_target_names ?
+                                patch->old_filename : patch->new_filename,
                               base_dir, strip_count, prop_changes_only,
                               wc_ctx, result_pool, scratch_pool));
   if (! target->skipped)
@@ -626,13 +631,16 @@ init_patch_target(patch_target_t **patch
                                                    scratch_pool));
         }
 
-      /* ### Is it ok to set target->added here? Isn't the target supposed to
-       * ### be marked as added after it's been proven that it can be added?
-       * ### One alternative is to include a git_added flag. Or maybe we
-       * ### should have kept the patch field in patch_target_t? Then we
-       * ### could have checked for target->patch->operation == added */
+      /* ### Is it ok to set the operation of the target already here? Isn't
+       * ### the target supposed to be marked with an operation after we have
+       * ### determined that the changes will apply cleanly to the WC? Maybe
+       * ### we should have kept the patch field in patch_target_t to be
+       * ### able to distinguish between 'what the patch says we should do' 
+       * ### and 'what we can do with the given state of our WC'. */
       if (patch->operation == svn_diff_op_added)
         target->added = TRUE;
+      else if (patch->operation == svn_diff_op_deleted)
+        target->deleted = TRUE;
 
       SVN_ERR(svn_stream_open_unique(&patched_raw,
                                      &target->patched_path, NULL,
@@ -857,59 +865,41 @@ match_hunk(svn_boolean_t *matched, targe
                                            NULL, FALSE,
                                            content_info->keywords, FALSE,
                                            iterpool));
-      lines_read++;
       SVN_ERR(read_line(content_info, &target_line, iterpool, iterpool));
-      if (! hunk_eof)
+
+      lines_read++;
+
+      /* If the last line doesn't have a newline, we get EOF but still
+       * have a non-empty line to compare. */
+      if ((hunk_eof && hunk_line->len == 0) ||
+          (content_info->eof && strlen(target_line) == 0))
+        break;
+
+      /* Leading/trailing fuzzy lines always match. */
+      if ((lines_read <= fuzz && leading_context > fuzz) ||
+          (lines_read > hunk_length - fuzz && trailing_context > fuzz))
+        lines_matched = TRUE;
+      else
         {
-          if (lines_read <= fuzz && leading_context > fuzz)
-            lines_matched = TRUE;
-          else if (lines_read > hunk_length - fuzz &&
-                   trailing_context > fuzz)
-            lines_matched = TRUE;
-          else
+          if (ignore_whitespace)
             {
-              if (ignore_whitespace)
-                {
-                  char *stripped_hunk_line = apr_pstrdup(pool,
-                                                         hunk_line_translated);
-                  char *stripped_target_line = apr_pstrdup(pool, target_line);
-
-                  apr_collapse_spaces(stripped_hunk_line,
-                                      hunk_line_translated);
-                  apr_collapse_spaces(stripped_target_line, target_line);
-                  lines_matched = ! strcmp(stripped_hunk_line,
-                                           stripped_target_line);
-                }
-              else 
-                lines_matched = ! strcmp(hunk_line_translated, target_line);
+              char *hunk_line_trimmed;
+              char *target_line_trimmed;
+
+              hunk_line_trimmed = apr_pstrdup(iterpool, hunk_line_translated);
+              target_line_trimmed = apr_pstrdup(iterpool, target_line);
+              apr_collapse_spaces(hunk_line_trimmed, hunk_line_trimmed);
+              apr_collapse_spaces(target_line_trimmed, target_line_trimmed);
+              lines_matched = ! strcmp(hunk_line_trimmed, target_line_trimmed);
             }
+          else
+            lines_matched = ! strcmp(hunk_line_translated, target_line);
         }
     }
-  while (lines_matched && ! (hunk_eof || content_info->eof));
+  while (lines_matched);
 
-  if (hunk_eof)
-    *matched = lines_matched;
-  else if (content_info->eof)
-    {
-      /* If the target has no newline at end-of-file, we get an EOF
-       * indication for the target earlier than we do get it for the hunk. */
-      if (match_modified)
-        SVN_ERR(svn_diff_hunk_readline_modified_text(hunk, &hunk_line,
-                                                     NULL, &hunk_eof,
-                                                     iterpool, iterpool));
-      else
-        SVN_ERR(svn_diff_hunk_readline_original_text(hunk, &hunk_line,
-                                                     NULL, &hunk_eof,
-                                                     iterpool, iterpool));
+  *matched = lines_matched && hunk_eof && hunk_line->len == 0;
 
-      /* When comparing modified text we require that all lines match, else
-       * a hunk that adds a newline at the end will be treated as already
-       * applied even if it isn't. */
-      if (! match_modified && hunk_line->len == 0 && hunk_eof)
-        *matched = lines_matched;
-      else
-        *matched = FALSE;
-    }
   SVN_ERR(seek_to_line(content_info, saved_line, iterpool));
 
   svn_pool_destroy(iterpool);
@@ -1155,54 +1145,55 @@ get_hunk_info(hunk_info_t **hi, patch_ta
   else if (original_start > 0 && content_info->stream)
     {
       svn_linenum_t saved_line = content_info->current_line;
-      svn_linenum_t modified_start;
 
-      /* Check if the hunk is already applied.
-       * We only check for an exact match here, and don't bother checking
-       * for already applied patches with offset/fuzz, because such a
-       * check would be ambiguous. */
-      if (fuzz == 0)
+      /* Scan for a match at the line where the hunk thinks it
+       * should be going. */
+      SVN_ERR(seek_to_line(content_info, original_start, scratch_pool));
+      if (content_info->current_line != original_start)
         {
-          modified_start = svn_diff_hunk_get_modified_start(hunk);
-          if (modified_start == 0)
-            {
-              /* Patch wants to delete the file. */
-              already_applied = target->locally_deleted;
-            }
-          else
-            {
-              SVN_ERR(seek_to_line(content_info, modified_start,
-                                   scratch_pool));
-              SVN_ERR(scan_for_match(&matched_line, content_info,
-                                     hunk, TRUE,
-                                     modified_start + 1,
-                                     fuzz, ignore_whitespace, TRUE,
-                                     cancel_func, cancel_baton,
-                                     scratch_pool));
-              already_applied = (matched_line == modified_start);
-            }
+          /* Seek failed. */
+          matched_line = 0;
         }
       else
-        already_applied = FALSE;
+        SVN_ERR(scan_for_match(&matched_line, content_info, hunk, TRUE,
+                               original_start + 1, fuzz,
+                               ignore_whitespace, FALSE,
+                               cancel_func, cancel_baton,
+                               scratch_pool));
 
-      if (! already_applied)
+      if (matched_line != original_start)
         {
-          /* Scan for a match at the line where the hunk thinks it
-           * should be going. */
-          SVN_ERR(seek_to_line(content_info, original_start, scratch_pool));
-          if (content_info->current_line != original_start)
+          /* Check if the hunk is already applied.
+           * We only check for an exact match here, and don't bother checking
+           * for already applied patches with offset/fuzz, because such a
+           * check would be ambiguous. */
+          if (fuzz == 0)
             {
-              /* Seek failed. */
-              matched_line = 0;
+              svn_linenum_t modified_start;
+
+              modified_start = svn_diff_hunk_get_modified_start(hunk);
+              if (modified_start == 0)
+                {
+                  /* Patch wants to delete the file. */
+                  already_applied = target->locally_deleted;
+                }
+              else
+                {
+                  SVN_ERR(seek_to_line(content_info, modified_start,
+                                       scratch_pool));
+                  SVN_ERR(scan_for_match(&matched_line, content_info,
+                                         hunk, TRUE,
+                                         modified_start + 1,
+                                         fuzz, ignore_whitespace, TRUE,
+                                         cancel_func, cancel_baton,
+                                         scratch_pool));
+                  already_applied = (matched_line == modified_start);
+                }
             }
           else
-            SVN_ERR(scan_for_match(&matched_line, content_info, hunk, TRUE,
-                                   original_start + 1, fuzz,
-                                   ignore_whitespace, FALSE,
-                                   cancel_func, cancel_baton,
-                                   scratch_pool));
+            already_applied = FALSE;
 
-          if (matched_line != original_start)
+          if (! already_applied)
             {
               /* Scan the whole file again from the start. */
               SVN_ERR(seek_to_line(content_info, 1, scratch_pool));
@@ -1649,6 +1640,8 @@ close_target_streams(const patch_target_
  * in RESULT_POOL. Use WC_CTX as the working copy context.
  * STRIP_COUNT specifies the number of leading path components
  * which should be stripped from target paths in the patch.
+ * OLD_PATCH_TARGET_NAMES indicates whether the old filename parsed
+ * from the patch file should be preferred over the new filename.
  * REMOVE_TEMPFILES, PATCH_FUNC, and PATCH_BATON as in svn_client_patch().
  * IGNORE_WHITESPACE tells whether whitespace should be considered when
  * doing the matching.
@@ -1658,6 +1651,7 @@ static svn_error_t *
 apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch,
                 const char *abs_wc_path, svn_wc_context_t *wc_ctx,
                 int strip_count,
+                svn_boolean_t old_patch_target_names,
                 svn_boolean_t ignore_whitespace,
                 svn_boolean_t remove_tempfiles,
                 svn_client_patch_func_t patch_func,
@@ -1672,7 +1666,8 @@ apply_one_patch(patch_target_t **patch_t
   static const int MAX_FUZZ = 2;
   apr_hash_index_t *hash_index;
 
-  SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count,
+  SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx,
+                            strip_count, old_patch_target_names,
                             remove_tempfiles, result_pool, scratch_pool));
   if (target->skipped)
     {
@@ -2559,6 +2554,9 @@ typedef struct {
   /* Number of leading components to strip from patch target paths. */
   int strip_count;
 
+  /* Whether to use the old path from the patch file instead of the new one. */
+  svn_boolean_t old_patch_target_names;
+
   /* Whether to apply the patch in reverse. */
   svn_boolean_t reverse;
 
@@ -2624,6 +2622,7 @@ apply_patches(void *baton,
 
           SVN_ERR(apply_one_patch(&target, patch, btn->abs_wc_path,
                                   btn->ctx->wc_ctx, btn->strip_count,
+                                  btn->old_patch_target_names,
                                   btn->ignore_whitespace,
                                   btn->remove_tempfiles,
                                   btn->patch_func, btn->patch_baton,
@@ -2643,7 +2642,9 @@ apply_patches(void *baton,
 
               if (! target->skipped)
                 {
-                  if (target->has_text_changes || target->added)
+                  if (target->has_text_changes 
+                      || target->added 
+                      || target->deleted)
                     SVN_ERR(install_patched_target(target, btn->abs_wc_path,
                                                    btn->ctx, btn->dry_run,
                                                    iterpool));
@@ -2679,6 +2680,7 @@ svn_client_patch(const char *patch_abspa
                  const char *local_abspath,
                  svn_boolean_t dry_run,
                  int strip_count,
+                 svn_boolean_t old_patch_target_names,
                  svn_boolean_t reverse,
                  svn_boolean_t ignore_whitespace,
                  svn_boolean_t remove_tempfiles,
@@ -2699,6 +2701,7 @@ svn_client_patch(const char *patch_abspa
   baton.dry_run = dry_run;
   baton.ctx = ctx;
   baton.strip_count = strip_count;
+  baton.old_patch_target_names = old_patch_target_names;
   baton.reverse = reverse;
   baton.ignore_whitespace = ignore_whitespace;
   baton.remove_tempfiles = remove_tempfiles;

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/prop_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/prop_commands.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/prop_commands.c Tue Sep 28 17:35:22 2010
@@ -450,6 +450,53 @@ svn_client_propset4(const char *propname
     }
 }
 
+static svn_error_t *
+check_and_set_revprop(svn_revnum_t *set_rev,
+                      svn_ra_session_t *ra_session,
+                      const char *propname,
+                      const svn_string_t *original_propval,
+                      const svn_string_t *propval,
+                      apr_pool_t *pool)
+{
+  if (original_propval)
+    {
+      /* Ensure old value hasn't changed behind our back. */
+      svn_string_t *current;
+      SVN_ERR(svn_ra_rev_prop(ra_session, *set_rev, propname, &current, pool));
+
+      if (original_propval->data && (! current))
+        {
+          return svn_error_createf(
+                  SVN_ERR_RA_OUT_OF_DATE, NULL,
+                  _("revprop '%s' in r%ld is unexpectedly absent "
+                    "in repository (maybe someone else deleted it?)"),
+                  propname, *set_rev);
+        }
+      else if (original_propval->data
+               && (! svn_string_compare(original_propval, current)))
+        {
+          return svn_error_createf(
+                  SVN_ERR_RA_OUT_OF_DATE, NULL,
+                  _("revprop '%s' in r%ld has unexpected value "
+                    "in repository (maybe someone else changed it?)"),
+                  propname, *set_rev);
+        }
+      else if ((! original_propval->data) && current)
+        {
+          return svn_error_createf(
+                  SVN_ERR_RA_OUT_OF_DATE, NULL,
+                  _("revprop '%s' in r%ld is unexpectedly present "
+                    "in repository (maybe someone else set it?)"),
+                  propname, *set_rev);
+        }
+    }
+
+  SVN_ERR(svn_ra_change_rev_prop2(ra_session, *set_rev, propname, 
+                                  NULL, propval, pool));
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_revprop_set2(const char *propname,
                         const svn_string_t *propval,
@@ -462,6 +509,7 @@ svn_client_revprop_set2(const char *prop
                         apr_pool_t *pool)
 {
   svn_ra_session_t *ra_session;
+  svn_boolean_t be_atomic;
 
   if ((strcmp(propname, SVN_PROP_REVISION_AUTHOR) == 0)
       && propval
@@ -485,42 +533,31 @@ svn_client_revprop_set2(const char *prop
   SVN_ERR(svn_client__get_revision_number(set_rev, NULL, ctx->wc_ctx, NULL,
                                           ra_session, revision, pool));
 
-  if (original_propval)
-    {
-      /* Ensure old value hasn't changed behind our back. */
-      svn_string_t *current;
-      SVN_ERR(svn_ra_rev_prop(ra_session, *set_rev, propname, &current, pool));
+  SVN_ERR(svn_ra_has_capability(ra_session, &be_atomic,
+                                SVN_RA_CAPABILITY_ATOMIC_REVPROPS, pool));
+  if (be_atomic)
+    {
+      /* Convert ORIGINAL_PROPVAL to an OLD_VALUE_P. */
+      const svn_string_t *const *old_value_p;
+      const svn_string_t *unset = NULL;
+
+      if (original_propval == NULL)
+      	old_value_p = NULL;
+      else if (original_propval->data == NULL)
+      	old_value_p = &unset;
+      else
+      	old_value_p = &original_propval;
 
-      if (original_propval->data && (! current))
-        {
-          return svn_error_createf(
-                  SVN_ERR_RA_OUT_OF_DATE, NULL,
-                  _("revprop '%s' in r%ld is unexpectedly absent "
-                    "in repository (maybe someone else deleted it?)"),
-                  propname, *set_rev);
-        }
-      else if (original_propval->data
-               && (! svn_string_compare(original_propval, current)))
-        {
-          return svn_error_createf(
-                  SVN_ERR_RA_OUT_OF_DATE, NULL,
-                  _("revprop '%s' in r%ld has unexpected value "
-                    "in repository (maybe someone else changed it?)"),
-                  propname, *set_rev);
-        }
-      else if ((! original_propval->data) && current)
-        {
-          return svn_error_createf(
-                  SVN_ERR_RA_OUT_OF_DATE, NULL,
-                  _("revprop '%s' in r%ld is unexpectedly present "
-                    "in repository (maybe someone else set it?)"),
-                  propname, *set_rev);
-        }
+      /* The actual RA call. */
+      SVN_ERR(svn_ra_change_rev_prop2(ra_session, *set_rev, propname, 
+                                      old_value_p, propval, pool));
+    }
+  else
+    {
+      /* The actual RA call. */
+      SVN_ERR(check_and_set_revprop(set_rev, ra_session, propname,
+                                    original_propval, propval, pool));
     }
-
-  /* The actual RA call. */
-  SVN_ERR(svn_ra_change_rev_prop(ra_session, *set_rev, propname, propval,
-                                 pool));
 
   if (ctx->notify_func2)
     {

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/relocate.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/relocate.c Tue Sep 28 17:35:22 2010
@@ -126,24 +126,23 @@ validator_func(void *baton,
 }
 
 svn_error_t *
-svn_client_relocate(const char *path,
-                    const char *from,
-                    const char *to,
-                    svn_boolean_t recurse,
-                    svn_client_ctx_t *ctx,
-                    apr_pool_t *pool)
+svn_client_relocate2(const char *wcroot_dir,
+                     const char *from,
+                     const char *to,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool)
 {
   struct validator_baton_t vb;
   const char *local_abspath;
 
-  /* Now, populate our validator callback baton, and call the relocate code. */
+  /* Populate our validator callback baton, and call the relocate code. */
   vb.ctx = ctx;
-  vb.path = path;
+  vb.path = wcroot_dir;
   vb.url_uuids = apr_array_make(pool, 1, sizeof(struct url_uuid_t));
   vb.pool = pool;
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from, to, recurse,
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, wcroot_dir, pool));
+  SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from, to,
                            validator_func, &vb, pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/switch.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/switch.c Tue Sep 28 17:35:22 2010
@@ -190,7 +190,6 @@ switch_internal(svn_revnum_t *result_rev
                                     depth,
                                     depth_is_sticky, allow_unver_obstructions,
                                     diff3_cmd, preserved_exts,
-                                    NULL, NULL,
                                     ctx->conflict_func, ctx->conflict_baton,
                                     svn_client__external_info_gatherer, &efb,
                                     ctx->cancel_func, ctx->cancel_baton,

Modified: subversion/branches/javahl-ra/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/update.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/update.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/update.c Tue Sep 28 17:35:22 2010
@@ -45,49 +45,6 @@
 /*** Code. ***/
 
 
-/* Context baton for file_fetcher below. */
-struct ff_baton
-{
-  svn_client_ctx_t *ctx;       /* client context used to open ra session */
-  const char *repos_root;      /* repository root URL */
-  svn_ra_session_t *session;   /* the secondary ra session itself */
-  apr_pool_t *pool;            /* the pool where the ra session is allocated */
-};
-
-
-/* Implementation of svn_wc_get_file_t.  A feeble callback wrapper
-   around svn_ra_get_file(), so that the update_editor can use it to
-   fetch any file, any time. */
-static svn_error_t *
-file_fetcher(void *baton,
-             const char *path,
-             svn_revnum_t revision,
-             svn_stream_t *stream,
-             svn_revnum_t *fetched_rev,
-             apr_hash_t **props,
-             apr_pool_t *pool)
-{
-  struct ff_baton *ffb = (struct ff_baton *)baton;
-  const char *dirpath, *base_name, *session_url, *old_session_url;
-
-  svn_relpath_split(&dirpath, &base_name, path, pool);
-  session_url = svn_path_url_add_component2(ffb->repos_root, 
-                                            dirpath, pool);
-
-  if (ffb->session)
-    SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ffb->session,
-                                              session_url, ffb->pool));
-  else
-    SVN_ERR(svn_client__open_ra_session_internal(&(ffb->session), NULL,
-                                                 session_url, NULL, NULL,
-                                                 FALSE, TRUE,
-                                                 ffb->ctx, ffb->pool));
-
-  return svn_ra_get_file(ffb->session, base_name, revision, stream,
-                         fetched_rev, props, pool);
-}
-
-
 static svn_error_t *
 update_internal(svn_revnum_t *result_rev,
                 const char *local_abspath,
@@ -98,7 +55,6 @@ update_internal(svn_revnum_t *result_rev
                 svn_boolean_t ignore_externals,
                 svn_boolean_t allow_unver_obstructions,
                 svn_boolean_t *timestamp_sleep,
-                svn_boolean_t send_copyfrom_args,
                 svn_boolean_t innerupdate,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
@@ -120,7 +76,6 @@ update_internal(svn_revnum_t *result_rev
   svn_ra_session_t *ra_session;
   const char *preserved_exts_str;
   apr_array_header_t *preserved_exts;
-  struct ff_baton *ffb;
   svn_client__external_func_baton_t efb;
   svn_boolean_t server_supports_depth;
   svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
@@ -216,12 +171,6 @@ update_internal(svn_revnum_t *result_rev
      a strict sense, however.) */
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
 
-  /* Build a baton for the file-fetching callback. */
-  ffb = apr_pcalloc(pool, sizeof(*ffb));
-  ffb->ctx = ctx;
-  ffb->repos_root = repos_root;
-  ffb->pool = pool;
-
   /* Build a baton for the externals-info-gatherer callback. */
   efb.externals_new = apr_hash_make(pool);
   efb.externals_old = apr_hash_make(pool);
@@ -235,7 +184,6 @@ update_internal(svn_revnum_t *result_rev
                                     target, use_commit_times, depth,
                                     depth_is_sticky, allow_unver_obstructions,
                                     diff3_cmd, preserved_exts,
-                                    file_fetcher, ffb,
                                     ctx->conflict_func, ctx->conflict_baton,
                                     svn_client__external_info_gatherer, &efb,
                                     ctx->cancel_func, ctx->cancel_baton,
@@ -244,12 +192,8 @@ update_internal(svn_revnum_t *result_rev
 
   /* Tell RA to do an update of URL+TARGET to REVISION; if we pass an
      invalid revnum, that means RA will use the latest revision.  */
-  SVN_ERR(svn_ra_do_update2(ra_session,
-                            &reporter, &report_baton,
-                            revnum,
-                            target,
-                            depth,
-                            send_copyfrom_args,
+  SVN_ERR(svn_ra_do_update2(ra_session, &reporter, &report_baton,
+                            revnum, target, depth, FALSE,
                             update_editor, update_edit_baton, pool));
 
   SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
@@ -321,7 +265,6 @@ svn_client__update_internal(svn_revnum_t
                             svn_boolean_t ignore_externals,
                             svn_boolean_t allow_unver_obstructions,
                             svn_boolean_t *timestamp_sleep,
-                            svn_boolean_t send_copyfrom_args,
                             svn_boolean_t innerupdate,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool)
@@ -343,8 +286,7 @@ svn_client__update_internal(svn_revnum_t
   err = update_internal(result_rev, local_abspath, anchor_abspath,
                          revision, depth, depth_is_sticky,
                          ignore_externals, allow_unver_obstructions,
-                         timestamp_sleep, send_copyfrom_args,
-                         innerupdate, ctx, pool);
+                         timestamp_sleep, innerupdate, ctx, pool);
 
   err = svn_error_compose_create(
             err,
@@ -398,7 +340,7 @@ svn_client_update3(apr_array_header_t **
                                             revision, depth, depth_is_sticky,
                                             ignore_externals,
                                             allow_unver_obstructions,
-                                            &sleep, TRUE, FALSE, ctx, subpool);
+                                            &sleep, FALSE, ctx, subpool);
 
           if (err && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
             {

Modified: subversion/branches/javahl-ra/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_diff/parse-diff.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_diff/parse-diff.c Tue Sep 28 17:35:22 2010
@@ -183,7 +183,6 @@ parse_range(svn_linenum_t *start, svn_li
 /* Try to parse a hunk header in string HEADER, putting parsed information
  * into HUNK. Return TRUE if the header parsed correctly. ATAT is the
  * character string used to delimit the hunk header.
- * If REVERSE is TRUE, invert the hunk header while parsing it.
  * Do all allocations in POOL. */
 static svn_boolean_t
 parse_hunk_header(const char *header, svn_diff_hunk_t *hunk,
@@ -753,8 +752,8 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
 static int
 compare_hunks(const void *a, const void *b)
 {
-  const svn_diff_hunk_t *ha = *((const svn_diff_hunk_t **)a);
-  const svn_diff_hunk_t *hb = *((const svn_diff_hunk_t **)b);
+  const svn_diff_hunk_t *ha = *((const svn_diff_hunk_t *const *)a);
+  const svn_diff_hunk_t *hb = *((const svn_diff_hunk_t *const *)b);
 
   if (ha->original_start < hb->original_start)
     return -1;

Modified: subversion/branches/javahl-ra/subversion/libsvn_fs/access.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_fs/access.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_fs/access.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_fs/access.c Tue Sep 28 17:35:22 2010
@@ -87,7 +87,7 @@ svn_fs_access_add_lock_token2(svn_fs_acc
                               const char *token)
 {
   apr_hash_set(access_ctx->lock_tokens,
-               token, APR_HASH_KEY_STRING, (void *) path);
+               token, APR_HASH_KEY_STRING, path);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_fs_base/revs-txns.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_fs_base/revs-txns.c Tue Sep 28 17:35:22 2010
@@ -270,7 +270,7 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,
               && !svn_string_compare(wanted_value, present_value)))
         {
           /* What we expected isn't what we found. */
-          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
                                    _("revprop '%s' has unexpected value in "
                                      "filesystem"),
                                    name);

Modified: subversion/branches/javahl-ra/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_fs_fs/fs_fs.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_fs_fs/fs_fs.c Tue Sep 28 17:35:22 2010
@@ -7312,7 +7312,7 @@ change_rev_prop_body(void *baton, apr_po
               && !svn_string_compare(wanted_value, present_value)))
         {
           /* What we expected isn't what we found. */
-          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
                                    _("revprop '%s' has unexpected value in "
                                      "filesystem"),
                                    cb->name);

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra/deprecated.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra/deprecated.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra/deprecated.c Tue Sep 28 17:35:22 2010
@@ -196,6 +196,15 @@ svn_error_t *svn_ra_open(svn_ra_session_
                       config, pool);
 }
 
+svn_error_t *svn_ra_change_rev_prop(svn_ra_session_t *session,
+                                    svn_revnum_t rev,
+                                    const char *name,
+                                    const svn_string_t *value,
+                                    apr_pool_t *pool)
+{
+  return svn_ra_change_rev_prop2(session, rev, name, NULL, value, pool);
+}
+
 svn_error_t *svn_ra_get_commit_editor2(svn_ra_session_t *session,
                                        const svn_delta_editor_t **editor,
                                        void **edit_baton,

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.c Tue Sep 28 17:35:22 2010
@@ -612,14 +612,37 @@ svn_error_t *svn_ra_get_dated_revision(s
   return session->vtable->get_dated_revision(session, revision, tm, pool);
 }
 
-svn_error_t *svn_ra_change_rev_prop(svn_ra_session_t *session,
-                                    svn_revnum_t rev,
-                                    const char *name,
-                                    const svn_string_t *value,
-                                    apr_pool_t *pool)
+svn_error_t *svn_ra_change_rev_prop2(svn_ra_session_t *session,
+                                     svn_revnum_t rev,
+                                     const char *name,
+                                     const svn_string_t *const *old_value_p,
+                                     const svn_string_t *value,
+                                     apr_pool_t *pool)
 {
   SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
-  return session->vtable->change_rev_prop(session, rev, name, value, pool);
+
+  /* If an old value was specified, make sure the server supports
+   * specifying it. */
+  if (old_value_p)
+    {
+      svn_boolean_t has_atomic_revprops;
+
+      SVN_ERR(svn_ra_has_capability(session, &has_atomic_revprops,
+                                    SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                                    pool));
+
+      if (!has_atomic_revprops)
+        /* API violation.  (Should be an ASSERT, but gstein talked me
+         * out of it.) */
+        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                 _("Specifying 'old_value_p' is not allowed when "
+                                   "the '%s' capability is not advertised, and "
+                                   "could indicate a bug in your client"),
+                                   SVN_RA_CAPABILITY_ATOMIC_REVPROPS);
+    }
+
+  return session->vtable->change_rev_prop(session, rev, name,
+                                          old_value_p, value, pool);
 }
 
 svn_error_t *svn_ra_rev_proplist(svn_ra_session_t *session,

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.h?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.h Tue Sep 28 17:35:22 2010
@@ -77,6 +77,7 @@ typedef struct svn_ra__vtable_t {
   svn_error_t *(*change_rev_prop)(svn_ra_session_t *session,
                                   svn_revnum_t rev,
                                   const char *name,
+                                  const svn_string_t *const *old_value_p,
                                   const svn_string_t *value,
                                   apr_pool_t *pool);
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra/wrapper_template.h?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra/wrapper_template.h Tue Sep 28 17:35:22 2010
@@ -127,7 +127,7 @@ static svn_error_t *compat_change_rev_pr
                                            const svn_string_t *value,
                                            apr_pool_t *pool)
 {
-  return VTBL.change_rev_prop(session_baton, rev, propname, value, pool);
+  return VTBL.change_rev_prop(session_baton, rev, propname, NULL, value, pool);
 }
 
 static svn_error_t *compat_rev_proplist(void *session_baton,

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_local/ra_plugin.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_local/ra_plugin.c Tue Sep 28 17:35:22 2010
@@ -563,14 +563,16 @@ static svn_error_t *
 svn_ra_local__change_rev_prop(svn_ra_session_t *session,
                               svn_revnum_t rev,
                               const char *name,
+                              const svn_string_t *const *old_value_p,
                               const svn_string_t *value,
                               apr_pool_t *pool)
 {
   svn_ra_local__session_baton_t *sess = session->priv;
+
   SVN_ERR(get_username(session, pool));
-  return svn_repos_fs_change_rev_prop3(sess->repos, rev, sess->username,
-                                       name, value, TRUE, TRUE, NULL, NULL,
-                                       pool);
+  return svn_repos_fs_change_rev_prop4(sess->repos, rev, sess->username,
+                                       name, old_value_p, value, TRUE, TRUE,
+                                       NULL, NULL, pool);
 }
 
 static svn_error_t *
@@ -1389,7 +1391,8 @@ svn_ra_local__has_capability(svn_ra_sess
   if (strcmp(capability, SVN_RA_CAPABILITY_DEPTH) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_LOG_REVPROPS) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_PARTIAL_REPLAY) == 0
-      || strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0)
+      || strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0
+      || strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0)
     {
       *has = TRUE;
     }

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_neon/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_neon/commit.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_neon/commit.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_neon/commit.c Tue Sep 28 17:35:22 2010
@@ -616,7 +616,8 @@ static svn_error_t * do_proppatch(svn_ra
     }
 
   return svn_ra_neon__do_proppatch(ras, url, rb->prop_changes,
-                                   rb->prop_deletes, extra_headers, pool);
+                                   rb->prop_deletes, NULL, extra_headers,
+                                   pool);
 }
 
 
@@ -1416,7 +1417,7 @@ static svn_error_t * apply_revprops(comm
     return err;
 
   return svn_ra_neon__do_proppatch(cc->ras, vcc_rsrc.wr_url, revprop_table,
-                                   NULL, NULL, pool);
+                                   NULL, NULL, NULL, pool);
 }
 
 svn_error_t * svn_ra_neon__get_commit_editor(svn_ra_session_t *session,

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_neon/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_neon/fetch.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_neon/fetch.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_neon/fetch.c Tue Sep 28 17:35:22 2010
@@ -1122,6 +1122,7 @@ svn_error_t *svn_ra_neon__get_latest_rev
 svn_error_t *svn_ra_neon__change_rev_prop(svn_ra_session_t *session,
                                           svn_revnum_t rev,
                                           const char *name,
+                                          const svn_string_t *const *old_value_p,
                                           const svn_string_t *value,
                                           apr_pool_t *pool)
 {
@@ -1130,12 +1131,24 @@ svn_error_t *svn_ra_neon__change_rev_pro
   svn_error_t *err;
   apr_hash_t *prop_changes = NULL;
   apr_array_header_t *prop_deletes = NULL;
+  apr_hash_t *prop_old_values = NULL;
   static const ne_propname wanted_props[] =
     {
       { "DAV:", "auto-version" },
       { NULL }
     };
 
+  if (old_value_p)
+    {
+      svn_boolean_t capable;
+      SVN_ERR(svn_ra_neon__has_capability(session, &capable,
+                                          SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                                          pool));
+
+      /* How did you get past the same check in svn_ra_change_rev_prop2()? */
+      SVN_ERR_ASSERT(capable);
+    }
+
   /* Main objective: do a PROPPATCH (allprops) on a baseline object */
 
   /* ### A Word From Our Sponsor:  see issue #916.
@@ -1165,19 +1178,33 @@ svn_error_t *svn_ra_neon__change_rev_pro
          to attempt the PROPPATCH if the deltaV server is going to do
          auto-versioning and create a new baseline! */
 
-  if (value)
+  if (old_value_p)
     {
-      prop_changes = apr_hash_make(pool);
-      apr_hash_set(prop_changes, name, APR_HASH_KEY_STRING, value);
+      svn_dav__two_props_t *both_values;
+
+      both_values = apr_palloc(pool, sizeof(*both_values));
+      both_values->old_value_p = old_value_p;
+      both_values->new_value = value;
+
+      prop_old_values = apr_hash_make(pool);
+      apr_hash_set(prop_old_values, name, APR_HASH_KEY_STRING, both_values);
     }
   else
     {
-      prop_deletes = apr_array_make(pool, 1, sizeof(const char *));
-      APR_ARRAY_PUSH(prop_deletes, const char *) = name;
+      if (value)
+        {
+          prop_changes = apr_hash_make(pool);
+          apr_hash_set(prop_changes, name, APR_HASH_KEY_STRING, value);
+        }
+      else
+        {
+          prop_deletes = apr_array_make(pool, 1, sizeof(const char *));
+          APR_ARRAY_PUSH(prop_deletes, const char *) = name;
+        }
     }
 
   err = svn_ra_neon__do_proppatch(ras, baseline->url, prop_changes,
-                                  prop_deletes, NULL, pool);
+                                  prop_deletes, prop_old_values, NULL, pool);
   if (err)
     return
       svn_error_create

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_neon/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_neon/options.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_neon/options.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_neon/options.c Tue Sep 28 17:35:22 2010
@@ -152,6 +152,8 @@ parse_capabilities(ne_request *req,
                APR_HASH_KEY_STRING, capability_no);
   apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
                APR_HASH_KEY_STRING, capability_no);
+  apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+               APR_HASH_KEY_STRING, capability_no);
 
   /* Then find out which ones are supported. */
   val = ne_get_response_header(req, "dav");
@@ -199,6 +201,10 @@ parse_capabilities(ne_request *req,
         apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
                      APR_HASH_KEY_STRING, capability_yes);
 
+      if (svn_cstring_match_glob_list(SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS, vals))
+        apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                     APR_HASH_KEY_STRING, capability_yes);
+
       if (svn_cstring_match_glob_list(SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY,
                                       vals))
         apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_neon/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_neon/props.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_neon/props.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_neon/props.c Tue Sep 28 17:35:22 2010
@@ -1075,12 +1075,14 @@ get_encoding_and_cdata(const char **enco
 static svn_error_t *
 append_setprop(svn_stringbuf_t *body,
                const char *name,
+               const svn_string_t *const *old_value_p,
                const svn_string_t *value,
                apr_pool_t *pool)
 {
   const char *encoding;
   const char *xml_safe;
   const char *xml_tag_name;
+  const char *old_value_tag;
 
   /* Map property names to namespaces */
 #define NSLEN (sizeof(SVN_PROP_PREFIX) - 1)
@@ -1094,11 +1096,45 @@ append_setprop(svn_stringbuf_t *body,
       xml_tag_name = apr_pstrcat(pool, "C:", name, NULL);
     }
 
-  SVN_ERR(get_encoding_and_cdata(&encoding, &xml_safe, value, pool));
+  if (old_value_p)
+    {
+      if (*old_value_p)
+        {
+          const char *encoding2;
+          const char *xml_safe2;
+          SVN_ERR(get_encoding_and_cdata(&encoding2, &xml_safe2,
+                                         *old_value_p, pool));
+          old_value_tag = apr_psprintf(pool, "<%s %s>%s</%s>",
+                                       "V:" SVN_DAV__OLD_VALUE, encoding2,
+                                       xml_safe2, "V:" SVN_DAV__OLD_VALUE);
+        }
+      else
+        {
+#define OLD_VALUE_ABSENT_TAG \
+          "<" "V:" SVN_DAV__OLD_VALUE \
+              " V:" SVN_DAV__OLD_VALUE__ABSENT "=\"1\" " \
+          "/>"
+          old_value_tag = OLD_VALUE_ABSENT_TAG;
+        }
+    }
+  else
+    {
+      old_value_tag = "";
+    }
+
+  if (old_value_p && !value)
+    {
+      encoding = "V:" SVN_DAV__OLD_VALUE__ABSENT "=\"1\"" ;
+      xml_safe = "";
+    }
+  else
+    {
+      SVN_ERR(get_encoding_and_cdata(&encoding, &xml_safe, value, pool));
+    }
 
   svn_stringbuf_appendcstr(body,
-                           apr_psprintf(pool,"<%s %s>%s</%s>",
-                                        xml_tag_name, encoding,
+                           apr_psprintf(pool,"<%s %s>%s%s</%s>",
+                                        xml_tag_name, encoding, old_value_tag,
                                         xml_safe, xml_tag_name));
   return SVN_NO_ERROR;
 }
@@ -1109,6 +1145,7 @@ svn_ra_neon__do_proppatch(svn_ra_neon__s
                           const char *url,
                           apr_hash_t *prop_changes,
                           const apr_array_header_t *prop_deletes,
+                          apr_hash_t *prop_old_values,
                           apr_hash_t *extra_headers,
                           apr_pool_t *pool)
 {
@@ -1118,7 +1155,8 @@ svn_ra_neon__do_proppatch(svn_ra_neon__s
 
   /* just punt if there are no changes to make. */
   if ((prop_changes == NULL || (! apr_hash_count(prop_changes)))
-      && (prop_deletes == NULL || prop_deletes->nelts == 0))
+      && (prop_deletes == NULL || prop_deletes->nelts == 0)
+      && (prop_old_values == NULL || (! apr_hash_count(prop_old_values))))
     return SVN_NO_ERROR;
 
   /* easier to roll our own PROPPATCH here than use ne_proppatch(), which
@@ -1130,6 +1168,22 @@ svn_ra_neon__do_proppatch(svn_ra_neon__s
      SVN_DAV_PROP_NS_CUSTOM "\" xmlns:S=\""
      SVN_DAV_PROP_NS_SVN "\">" DEBUG_CR, pool);
 
+  /* Handle property changes/deletions with expected old values. */
+  if (prop_old_values)
+    {
+      apr_hash_index_t *hi;
+      svn_stringbuf_appendcstr(body, "<D:set><D:prop>");
+      for (hi = apr_hash_first(pool, prop_old_values); hi; hi = apr_hash_next(hi))
+        {
+          const char *name = svn__apr_hash_index_key(hi);
+          svn_dav__two_props_t *both_values = svn__apr_hash_index_val(hi);
+          svn_pool_clear(subpool);
+          SVN_ERR(append_setprop(body, name, both_values->old_value_p,
+                                 both_values->new_value, subpool));
+        }
+      svn_stringbuf_appendcstr(body, "</D:prop></D:set>");
+    }
+
   /* Handle property changes. */
   if (prop_changes)
     {
@@ -1141,7 +1195,7 @@ svn_ra_neon__do_proppatch(svn_ra_neon__s
           void *val;
           svn_pool_clear(subpool);
           apr_hash_this(hi, &key, NULL, &val);
-          SVN_ERR(append_setprop(body, key, val, subpool));
+          SVN_ERR(append_setprop(body, key, NULL, val, subpool));
         }
       svn_stringbuf_appendcstr(body, "</D:prop></D:set>");
     }
@@ -1155,7 +1209,7 @@ svn_ra_neon__do_proppatch(svn_ra_neon__s
         {
           const char *name = APR_ARRAY_IDX(prop_deletes, n, const char *);
           svn_pool_clear(subpool);
-          SVN_ERR(append_setprop(body, name, NULL, subpool));
+          SVN_ERR(append_setprop(body, name, NULL, NULL, subpool));
         }
       svn_stringbuf_appendcstr(body, "</D:prop></D:remove>");
     }

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_neon/ra_neon.h?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_neon/ra_neon.h Tue Sep 28 17:35:22 2010
@@ -254,6 +254,7 @@ svn_error_t *svn_ra_neon__get_dated_revi
 svn_error_t *svn_ra_neon__change_rev_prop(svn_ra_session_t *session,
                                           svn_revnum_t rev,
                                           const char *name,
+                                          const svn_string_t *const *old_value_p,
                                           const svn_string_t *value,
                                           apr_pool_t *pool);
 
@@ -575,12 +576,15 @@ svn_error_t *svn_ra_neon__get_vcc(const 
 /* Issue a PROPPATCH request on URL, transmitting PROP_CHANGES (a hash
    of const svn_string_t * values keyed on Subversion user-visible
    property names) and PROP_DELETES (an array of property names to
-   delete).  Send any extra request headers in EXTRA_HEADERS. Use POOL
-   for all allocations.  */
+   delete). PROP_OLD_VALUES is a hash of Subversion user-visible property
+   names mapped to svn_dav__two_props_t * values. Send any extra
+   request headers in EXTRA_HEADERS. Use POOL for all allocations.
+ */
 svn_error_t *svn_ra_neon__do_proppatch(svn_ra_neon__session_t *ras,
                                        const char *url,
                                        apr_hash_t *prop_changes,
                                        const apr_array_header_t *prop_deletes,
+                                       apr_hash_t *prop_old_values,
                                        apr_hash_t *extra_headers,
                                        apr_pool_t *pool);
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_neon/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_neon/util.c?rev=1002283&r1=1002282&r2=1002283&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_neon/util.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_neon/util.c Tue Sep 28 17:35:22 2010
@@ -167,6 +167,7 @@ typedef struct
   svn_ra_neon__request_t *req;
   svn_stringbuf_t *description;
   svn_boolean_t contains_error;
+  svn_boolean_t contains_precondition_error;
 } multistatus_baton_t;
 
 /* Implements svn_ra_neon__startelm_cb_t. */
@@ -231,6 +232,9 @@ end_207_element(void *baton, int state,
             return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                     _("The request response contained at least "
                                       "one error"));
+          else if (b->contains_precondition_error) 
+            return svn_error_create(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
+                                    b->description->data);
           else
             return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                     b->description->data);
@@ -260,6 +264,10 @@ end_207_element(void *baton, int state,
             else
               b->propstat_has_error = (status.klass != 2);
 
+            /* Handle "412 Precondition Failed" specially */
+            if (status.code == 412)
+              b->contains_precondition_error = TRUE;
+
             free(status.reason_phrase);
           }
         else