You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2013/01/06 03:33:39 UTC

svn commit: r1429457 [14/21] - in /subversion/branches/tree-read-api: ./ build/ build/ac-macros/ build/generator/templates/ build/win32/ contrib/server-side/svncutter/ doc/ subversion/bindings/cxxhl/include/ subversion/bindings/cxxhl/include/svncxxhl/ ...

Modified: subversion/branches/tree-read-api/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_authz_svn/mod_authz_svn.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_authz_svn/mod_authz_svn.c Sun Jan  6 02:33:34 2013
@@ -87,6 +87,34 @@ create_authz_svn_dir_config(apr_pool_t *
   return conf;
 }
 
+/* canonicalize ACCESS_FILE based on the type of argument.
+ * If SERVER_RELATIVE is true, ACCESS_FILE is a relative
+ * path then ACCESS_FILE is converted to an absolute
+ * path rooted at the server root. */
+static const char *
+canonicalize_access_file(const char *access_file,
+                         svn_boolean_t server_relative,
+                         apr_pool_t *pool)
+{
+  if (svn_path_is_url(access_file))
+    {
+      access_file = svn_uri_canonicalize(access_file, pool);
+    }
+  else if (!svn_path_is_repos_relative_url(access_file))
+    {
+      if (server_relative)
+        access_file = ap_server_root_relative(pool, access_file);
+
+      access_file = svn_dirent_internal_style(access_file, pool);
+    }
+
+  /* We don't canonicalize repos relative urls since they get
+   * canonicalized inside svn_repos_authz_read2() when they
+   * are resolved. */
+
+  return access_file;
+}
+
 static const char *
 AuthzSVNAccessFile_cmd(cmd_parms *cmd, void *config, const char *arg1)
 {
@@ -96,7 +124,7 @@ AuthzSVNAccessFile_cmd(cmd_parms *cmd, v
     return "AuthzSVNAccessFile and AuthzSVNReposRelativeAccessFile "
            "directives are mutually exclusive.";
 
-  conf->access_file = ap_server_root_relative(cmd->pool, arg1);
+  conf->access_file = canonicalize_access_file(arg1, TRUE, cmd->pool);
 
   return NULL;
 }
@@ -113,7 +141,8 @@ AuthzSVNReposRelativeAccessFile_cmd(cmd_
     return "AuthzSVNAccessFile and AuthzSVNReposRelativeAccessFile "
            "directives are mutually exclusive.";
 
-  conf->repo_relative_access_file = arg1;
+  conf->repo_relative_access_file = canonicalize_access_file(arg1, FALSE,
+                                                             cmd->pool);
 
   return NULL;
 }
@@ -130,13 +159,17 @@ static const command_rec authz_svn_cmds[
                 NULL,
                 OR_AUTHCFG,
                 "Path to text file containing permissions of repository "
-                "paths."),
+                "paths.  Path may be an repository relative URL (^/) or "
+                "absolute file:// URL to a text file in a Subversion "
+                "repository."),
   AP_INIT_TAKE1("AuthzSVNReposRelativeAccessFile",
                 AuthzSVNReposRelativeAccessFile_cmd,
                 NULL,
                 OR_AUTHCFG,
                 "Path (relative to repository 'conf' directory) to text "
-                "file containing permissions of repository paths. "),
+                "file containing permissions of repository paths. Path may "
+                "be an repository relative URL (^/) or absolute file:// URL "
+                "to a text file in a Subversion repository."),
   AP_INIT_FLAG("AuthzSVNAnonymous", ap_set_flag_slot,
                (void *)APR_OFFSETOF(authz_svn_config_rec, anonymous),
                OR_AUTHCFG,
@@ -161,6 +194,102 @@ static const command_rec authz_svn_cmds[
   { NULL }
 };
 
+
+/* The macros LOG_ARGS_SIGNATURE and LOG_ARGS_CASCADE are expanded as formal
+ * and actual parameters to log_access_verdict with respect to HTTPD version.
+ */
+#if AP_MODULE_MAGIC_AT_LEAST(20100606,0)
+#define LOG_ARGS_SIGNATURE const char *file, int line, int module_index
+#define LOG_ARGS_CASCADE file, line, module_index
+#else
+#define LOG_ARGS_SIGNATURE const char *file, int line
+#define LOG_ARGS_CASCADE file, line
+#endif
+
+/* Log a message indicating the access control decision made about a
+ * request.  The macro LOG_ARGS_SIGNATURE expands to FILE, LINE and
+ * MODULE_INDEX in HTTPD 2.3 as APLOG_MARK macro has been changed for
+ * per-module loglevel configuration.  It expands to FILE and LINE
+ * in older server versions.  ALLOWED is boolean.
+ * REPOS_PATH and DEST_REPOS_PATH are information
+ * about the request.  DEST_REPOS_PATH may be NULL. */
+static void
+log_access_verdict(LOG_ARGS_SIGNATURE,
+                   const request_rec *r, int allowed,
+                   const char *repos_path, const char *dest_repos_path)
+{
+  int level = allowed ? APLOG_INFO : APLOG_ERR;
+  const char *verdict = allowed ? "granted" : "denied";
+
+  if (r->user)
+    {
+      if (dest_repos_path)
+        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
+                      "Access %s: '%s' %s %s %s", verdict, r->user,
+                      r->method, repos_path, dest_repos_path);
+      else
+        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
+                      "Access %s: '%s' %s %s", verdict, r->user,
+                      r->method, repos_path);
+    }
+  else
+    {
+      if (dest_repos_path)
+        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
+                      "Access %s: - %s %s %s", verdict,
+                      r->method, repos_path, dest_repos_path);
+      else
+        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
+                      "Access %s: - %s %s", verdict,
+                      r->method, repos_path);
+    }
+}
+
+/* Log a message indiciating the ERR encountered during the request R.
+ * LOG_ARGS_SIGNATURE expands as in log_access_verdict() above.
+ * PREFIX is inserted at the start of the message.  The rest of the
+ * message is generated by combining the message for each error in the
+ * chain of ERR, excluding for trace errors.  ERR will be cleared
+ * when finished. */
+static void
+log_svn_error(LOG_ARGS_SIGNATURE,
+              request_rec *r, const char *prefix,
+              svn_error_t *err, apr_pool_t *scratch_pool)
+{
+  svn_error_t *err_pos = svn_error_purge_tracing(err);
+  svn_stringbuf_t *buff = svn_stringbuf_create(prefix, scratch_pool);
+
+  /* Build the error chain into a space separated stringbuf. */
+  while (err_pos)
+    {
+      svn_stringbuf_appendbyte(buff, ' ');
+      if (err_pos->message)
+        {
+          svn_stringbuf_appendcstr(buff, err_pos->message);
+        }
+      else
+        {
+          char strerr[256];
+          
+          svn_stringbuf_appendcstr(buff, svn_strerror(err->apr_err, strerr,
+                                                       sizeof(strerr)));
+        }
+
+      err_pos = err_pos->child;
+    }
+
+  ap_log_rerror(LOG_ARGS_CASCADE, APLOG_ERR,
+                /* If it is an error code that APR can make sense of, then
+                   show it, otherwise, pass zero to avoid putting "APR does
+                   not understand this error code" in the error log. */
+                ((err->apr_err >= APR_OS_START_USERERR &&
+                  err->apr_err < APR_OS_START_CANONERR) ?
+                 0 : err->apr_err),
+                r, "%s", buff->data);
+
+  svn_error_clear(err);
+}
+
 /*
  * Get the, possibly cached, svn_authz_t for this request.
  */
@@ -175,18 +304,24 @@ get_access_conf(request_rec *r, authz_sv
   svn_authz_t *access_conf = NULL;
   svn_error_t *svn_err;
   dav_error *dav_err;
-  char errbuf[256];
+
+  dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_path);
+  if (dav_err)
+    {
+      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", dav_err->desc);
+      return NULL;
+    }
 
   if (conf->repo_relative_access_file)
     {
-      dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_path);
-      if (dav_err) {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", dav_err->desc);
-        return NULL;
-      }
-      access_file = svn_dirent_join_many(scratch_pool, repos_path, "conf",
-                                         conf->repo_relative_access_file,
-                                         NULL);
+      access_file = conf->repo_relative_access_file;
+      if (!svn_path_is_repos_relative_url(access_file) &&
+          !svn_path_is_url(access_file))
+        {
+          access_file = svn_dirent_join_many(scratch_pool, repos_path, "conf",
+                                             conf->repo_relative_access_file,
+                                             NULL);
+        }
     }
   else
     {
@@ -202,21 +337,13 @@ get_access_conf(request_rec *r, authz_sv
   access_conf = user_data;
   if (access_conf == NULL)
     {
-      svn_err = svn_repos_authz_read(&access_conf, access_file,
-                                     TRUE, r->connection->pool);
+      svn_err = svn_repos_authz_read2(&access_conf, access_file,
+                                      TRUE, repos_path, r->connection->pool);
       if (svn_err)
         {
-          ap_log_rerror(APLOG_MARK, APLOG_ERR,
-                        /* If it is an error code that APR can make sense
-                           of, then show it, otherwise, pass zero to avoid
-                           putting "APR does not understand this error code"
-                           in the error log. */
-                        ((svn_err->apr_err >= APR_OS_START_USERERR &&
-                          svn_err->apr_err < APR_OS_START_CANONERR) ?
-                         0 : svn_err->apr_err),
-                        r, "Failed to load the AuthzSVNAccessFile: %s",
-                        svn_err_best_message(svn_err, errbuf, sizeof(errbuf)));
-          svn_error_clear(svn_err);
+          log_svn_error(APLOG_MARK, r,
+                        "Failed to load the AuthzSVNAccessFile:",
+                        svn_err, scratch_pool);
           access_conf = NULL;
         }
       else
@@ -285,7 +412,6 @@ req_check_access(request_rec *r,
   svn_boolean_t authz_access_granted = FALSE;
   svn_authz_t *access_conf = NULL;
   svn_error_t *svn_err;
-  char errbuf[256];
   const char *username_to_authorize = get_username_to_authorize(r, conf,
                                                                 r->pool);
 
@@ -458,19 +584,9 @@ req_check_access(request_rec *r,
                                              r->pool);
       if (svn_err)
         {
-          ap_log_rerror(APLOG_MARK, APLOG_ERR,
-                        /* If it is an error code that APR can make
-                           sense of, then show it, otherwise, pass
-                           zero to avoid putting "APR does not
-                           understand this error code" in the error
-                           log. */
-                        ((svn_err->apr_err >= APR_OS_START_USERERR &&
-                          svn_err->apr_err < APR_OS_START_CANONERR) ?
-                          0 : svn_err->apr_err),
-                         r, "Failed to perform access control: %s",
-                         svn_err_best_message(svn_err, errbuf,
-                                              sizeof(errbuf)));
-          svn_error_clear(svn_err);
+          log_svn_error(APLOG_MARK, r,
+                        "Failed to perform access control:",
+                        svn_err, r->pool);
 
           return DECLINED;
         }
@@ -505,17 +621,9 @@ req_check_access(request_rec *r,
                                              r->pool);
       if (svn_err)
         {
-          ap_log_rerror(APLOG_MARK, APLOG_ERR,
-                        /* If it is an error code that APR can make sense
-                           of, then show it, otherwise, pass zero to avoid
-                           putting "APR does not understand this error code"
-                           in the error log. */
-                        ((svn_err->apr_err >= APR_OS_START_USERERR &&
-                          svn_err->apr_err < APR_OS_START_CANONERR) ?
-                         0 : svn_err->apr_err),
-                        r, "Failed to perform access control: %s",
-                        svn_err_best_message(svn_err, errbuf, sizeof(errbuf)));
-          svn_error_clear(svn_err);
+          log_svn_error(APLOG_MARK, r,
+                        "Failed to perform access control:",
+                        svn_err, r->pool);
 
           return DECLINED;
         }
@@ -530,56 +638,6 @@ req_check_access(request_rec *r,
   return OK;
 }
 
-/* The macros LOG_ARGS_SIGNATURE and LOG_ARGS_CASCADE are expanded as formal
- * and actual parameters to log_access_verdict with respect to HTTPD version.
- */
-#if AP_MODULE_MAGIC_AT_LEAST(20100606,0)
-#define LOG_ARGS_SIGNATURE const char *file, int line, int module_index
-#define LOG_ARGS_CASCADE file, line, module_index
-#else
-#define LOG_ARGS_SIGNATURE const char *file, int line
-#define LOG_ARGS_CASCADE file, line
-#endif
-
-/* Log a message indicating the access control decision made about a
- * request.  The macro LOG_ARGS_SIGNATURE expands to FILE, LINE and
- * MODULE_INDEX in HTTPD 2.3 as APLOG_MARK macro has been changed for
- * per-module loglevel configuration.  It expands to FILE and LINE
- * in older server versions.  ALLOWED is boolean.
- * REPOS_PATH and DEST_REPOS_PATH are information
- * about the request.  DEST_REPOS_PATH may be NULL. */
-static void
-log_access_verdict(LOG_ARGS_SIGNATURE,
-                   const request_rec *r, int allowed,
-                   const char *repos_path, const char *dest_repos_path)
-{
-  int level = allowed ? APLOG_INFO : APLOG_ERR;
-  const char *verdict = allowed ? "granted" : "denied";
-
-  if (r->user)
-    {
-      if (dest_repos_path)
-        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
-                      "Access %s: '%s' %s %s %s", verdict, r->user,
-                      r->method, repos_path, dest_repos_path);
-      else
-        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
-                      "Access %s: '%s' %s %s", verdict, r->user,
-                      r->method, repos_path);
-    }
-  else
-    {
-      if (dest_repos_path)
-        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
-                      "Access %s: - %s %s %s", verdict,
-                      r->method, repos_path, dest_repos_path);
-      else
-        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
-                      "Access %s: - %s %s", verdict,
-                      r->method, repos_path);
-    }
-}
-
 /*
  * Implementation of subreq_bypass with scratch_pool parameter.
  */
@@ -593,7 +651,6 @@ subreq_bypass2(request_rec *r,
   svn_authz_t *access_conf = NULL;
   authz_svn_config_rec *conf = NULL;
   svn_boolean_t authz_access_granted = FALSE;
-  char errbuf[256];
   const char *username_to_authorize;
 
   conf = ap_get_module_config(r->per_dir_config,
@@ -626,18 +683,9 @@ subreq_bypass2(request_rec *r,
                                              scratch_pool);
       if (svn_err)
         {
-          ap_log_rerror(APLOG_MARK, APLOG_ERR,
-                        /* If it is an error code that APR can make
-                           sense of, then show it, otherwise, pass
-                           zero to avoid putting "APR does not
-                           understand this error code" in the error
-                           log. */
-                        ((svn_err->apr_err >= APR_OS_START_USERERR &&
-                          svn_err->apr_err < APR_OS_START_CANONERR) ?
-                         0 : svn_err->apr_err),
-                        r, "Failed to perform access control: %s",
-                        svn_err_best_message(svn_err, errbuf, sizeof(errbuf)));
-          svn_error_clear(svn_err);
+          log_svn_error(APLOG_MARK, r,
+                        "Failed to perform access control:",
+                        svn_err, scratch_pool);
           return HTTP_FORBIDDEN;
         }
       if (!authz_access_granted)

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/authz.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/authz.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/authz.c Sun Jan  6 02:33:34 2013
@@ -105,7 +105,6 @@ dav_svn__allow_list_repos(request_rec *r
   const char *uri;
   request_rec *subreq;
   svn_boolean_t allowed = FALSE;
-  authz_svn__subreq_bypass_func_t allow_read_bypass = NULL;
 
   /* Easy out:  if the admin has explicitly set 'SVNPathAuthz Off',
      then this whole callback does nothing. */
@@ -114,19 +113,8 @@ dav_svn__allow_list_repos(request_rec *r
       return TRUE;
     }
 
-  /* If bypass is specified and authz has exported the provider.
-     Otherwise, we fall through to the full version.  This should be
-     safer than allowing or disallowing all accesses if there is a
-     configuration error.
-     XXX: Is this the proper thing to do in this case? */
-  allow_read_bypass = dav_svn__get_pathauthz_bypass(r);
-  if (allow_read_bypass != NULL)
-    {
-      if (allow_read_bypass(r, "/", repos_name) == OK)
-        return TRUE;
-      else
-        return FALSE;
-    }
+  /* Do not use short_circuit mode: bypass provider expects R to be request to
+     the repository to find repository relative authorization file. */
 
   /* Build a Public Resource uri representing repository root. */
   uri =  svn_urlpath__join(dav_svn__get_root_dir(r),

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/dav_svn.h?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/dav_svn.h Sun Jan  6 02:33:34 2013
@@ -52,6 +52,12 @@ extern "C" {
 /* a pool-key for the shared dav_svn_root used by autoversioning  */
 #define DAV_SVN__AUTOVERSIONING_ACTIVITY "svn-autoversioning-activity"
 
+/* Option values for SVNAllowBulkUpdates */
+typedef enum dav_svn__bulk_upd_conf {
+    CONF_BULKUPD_ON,
+    CONF_BULKUPD_OFF,
+    CONF_BULKUPD_PREFER
+} dav_svn__bulk_upd_conf;
 
 /* dav_svn_repos
  *
@@ -110,7 +116,7 @@ typedef struct dav_svn_repos {
   svn_boolean_t autoversioning;
 
   /* Whether bulk updates are allowed for this repository. */
-  svn_boolean_t bulk_updates;
+  dav_svn__bulk_upd_conf bulk_updates;
 
   /* Whether HTTP protocol version 2 is allowed to be used. */
   svn_boolean_t v2_protocol;
@@ -302,7 +308,7 @@ const char *dav_svn__get_fs_parent_path(
 svn_boolean_t dav_svn__get_autoversioning_flag(request_rec *r);
 
 /* for the repository referred to by this request, are bulk updates allowed? */
-svn_boolean_t dav_svn__get_bulk_updates_flag(request_rec *r);
+dav_svn__bulk_upd_conf dav_svn__get_bulk_updates_flag(request_rec *r);
 
 /* for the repository referred to by this request, are subrequests active? */
 svn_boolean_t dav_svn__get_pathauthz_flag(request_rec *r);

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/mirror.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/mirror.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/mirror.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/mirror.c Sun Jan  6 02:33:34 2013
@@ -39,12 +39,17 @@
    URI_SEGMENT is the URI bits relative to the repository root (but if
    non-empty, *does* have a leading slash delimiter).
    MASTER_URI and URI_SEGMENT are not URI-encoded. */
-static void proxy_request_fixup(request_rec *r,
-                                const char *master_uri,
-                                const char *uri_segment)
+static int proxy_request_fixup(request_rec *r,
+                               const char *master_uri,
+                               const char *uri_segment)
 {
-    assert((uri_segment[0] == '\0')
-           || (uri_segment[0] == '/'));
+    if (uri_segment[0] != '\0' && uri_segment[0] != '/')
+      {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, SVN_ERR_BAD_CONFIG_VALUE, r,
+                     "Invalid URI segment '%s' in slave fixup",
+                      uri_segment);
+        return HTTP_INTERNAL_SERVER_ERROR;
+      }
 
     r->proxyreq = PROXYREQ_REVERSE;
     r->uri = r->unparsed_uri;
@@ -67,6 +72,7 @@ static void proxy_request_fixup(request_
     ap_add_output_filter("LocationRewrite", NULL, r, r->connection);
     ap_add_output_filter("ReposRewrite", NULL, r, r->connection);
     ap_add_input_filter("IncomingRewrite", NULL, r, r->connection);
+    return OK;
 }
 
 
@@ -101,8 +107,10 @@ int dav_svn__proxy_request_fixup(request
                                                     "/txn/", (char *)NULL))
                     || ap_strstr_c(seg, apr_pstrcat(r->pool, special_uri,
                                                     "/txr/", (char *)NULL))) {
+                    int rv;
                     seg += strlen(root_dir);
-                    proxy_request_fixup(r, master_uri, seg);
+                    rv = proxy_request_fixup(r, master_uri, seg);
+                    if (rv) return rv;
                 }
             }
             return OK;
@@ -116,8 +124,10 @@ int dav_svn__proxy_request_fixup(request
                     r->method_number == M_LOCK ||
                     r->method_number == M_UNLOCK ||
                     ap_strstr_c(seg, special_uri))) {
+            int rv;
             seg += strlen(root_dir);
-            proxy_request_fixup(r, master_uri, seg);
+            rv = proxy_request_fixup(r, master_uri, seg);
+            if (rv) return rv;
             return OK;
         }
     }

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/mod_dav_svn.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/mod_dav_svn.c Sun Jan  6 02:33:34 2013
@@ -93,7 +93,7 @@ typedef struct dir_conf_t {
   const char *xslt_uri;              /* XSL transform URI */
   const char *fs_parent_path;        /* path to parent of SVN FS'es  */
   enum conf_flag autoversioning;     /* whether autoversioning is active */
-  enum conf_flag bulk_updates;       /* whether bulk updates are allowed */
+  dav_svn__bulk_upd_conf bulk_updates; /* whether bulk updates are allowed */
   enum conf_flag v2_protocol;        /* whether HTTP v2 is advertised */
   enum path_authz_conf path_authz_method; /* how GET subrequests are handled */
   enum conf_flag list_parentpath;    /* whether to allow GET of parentpath */
@@ -213,7 +213,7 @@ create_dir_config(apr_pool_t *p, char *d
      <Location /blah> directive. So we treat it as a urlpath. */
   if (dir)
     conf->root_dir = svn_urlpath__canonicalize(dir, p);
-  conf->bulk_updates = CONF_FLAG_ON;
+  conf->bulk_updates = CONF_BULKUPD_ON;
   conf->v2_protocol = CONF_FLAG_ON;
   conf->hooks_env = NULL;
 
@@ -357,14 +357,26 @@ SVNAutoversioning_cmd(cmd_parms *cmd, vo
 
 
 static const char *
-SVNAllowBulkUpdates_cmd(cmd_parms *cmd, void *config, int arg)
+SVNAllowBulkUpdates_cmd(cmd_parms *cmd, void *config, const char *arg1)
 {
   dir_conf_t *conf = config;
 
-  if (arg)
-    conf->bulk_updates = CONF_FLAG_ON;
+  if (apr_strnatcasecmp("on", arg1) == 0)
+    {
+      conf->bulk_updates = CONF_BULKUPD_ON;
+    }
+  else if (apr_strnatcasecmp("off", arg1) == 0)
+    {
+      conf->bulk_updates = CONF_BULKUPD_OFF;
+    }
+  else if (apr_strnatcasecmp("prefer", arg1) == 0)
+    {
+      conf->bulk_updates = CONF_BULKUPD_PREFER;
+    }
   else
-    conf->bulk_updates = CONF_FLAG_OFF;
+    {
+      return "Unrecognized value for SVNAllowBulkUpdates directive";
+    }
 
   return NULL;
 }
@@ -662,7 +674,7 @@ dav_svn_get_repos_path(request_rec *r,
 
   /* Construct the full path from the parent path base directory
      and the repository name. */
-  *repos_path = svn_urlpath__join(fs_parent_path, repos_name, r->pool);
+  *repos_path = svn_dirent_join(fs_parent_path, repos_name, r->pool);
   return NULL;
 }
 
@@ -793,13 +805,13 @@ dav_svn__get_autoversioning_flag(request
 }
 
 
-svn_boolean_t
+dav_svn__bulk_upd_conf
 dav_svn__get_bulk_updates_flag(request_rec *r)
 {
   dir_conf_t *conf;
 
   conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
-  return conf->bulk_updates == CONF_FLAG_ON;
+  return conf->bulk_updates;
 }
 
 
@@ -1144,11 +1156,12 @@ static const command_rec cmds[] =
                 "activities database(s) should be stored"),
 
   /* per directory/location */
-  AP_INIT_FLAG("SVNAllowBulkUpdates", SVNAllowBulkUpdates_cmd, NULL,
-               ACCESS_CONF|RSRC_CONF,
-               "enables support for bulk update-style requests (as opposed to "
-               "only skeletal reports that require additional per-file "
-               "downloads."),
+  AP_INIT_TAKE1("SVNAllowBulkUpdates", SVNAllowBulkUpdates_cmd, NULL,
+                ACCESS_CONF|RSRC_CONF,
+                "enables support for bulk update-style requests (On, default), "
+                "as opposed to only skeletal reports that require additional "
+                "per-file downloads (Off). Use Prefer to tell the svn client "
+                "to always use bulk update requests, if supported."),
 
   /* per directory/location */
   AP_INIT_FLAG("SVNAdvertiseV2Protocol", SVNAdvertiseV2Protocol_cmd, NULL,

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/inherited-props.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/inherited-props.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/inherited-props.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/inherited-props.c Sun Jan  6 02:33:34 2013
@@ -113,7 +113,7 @@ dav_svn__get_inherited_props_report(cons
                                 "couldn't retrieve revision root",
                                 resource->pool);
 
-  serr = svn_repos_fs_get_inherited_props(&inherited_props, root, path,
+  serr = svn_repos_fs_get_inherited_props(&inherited_props, root, path, NULL,
                                           dav_svn__authz_read_func(&arb),
                                           &arb, resource->pool, iterpool);
   if (serr)

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/update.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/reports/update.c Sun Jan  6 02:33:34 2013
@@ -1016,11 +1016,15 @@ dav_svn__update_report(const dav_resourc
                                     SVN_DAV_ERROR_TAG);
     }
 
-  /* If server configuration permits bulk updates (a report with props
-     and textdeltas inline, rather than placeholder tags that tell the
-     client to do further fetches), look to see if client requested as
-     much.  */
-  if (repos->bulk_updates)
+  /* SVNAllowBulkUpdates On/Prefer: server configuration permits bulk updates
+     (a report with props and textdeltas inline, rather than placeholder tags
+     that tell the client to do further fetches), look to see if client
+     requested as much.
+      
+     SVNAllowBulkUpdates Off: no bulk updates allowed, force skelta mode.
+   */
+  if (repos->bulk_updates == CONF_BULKUPD_ON ||
+      repos->bulk_updates == CONF_BULKUPD_PREFER)
     {
       apr_xml_attr *this_attr;
 

Modified: subversion/branches/tree-read-api/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/mod_dav_svn/version.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/tree-read-api/subversion/mod_dav_svn/version.c Sun Jan  6 02:33:34 2013
@@ -247,7 +247,8 @@ get_option(const dav_resource *resource,
     {
       int i;
       svn_version_t *master_version = dav_svn__get_master_version(r);
-
+      dav_svn__bulk_upd_conf bulk_upd_conf = dav_svn__get_bulk_updates_flag(r);
+      
       /* The list of Subversion's custom POSTs and which versions of
          Subversion support them.  We need this latter information
          when acting as a WebDAV slave -- we don't want to claim
@@ -286,6 +287,9 @@ get_option(const dav_resource *resource,
       apr_table_set(r->headers_out, SVN_DAV_VTXN_STUB_HEADER,
                     apr_pstrcat(resource->pool, repos_root_uri, "/",
                                 dav_svn__get_vtxn_stub(r), (char *)NULL));
+      apr_table_set(r->headers_out, SVN_DAV_ALLOW_BULK_UPDATES,
+                    bulk_upd_conf == CONF_BULKUPD_ON ? "On" :
+                      bulk_upd_conf == CONF_BULKUPD_OFF ? "Off" : "Prefer");
 
       /* Report the supported POST types. */
       for (i = 0; i < sizeof(posts_versions)/sizeof(posts_versions[0]); ++i)

Modified: subversion/branches/tree-read-api/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/cl.h?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/cl.h (original)
+++ subversion/branches/tree-read-api/subversion/svn/cl.h Sun Jan  6 02:33:34 2013
@@ -288,13 +288,13 @@ svn_opt_subcommand_t
   svn_cl__upgrade;
 
 
-/* See definition in main.c for documentation. */
+/* See definition in svn.c for documentation. */
 extern const svn_opt_subcommand_desc2_t svn_cl__cmd_table[];
 
-/* See definition in main.c for documentation. */
+/* See definition in svn.c for documentation. */
 extern const int svn_cl__global_options[];
 
-/* See definition in main.c for documentation. */
+/* See definition in svn.c for documentation. */
 extern const apr_getopt_option_t svn_cl__options[];
 
 
@@ -462,33 +462,6 @@ svn_cl__print_status_xml(const char *cwd
                          svn_client_ctx_t *ctx,
                          apr_pool_t *pool);
 
-
-/* Print to stdout a hash that maps property names (char *) to property
-   values (svn_string_t *).  The names are assumed to be in UTF-8 format;
-   the values are either in UTF-8 (the special Subversion props) or
-   plain binary values.
-
-   If OUT is not NULL, then write to it rather than stdout.
-
-   If NAMES_ONLY is true, print just names, else print names and
-   values. */
-svn_error_t *
-svn_cl__print_prop_hash(svn_stream_t *out,
-                        apr_hash_t *prop_hash,
-                        svn_boolean_t names_only,
-                        apr_pool_t *pool);
-
-/* Similar to svn_cl__print_prop_hash(), only output xml to *OUTSTR.
-   If INHERITED_PROPS is true, then PROP_HASH contains inherited properties,
-   otherwise PROP_HASH contains explicit properties.  If *OUTSTR is NULL,
-   allocate it first from POOL, otherwise append to it. */
-svn_error_t *
-svn_cl__print_xml_prop_hash(svn_stringbuf_t **outstr,
-                            apr_hash_t *prop_hash,
-                            svn_boolean_t names_only,
-                            svn_boolean_t inherited_props,
-                            apr_pool_t *pool);
-
 /* Output a commit xml element to *OUTSTR.  If *OUTSTR is NULL, allocate it
    first from POOL, otherwise append to it.  If AUTHOR or DATE is
    NULL, it will be omitted. */
@@ -520,60 +493,6 @@ svn_cl__revprop_prepare(const svn_opt_re
                         svn_client_ctx_t *ctx,
                         apr_pool_t *pool);
 
-/* Search for a text editor command in standard environment variables,
-   and invoke it to edit CONTENTS (using a temporary file created in
-   directory BASE_DIR).  Return the new contents in *EDITED_CONTENTS,
-   or set *EDITED_CONTENTS to NULL if no edit was performed.
-
-   If EDITOR_CMD is not NULL, it is the name of the external editor
-   command to use, overriding anything else that might determine the
-   editor.
-
-   If TMPFILE_LEFT is NULL, the temporary file will be destroyed.
-   Else, the file will be left on disk, and its path returned in
-   *TMPFILE_LEFT.
-
-   CONFIG is a hash of svn_config_t * items keyed on a configuration
-   category (SVN_CONFIG_CATEGORY_CONFIG et al), and may be NULL.
-
-   If AS_TEXT is TRUE, recode CONTENTS and convert to native eol-style before
-   editing and back again afterwards.  In this case, ENCODING determines the
-   encoding used during editing.  If non-NULL, use the named encoding, else
-   use the system encoding.  If AS_TEXT is FALSE, don't do any translation.
-   In that case, ENCODING is ignored.
-
-   Use POOL for all allocations.  Use PREFIX as the prefix for the
-   temporary file used by the editor.
-
-   If return error, *EDITED_CONTENTS is not touched. */
-svn_error_t *
-svn_cl__edit_string_externally(svn_string_t **edited_contents,
-                               const char **tmpfile_left,
-                               const char *editor_cmd,
-                               const char *base_dir,
-                               const svn_string_t *contents,
-                               const char *prefix,
-                               apr_hash_t *config,
-                               svn_boolean_t as_text,
-                               const char *encoding,
-                               apr_pool_t *pool);
-
-
-/* Search for a text editor command in standard environment variables,
-   and invoke it to edit PATH.  Use POOL for all allocations.
-
-   If EDITOR_CMD is not NULL, it is the name of the external editor
-   command to use, overriding anything else that might determine the
-   editor.
-
-   CONFIG is a hash of svn_config_t * items keyed on a configuration
-   category (SVN_CONFIG_CATEGORY_CONFIG et al), and may be NULL.  */
-svn_error_t *
-svn_cl__edit_file_externally(const char *path,
-                             const char *editor_cmd,
-                             apr_hash_t *config,
-                             apr_pool_t *pool);
-
 /* Search for a merge tool command in environment variables,
    and use it to perform the merge of the four given files.
    WC_PATH is the path of the file that is in conflict, relative
@@ -820,15 +739,6 @@ svn_cl__args_to_target_array_print_reser
                                             svn_boolean_t keep_dest_origpath_on_truepath_collision,
                                             apr_pool_t *pool);
 
-/* Return a string allocated in POOL that is a copy of STR but with each
- * line prefixed with INDENT. A line is all characters up to the first
- * CR-LF, LF-CR, CR or LF, or the end of STR if sooner. */
-const char *
-svn_cl__indent_string(const char *str,
-                      const char *indent,
-                      apr_pool_t *pool);
-
-
 /* Return a string showing NODE's kind, URL and revision, to the extent that
  * that information is available in NODE. If NODE itself is NULL, this prints
  * just a 'none' node kind.

Modified: subversion/branches/tree-read-api/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/conflict-callbacks.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/conflict-callbacks.c Sun Jan  6 02:33:34 2013
@@ -38,6 +38,8 @@
 #include "cl.h"
 #include "tree-conflicts.h"
 
+#include "private/svn_cmdline_private.h"
+
 #include "svn_private_config.h"
 
 
@@ -203,8 +205,8 @@ open_editor(svn_boolean_t *performed_edi
 
   if (desc->merged_file)
     {
-      err = svn_cl__edit_file_externally(desc->merged_file, b->editor_cmd,
-                                         b->config, pool);
+      err = svn_cmdline__edit_file_externally(desc->merged_file, b->editor_cmd,
+                                              b->config, pool);
       if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
         {
           svn_error_t *root_err = svn_error_root_cause(err);
@@ -281,6 +283,160 @@ launch_resolver(svn_boolean_t *performed
   return SVN_NO_ERROR;
 }
 
+
+/* Maximum line length for the prompt string. */
+#define MAX_PROMPT_WIDTH 70
+
+/* Description of a resolver option */
+typedef struct resolver_option_t
+{
+  const char *code;        /* one or two characters */
+  const char *short_desc;  /* short description */
+  const char *long_desc;   /* longer description */
+} resolver_option_t;
+
+/* Resolver options for a text conflict */
+static const resolver_option_t text_conflict_options[] =
+{
+  { "e",  "edit",             N_("change merged file in an editor") },
+  { "df", "diff-full",        N_("show all changes made to merged file") },
+  { "r",  "resolved",         N_("accept merged version of file") },
+  { "" },
+  { "dc", "display-conflict", N_("show all conflicts (ignoring merged version)") },
+  { "mc", "mine-conflict",    N_("accept my version for all conflicts (same)") },
+  { "tc", "theirs-conflict",  N_("accept their version for all conflicts (same)") },
+  { "" },
+  { "mf", "mine-full",        N_("accept my version of entire file (even "
+                                 "non-conflicts)") },
+  { "tf", "theirs-full",      N_("accept their version of entire file (same)") },
+  { "" },
+  { "p",  "postpone",         N_("mark the conflict to be resolved later") },
+  { "m",  "merge",            N_("use internal merge tool to resolve conflict") },
+  { "l",  "launch",           N_("launch external tool to resolve conflict") },
+  { "s",  "show all options", N_("show this list") },
+  { NULL }
+};
+
+/* Resolver options for a property conflict */
+static const resolver_option_t prop_conflict_options[] =
+{
+  { "p",  "postpone",         N_("mark the conflict to be resolved later") },
+  { "mf", "mine-full",        N_("accept my version of entire file (even "
+                                "non-conflicts)") },
+  { "tf", "theirs-full",      N_("accept their version of entire file (same)") },
+  { NULL }
+};
+
+/* Resolver options for an obstructued addition */
+static const resolver_option_t obstructed_add_options[] =
+{
+  { "p",  "postpone",         N_("resolve the conflict later") },
+  { "mf", "mine-full",        N_("accept pre-existing item (ignore upstream addition)") },
+  { "tf", "theirs-full",      N_("accept incoming item (overwrite pre-existing item)") },
+  { "h",  "help",             N_("show this help") },
+  { NULL }
+};
+
+/* Resolver options for a tree conflict */
+static const resolver_option_t tree_conflict_options[] =
+{
+  { "p",  "postpone",         N_("resolve the conflict later") },
+  { "r",  "resolved",         N_("accept current working copy state") },
+  { "mc", "mine-conflict",    N_("prefer local change") },
+  { "tc", "theirs-conflict",  N_("prefer incoming change") },
+  { "h",  "show help",        N_("show this help") },
+  { NULL }
+};
+
+/* Return a pointer to the option description in OPTIONS matching the
+ * one- or two-character OPTION_CODE.  Return NULL if not found. */
+static const resolver_option_t *
+find_option(const resolver_option_t *options,
+            const char *option_code)
+{
+  const resolver_option_t *opt;
+
+  for (opt = options; opt->code; opt++)
+    {
+      if (strcmp(opt->code, option_code) == 0)
+        return opt;
+    }
+  return NULL;
+}
+
+/* Return a prompt string listing the options OPTIONS. If OPTION_CODES is
+ * non-null, select only the options whose codes are mentioned in it. */
+static const char *
+prompt_string(const resolver_option_t *options,
+              const char *const *option_codes,
+              apr_pool_t *pool)
+{
+  const char *result = "Select:";
+  int this_line_len = strlen(result);
+  svn_boolean_t first = TRUE;
+
+  while (1)
+    {
+      const resolver_option_t *opt;
+      const char *s;
+
+      if (option_codes)
+        {
+          if (! *option_codes)
+            break;
+          opt = find_option(options, *option_codes++);
+        }
+      else
+        {
+          opt = options++;
+          if (! opt->code)
+            break;
+        }
+
+      if (! first)
+        result = apr_pstrcat(pool, result, ",", (char *)NULL);
+      /* Break the line if adding the next option would make it too long */
+      if ((this_line_len + strlen(opt->short_desc) + 6) > MAX_PROMPT_WIDTH)
+        {
+          result = apr_pstrcat(pool, result, "\n       ", (char *)NULL);
+          this_line_len = 7;
+        }
+      s = apr_psprintf(pool, " (%s) %s",
+                       opt->code, opt->short_desc);
+      result = apr_pstrcat(pool, result, s, (char *)NULL);
+      this_line_len += strlen(s);
+      first = FALSE;
+    }
+  return apr_pstrcat(pool, result, ": ", (char *)NULL);
+}
+
+/* Return a help string listing the OPTIONS. */
+static const char *
+help_string(const resolver_option_t *options,
+            apr_pool_t *pool)
+{
+  const char *result = "";
+  const resolver_option_t *opt;
+
+  for (opt = options; opt->code; opt++)
+    {
+      /* Append a line describing OPT, or a blank line if its code is "". */
+      if (opt->code[0])
+        {
+          const char *s = apr_psprintf(pool, "  (%s)", opt->code);
+
+          result = apr_psprintf(pool, "%s%-6s %-16s - %s\n",
+                                result, s, opt->short_desc, opt->long_desc);
+        }
+      else
+        {
+          result = apr_pstrcat(pool, result, "\n", (char *)NULL);
+        }
+    }
+  return result;
+}
+
+
 /* Ask the user what to do about the text conflict described by DESC.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
@@ -291,8 +447,7 @@ handle_text_conflict(svn_wc_conflict_res
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
-  const char *answer;
-  char *prompt;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_boolean_t diff_allowed = FALSE;
   /* Have they done something that might have affected the merged
      file (so that we need to save a .edited copy)? */
@@ -319,73 +474,45 @@ handle_text_conflict(svn_wc_conflict_res
 
   while (TRUE)
     {
-      svn_pool_clear(scratch_pool);
+      const char *options[12];  /* size of array must be big enough */
+      const char **next_option = options;
+      const char *prompt;
+      const char *answer;
 
-      prompt = apr_pstrdup(scratch_pool, _("Select: (p) postpone"));
+      svn_pool_clear(iterpool);
 
+      *next_option++ = "p";
       if (diff_allowed)
         {
-          prompt = apr_pstrcat(scratch_pool, prompt,
-                               _(", (df) diff-full, (e) edit, (m) merge"),
-                               (char *)NULL);
+          *next_option++ = "df";
+          *next_option++ = "e";
+          *next_option++ = "m";
 
           if (knows_something)
-            prompt = apr_pstrcat(scratch_pool, prompt, _(", (r) resolved"),
-                                 (char *)NULL);
+            *next_option++ = "r";
 
           if (! desc->is_binary)
-            prompt = apr_pstrcat(scratch_pool, prompt,
-                                 _(",\n        (mc) mine-conflict, "
-                                   "(tc) theirs-conflict"),
-                                 (char *)NULL);
+            *next_option++ = "mc";
+            *next_option++ = "tc";
         }
       else
         {
           if (knows_something)
-            prompt = apr_pstrcat(scratch_pool, prompt, _(", (r) resolved"),
-                                 (char *)NULL);
-          prompt = apr_pstrcat(scratch_pool, prompt,
-                               _(",\n        "
-                                 "(mf) mine-full, (tf) theirs-full"),
-                               (char *)NULL);
-        }
-
-      prompt = apr_pstrcat(scratch_pool, prompt, ",\n        ", (char *)NULL);
-      prompt = apr_pstrcat(scratch_pool, prompt,
-                           _("(s) show all options: "),
-                           (char *)NULL);
+            *next_option++ = "r";
+          *next_option++ = "mf";
+          *next_option++ = "tf";
+        }
+      *next_option++ = "s";
+      *next_option++ = NULL;
+      prompt = prompt_string(text_conflict_options, options, iterpool);
 
-      SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, scratch_pool));
+      SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
 
       if (strcmp(answer, "s") == 0)
         {
-          /* These are used in svn_cl__accept_from_word(). */
-          SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
-          _("\n"
-            "  (e)  edit             - change merged file in an editor\n"
-            "  (df) diff-full        - show all changes made to merged "
-                                      "file\n"
-            "  (r)  resolved         - accept merged version of file\n"
-            "\n"
-            "  (dc) display-conflict - show all conflicts "
-                                      "(ignoring merged version)\n"
-            "  (mc) mine-conflict    - accept my version for all "
-                                      "conflicts (same)\n"
-            "  (tc) theirs-conflict  - accept their version for all "
-                                      "conflicts (same)\n"
-            "\n"
-            "  (mf) mine-full        - accept my version of entire file "
-                                      "(even non-conflicts)\n"
-            "  (tf) theirs-full      - accept their version of entire "
-                                      "file (same)\n"
-            "\n"
-            "  (p)  postpone         - mark the conflict to be "
-                                      "resolved later\n"
-            "  (m)  merge            - use internal merge tool to "
-                                      "resolve conflict\n"
-            "  (l)  launch           - launch external tool to "
-                                      "resolve conflict\n"
-            "  (s)  show all         - show this list\n\n")));
+          SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n",
+                                      help_string(text_conflict_options,
+                                                  iterpool)));
         }
       else if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
         {
@@ -397,7 +524,7 @@ handle_text_conflict(svn_wc_conflict_res
         {
           if (desc->is_binary)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                           _("Invalid option; cannot choose "
                                             "based on conflicts in a "
                                             "binary file.\n\n")));
@@ -412,7 +539,7 @@ handle_text_conflict(svn_wc_conflict_res
         {
           if (desc->is_binary)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                           _("Invalid option; cannot choose "
                                             "based on conflicts in a "
                                             "binary file.\n\n")));
@@ -441,7 +568,7 @@ handle_text_conflict(svn_wc_conflict_res
         {
           if (desc->is_binary)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                           _("Invalid option; cannot "
                                             "display conflicts for a "
                                             "binary file.\n\n")));
@@ -450,30 +577,30 @@ handle_text_conflict(svn_wc_conflict_res
           else if (! (desc->my_abspath && desc->base_abspath &&
                       desc->their_abspath))
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                           _("Invalid option; original "
                                             "files not available.\n\n")));
               continue;
             }
-          SVN_ERR(show_conflicts(desc, scratch_pool));
+          SVN_ERR(show_conflicts(desc, iterpool));
           knows_something = TRUE;
         }
       else if (strcmp(answer, "df") == 0)
         {
           if (! diff_allowed)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                              _("Invalid option; there's no "
                                 "merged version to diff.\n\n")));
               continue;
             }
 
-          SVN_ERR(show_diff(desc, scratch_pool));
+          SVN_ERR(show_diff(desc, iterpool));
           knows_something = TRUE;
         }
       else if (strcmp(answer, "e") == 0 || strcmp(answer, ":-E") == 0)
         {
-          SVN_ERR(open_editor(&performed_edit, desc, b, scratch_pool));
+          SVN_ERR(open_editor(&performed_edit, desc, b, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
@@ -482,7 +609,7 @@ handle_text_conflict(svn_wc_conflict_res
         {
           if (desc->kind != svn_wc_conflict_kind_text)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                           _("Invalid option; can only "
                                             "resolve text conflicts with "
                                             "the internal merge tool."
@@ -504,11 +631,11 @@ handle_text_conflict(svn_wc_conflict_res
                                          b->editor_cmd,
                                          b->config,
                                          &remains_in_conflict,
-                                         scratch_pool));
+                                         iterpool));
               knows_something = !remains_in_conflict;
             }
           else
-            SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+            SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                         _("Invalid option.\n\n")));
         }
       else if (strcmp(answer, "l") == 0 || strcmp(answer, ":-l") == 0)
@@ -516,12 +643,12 @@ handle_text_conflict(svn_wc_conflict_res
           if (desc->base_abspath && desc->their_abspath &&
               desc->my_abspath && desc->merged_file)
             {
-              SVN_ERR(launch_resolver(&performed_edit, desc, b, scratch_pool));
+              SVN_ERR(launch_resolver(&performed_edit, desc, b, iterpool));
               if (performed_edit)
                 knows_something = TRUE;
             }
           else
-            SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+            SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                         _("Invalid option.\n\n")));
         }
       else if (strcmp(answer, "r") == 0)
@@ -535,10 +662,11 @@ handle_text_conflict(svn_wc_conflict_res
               break;
             }
           else
-            SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+            SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                         _("Invalid option.\n\n")));
         }
     }
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -553,9 +681,8 @@ handle_prop_conflict(svn_wc_conflict_res
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
-  const char *answer;
-  const char *prompt;
-  svn_stringbuf_t *prop_reject;
+  const char *prompt
+    = prompt_string(prop_conflict_options, NULL, scratch_pool);
   apr_pool_t *iterpool;
 
   SVN_ERR_ASSERT(desc->kind == svn_wc_conflict_kind_property);
@@ -575,6 +702,8 @@ handle_prop_conflict(svn_wc_conflict_res
    * ### This needs to be fixed so we can present better options here. */
   if (desc->their_abspath)
     {
+      svn_stringbuf_t *prop_reject;
+
       /* ### The library dumps an svn_string_t into a temp file, and
        * ### we read it back from the file into an svn_stringbuf_t here.
        * ### That's rather silly. We should be passed svn_string_t's
@@ -596,9 +725,9 @@ handle_prop_conflict(svn_wc_conflict_res
   iterpool = svn_pool_create(scratch_pool);
   while (TRUE)
     {
-      svn_pool_clear(iterpool);
+      const char *answer;
 
-      prompt = _("Select: (p) postpone, (mf) mine-full, (tf) theirs-full: ");
+      svn_pool_clear(iterpool);
 
       SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
 
@@ -677,9 +806,9 @@ svn_cl__conflict_func_interactive(svn_wc
               return SVN_NO_ERROR;
             }
 
-          err = svn_cl__edit_file_externally(desc->merged_file,
-                                             b->editor_cmd, b->config,
-                                             scratch_pool);
+          err = svn_cmdline__edit_file_externally(desc->merged_file,
+                                                  b->editor_cmd, b->config,
+                                                  scratch_pool);
           if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
             {
               SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
@@ -794,7 +923,8 @@ svn_cl__conflict_func_interactive(svn_wc
            && (desc->reason == svn_wc_conflict_reason_obstructed))
     {
       const char *answer;
-      const char *prompt;
+      const char *prompt
+        = prompt_string(obstructed_add_options, NULL, scratch_pool);
 
       SVN_ERR(svn_cmdline_fprintf(
                    stderr, subpool,
@@ -803,8 +933,6 @@ svn_cl__conflict_func_interactive(svn_wc
                    svn_cl__local_style_skip_ancestor(b->path_prefix,
                                                      desc->local_abspath,
                                                      subpool)));
-      prompt = _("Select: (p) postpone, (mf) mine-full, "
-                 "(tf) theirs-full, (h) help: ");
 
       while (1)
         {
@@ -814,13 +942,9 @@ svn_cl__conflict_func_interactive(svn_wc
 
           if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
-              _("  (p)  postpone    - resolve the conflict later\n"
-                "  (mf) mine-full   - accept pre-existing item "
-                "(ignore upstream addition)\n"
-                "  (tf) theirs-full - accept incoming item "
-                "(overwrite pre-existing item)\n"
-                "  (h)  help        - show this help\n\n")));
+              SVN_ERR(svn_cmdline_fprintf(stderr, subpool, "%s\n",
+                                          help_string(obstructed_add_options,
+                                                      subpool)));
             }
           if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
             {
@@ -843,7 +967,8 @@ svn_cl__conflict_func_interactive(svn_wc
   else if (desc->kind == svn_wc_conflict_kind_tree)
     {
       const char *answer;
-      const char *prompt;
+      const char *prompt
+        = prompt_string(tree_conflict_options, NULL, scratch_pool);
       const char *readable_desc;
 
       SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
@@ -856,10 +981,6 @@ svn_cl__conflict_func_interactive(svn_wc
                                                      scratch_pool),
                    readable_desc));
 
-      prompt = _("Select: (p) postpone, (r) mark-resolved, "
-                 "(mc) mine-conflict,\n"
-                 "        (tc) theirs-conflict, (h) help: ");
-
       while (1)
         {
           svn_pool_clear(subpool);
@@ -868,11 +989,9 @@ svn_cl__conflict_func_interactive(svn_wc
 
           if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
-              _("  (p) postpone         - resolve the conflict later\n"
-                "  (r) resolved         - accept current working copy state\n"
-                "  (mc) mine-conflict   - prefer local change\n"
-                "  (tc) theirs-conflict - prefer incoming change\n")));
+              SVN_ERR(svn_cmdline_fprintf(stderr, subpool, "%s",
+                                          help_string(tree_conflict_options,
+                                                      subpool)));
             }
           if (strcmp(answer, "p") == 0 || strcmp(answer, ":-p") == 0)
             {

Modified: subversion/branches/tree-read-api/subversion/svn/copy-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/copy-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/copy-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/copy-cmd.c Sun Jan  6 02:33:34 2013
@@ -68,7 +68,42 @@ svn_cl__copy(apr_getopt_t *os,
       svn_opt_revision_t *peg_revision = apr_palloc(pool,
                                                     sizeof(*peg_revision));
 
-      SVN_ERR(svn_opt_parse_path(peg_revision, &src, target, pool));
+      err = svn_opt_parse_path(peg_revision, &src, target, pool);
+
+      if (err)
+        {
+          /* Issue #3606: 'svn cp .@HEAD target' gives
+             svn: '@HEAD' is just a peg revision. Maybe try '@HEAD@' instead? 
+
+             This is caused by a first round of canonicalization in
+             svn_cl__args_to_target_array_print_reserved(). Undo that in an
+             attempt to fix this issue without revving many apis.
+           */
+          if (*target == '@' && err->apr_err == SVN_ERR_BAD_FILENAME)
+            {
+              svn_error_t *err2;
+
+              err2 = svn_opt_parse_path(peg_revision, &src,
+                                        apr_pstrcat(pool, ".", target,
+                                                    (const char *)NULL), pool);
+
+              if (err2)
+                {
+                  /* Fix attempt failed; return original error */
+                  svn_error_clear(err2);
+                }
+              else
+                {
+                  /* Error resolved. Use path */
+                  svn_error_clear(err);
+                  err = NULL;
+                }
+            }
+
+          if (err)
+              return svn_error_trace(err);
+        }
+
       source->path = src;
       source->revision = &(opt_state->start_revision);
       source->peg_revision = peg_revision;

Modified: subversion/branches/tree-read-api/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/diff-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/diff-cmd.c Sun Jan  6 02:33:34 2013
@@ -77,6 +77,12 @@ kind_to_word(svn_client_diff_summarize_k
     }
 }
 
+/* Baton for summarize_xml and summarize_regular */
+struct summarize_baton_t
+{
+  const char *anchor;
+};
+
 /* Print summary information about a given change as XML, implements the
  * svn_client_diff_summarize_func_t interface. The @a baton is a 'char *'
  * representing the either the path to the working copy root or the url
@@ -86,9 +92,10 @@ summarize_xml(const svn_client_diff_summ
               void *baton,
               apr_pool_t *pool)
 {
+  struct summarize_baton_t *b = baton;
   /* Full path to the object being diffed.  This is created by taking the
    * baton, and appending the target's relative path. */
-  const char *path = *(const char **)baton;
+  const char *path = b->anchor;
   svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool);
 
   /* Tack on the target path, so we can differentiate between different parts
@@ -125,7 +132,8 @@ summarize_regular(const svn_client_diff_
                   void *baton,
                   apr_pool_t *pool)
 {
-  const char *path = *(const char **)baton;
+  struct summarize_baton_t *b = baton;
+  const char *path = b->anchor;
 
   /* Tack on the target path, so we can differentiate between different parts
    * of the output when we're given multiple targets. */
@@ -176,6 +184,7 @@ svn_cl__diff(apr_getopt_t *os,
   svn_boolean_t ignore_properties =
     opt_state->diff.patch_compatible || opt_state->diff.ignore_properties;
   int i;
+  struct summarize_baton_t summarize_baton;
   const svn_client_diff_summarize_func_t summarize_func =
     (opt_state->xml ? summarize_xml : summarize_regular);
 
@@ -266,6 +275,17 @@ svn_cl__diff(apr_getopt_t *os,
       if (new_rev.kind != svn_opt_revision_unspecified)
         opt_state->end_revision = new_rev;
 
+      if (opt_state->new_target
+          && opt_state->start_revision.kind == svn_opt_revision_unspecified
+          && opt_state->end_revision.kind == svn_opt_revision_unspecified
+          && ! svn_path_is_url(old_target)
+          && ! svn_path_is_url(new_target))
+        {
+          /* We want the arbitrary_nodes_diff instead of just working nodes */
+          opt_state->start_revision.kind = svn_opt_revision_working;
+          opt_state->end_revision.kind = svn_opt_revision_working;
+        }
+
       if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
         opt_state->start_revision.kind = svn_path_is_url(old_target)
           ? svn_opt_revision_head : svn_opt_revision_base;
@@ -350,16 +370,20 @@ svn_cl__diff(apr_getopt_t *os,
             target2 = svn_dirent_join(new_target, path, iterpool);
 
           if (opt_state->diff.summarize)
-            SVN_ERR(svn_client_diff_summarize2
-                    (target1,
-                     &opt_state->start_revision,
-                     target2,
-                     &opt_state->end_revision,
-                     opt_state->depth,
-                     ! opt_state->diff.notice_ancestry,
-                     opt_state->changelists,
-                     summarize_func, &target1,
-                     ctx, iterpool));
+            {
+              summarize_baton.anchor = target1;
+
+              SVN_ERR(svn_client_diff_summarize2(
+                                target1,
+                                &opt_state->start_revision,
+                                target2,
+                                &opt_state->end_revision,
+                                opt_state->depth,
+                                ! opt_state->diff.notice_ancestry,
+                                opt_state->changelists,
+                                summarize_func, &summarize_baton,
+                                ctx, iterpool));
+            }
           else
             SVN_ERR(svn_client_diff6(
                      options,
@@ -397,16 +421,19 @@ svn_cl__diff(apr_getopt_t *os,
               ? svn_opt_revision_head : svn_opt_revision_working;
 
           if (opt_state->diff.summarize)
-            SVN_ERR(svn_client_diff_summarize_peg2
-                    (truepath,
-                     &peg_revision,
-                     &opt_state->start_revision,
-                     &opt_state->end_revision,
-                     opt_state->depth,
-                     ! opt_state->diff.notice_ancestry,
-                     opt_state->changelists,
-                     summarize_func, &truepath,
-                     ctx, iterpool));
+            {
+              summarize_baton.anchor = truepath;
+              SVN_ERR(svn_client_diff_summarize_peg2(
+                                truepath,
+                                &peg_revision,
+                                &opt_state->start_revision,
+                                &opt_state->end_revision,
+                                opt_state->depth,
+                                ! opt_state->diff.notice_ancestry,
+                                opt_state->changelists,
+                                summarize_func, &summarize_baton,
+                                ctx, iterpool));
+            }
           else
             SVN_ERR(svn_client_diff_peg6(
                      options,

Modified: subversion/branches/tree-read-api/subversion/svn/file-merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/file-merge.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/file-merge.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/file-merge.c Sun Jan  6 02:33:34 2013
@@ -37,6 +37,7 @@
 
 #include "svn_private_config.h"
 #include "private/svn_utf_private.h"
+#include "private/svn_cmdline_private.h"
 #include "private/svn_dep_compat.h"
 
 #if APR_HAVE_SYS_IOCTL_H
@@ -491,8 +492,8 @@ edit_chunk(apr_array_header_t **merged_c
     }
   SVN_ERR(svn_io_file_flush_to_disk(temp_file, scratch_pool));
 
-  err = svn_cl__edit_file_externally(temp_file_name, editor_cmd,
-                                     config, scratch_pool);
+  err = svn_cmdline__edit_file_externally(temp_file_name, editor_cmd,
+                                          config, scratch_pool);
   if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
     {
       svn_error_t *root_err = svn_error_root_cause(err);
@@ -861,13 +862,13 @@ svn_cl__merge_file(const char *base_path
                                    scratch_pool)));
 
   SVN_ERR(svn_io_file_open(&original_file, base_path,
-                           APR_READ|APR_BUFFERED|APR_BINARY,
+                           APR_READ | APR_BUFFERED,
                            APR_OS_DEFAULT, scratch_pool));
   SVN_ERR(svn_io_file_open(&modified_file, their_path,
-                           APR_READ|APR_BUFFERED|APR_BINARY,
+                           APR_READ | APR_BUFFERED,
                            APR_OS_DEFAULT, scratch_pool));
   SVN_ERR(svn_io_file_open(&latest_file, my_path,
-                           APR_READ|APR_BUFFERED|APR_BINARY,
+                           APR_READ | APR_BUFFERED,
                            APR_OS_DEFAULT, scratch_pool));
   SVN_ERR(svn_io_open_unique_file3(&merged_file, &merged_file_name,
                                    NULL, svn_io_file_del_none,

Modified: subversion/branches/tree-read-api/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/help-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/help-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/help-cmd.c Sun Jan  6 02:33:34 2013
@@ -28,6 +28,7 @@
 /*** Includes. ***/
 
 #include "svn_string.h"
+#include "svn_config.h"
 #include "svn_error.h"
 #include "svn_version.h"
 #include "cl.h"
@@ -43,7 +44,8 @@ svn_cl__help(apr_getopt_t *os,
              void *baton,
              apr_pool_t *pool)
 {
-  svn_cl__opt_state_t *opt_state;
+  svn_cl__opt_state_t *opt_state = NULL;
+  svn_stringbuf_t *version_footer = NULL;
 
   /* xgettext: the %s is for SVN_VER_NUMBER. */
   char help_header_template[] =
@@ -69,14 +71,72 @@ svn_cl__help(apr_getopt_t *os,
   const char *ra_desc_start
     = _("The following repository access (RA) modules are available:\n\n");
 
-  svn_stringbuf_t *version_footer;
-
   if (baton)
-    opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
-  else
-    opt_state = NULL;
+    {
+      svn_cl__cmd_baton_t *const cmd_baton = baton;
+#ifndef SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE
+      /* Windows never actually stores plaintext passwords, it
+         encrypts the contents using CryptoAPI. ...
+
+         ... If CryptoAPI is available ... but it should be on all
+         versions of Windows that are even remotely interesting two
+         days before the scheduled end of the world, when this comment
+         is being written. */
+#  ifndef WIN32
+      svn_boolean_t store_auth_creds =
+        SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
+      svn_boolean_t store_passwords =
+        SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
+      svn_boolean_t store_plaintext_passwords = FALSE;
+      svn_config_t *cfg;
+
+      if (cmd_baton->ctx->config)
+        {
+          cfg = apr_hash_get(cmd_baton->ctx->config,
+                             SVN_CONFIG_CATEGORY_CONFIG,
+                             APR_HASH_KEY_STRING);
+          if (cfg)
+            {
+              SVN_ERR(svn_config_get_bool(cfg, &store_auth_creds,
+                                          SVN_CONFIG_SECTION_AUTH,
+                                          SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
+                                          store_auth_creds));
+              SVN_ERR(svn_config_get_bool(cfg, &store_passwords,
+                                          SVN_CONFIG_SECTION_AUTH,
+                                          SVN_CONFIG_OPTION_STORE_PASSWORDS,
+                                          store_passwords));
+            }
+          cfg = apr_hash_get(cmd_baton->ctx->config,
+                             SVN_CONFIG_CATEGORY_SERVERS,
+                             APR_HASH_KEY_STRING);
+          if (cfg)
+            {
+              const char *value;
+              SVN_ERR(svn_config_get_yes_no_ask
+                      (cfg, &value,
+                       SVN_CONFIG_SECTION_GLOBAL,
+                       SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
+                       SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));
+              if (0 == svn_cstring_casecmp(value, SVN_CONFIG_TRUE))
+                store_plaintext_passwords = TRUE;
+            }
+        }
+
+      if (store_plaintext_passwords && store_auth_creds && store_passwords)
+        {
+          version_footer = svn_stringbuf_create(
+              _("WARNING: Plaintext password storage is enabled!\n\n"),
+              pool);
+          svn_stringbuf_appendcstr(version_footer, ra_desc_start);
+        }
+#  endif /* !WIN32 */
+#endif /* !SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE */
+
+      opt_state = cmd_baton->opt_state;
+    }
 
-  version_footer = svn_stringbuf_create(ra_desc_start, pool);
+  if (!version_footer)
+    version_footer = svn_stringbuf_create(ra_desc_start, pool);
   SVN_ERR(svn_ra_print_modules(version_footer, pool));
 
   return svn_opt_print_help4(os,

Modified: subversion/branches/tree-read-api/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/log-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/log-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/log-cmd.c Sun Jan  6 02:33:34 2013
@@ -21,9 +21,6 @@
  * ====================================================================
  */
 
-#define APR_WANT_STRFUNC
-#define APR_WANT_STDIO
-#include <apr_want.h>
 #include <apr_fnmatch.h>
 
 #include "svn_client.h"
@@ -39,6 +36,8 @@
 #include "svn_props.h"
 #include "svn_pools.h"
 
+#include "private/svn_cmdline_private.h"
+
 #include "cl.h"
 
 #include "svn_private_config.h"
@@ -653,9 +652,9 @@ log_entry_receiver_xml(void *baton,
   if (log_entry->revprops && apr_hash_count(log_entry->revprops) > 0)
     {
       svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops", NULL);
-      SVN_ERR(svn_cl__print_xml_prop_hash(&sb, log_entry->revprops,
-                                          FALSE, /* name_only */
-                                          FALSE, pool));
+      SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, log_entry->revprops,
+                                               FALSE, /* name_only */
+                                               FALSE, pool));
       svn_xml_make_close_tag(&sb, pool, "revprops");
     }
 

Modified: subversion/branches/tree-read-api/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/merge-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/merge-cmd.c Sun Jan  6 02:33:34 2013
@@ -37,6 +37,10 @@
 
 #include "svn_private_config.h"
 
+/* A handy constant */
+static const svn_opt_revision_t unspecified_revision
+  = { svn_opt_revision_unspecified, { 0 } };
+
 
 /*** Code. ***/
 
@@ -47,6 +51,7 @@ merge_reintegrate(const char *source_pat
                   const svn_opt_revision_t *source_peg_revision,
                   const char *target_wcpath,
                   svn_boolean_t dry_run,
+                  svn_boolean_t verbose,
                   const apr_array_header_t *merge_options,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *scratch_pool)
@@ -54,6 +59,15 @@ merge_reintegrate(const char *source_pat
   const char *url1, *url2;
   svn_revnum_t rev1, rev2;
 
+  if (verbose)
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("checking branch relationship...\n")));
+  SVN_ERR_W(svn_cl__check_related_source_and_target(
+              source_path_or_url, source_peg_revision,
+              target_wcpath, &unspecified_revision, ctx, scratch_pool),
+            _("Source and target must be different but related branches"));
+
+  if (verbose)
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("calculating reintegrate merge...\n")));
   SVN_ERR(svn_client_find_reintegrate_merge(
             &url1, &rev1, &url2, &rev2,
             source_path_or_url, source_peg_revision, target_wcpath,
@@ -70,6 +84,9 @@ merge_reintegrate(const char *source_pat
       revision2.kind = svn_opt_revision_number;
       revision2.value.number = rev2;
 
+      if (verbose)
+        SVN_ERR(svn_cmdline_printf(scratch_pool, _("merging...\n")));
+
       /* Do the merge.  Set 'allow_mixed_rev' to true, not because we want
        * to allow a mixed-rev WC but simply to bypass the check, as it was
        * already checked in svn_client_find_reintegrate_merge(). */
@@ -116,12 +133,23 @@ automatic_merge(const char *source_path_
                 svn_boolean_t allow_mixed_rev,
                 svn_boolean_t allow_local_mods,
                 svn_boolean_t allow_switched_subtrees,
+                svn_boolean_t verbose,
                 const apr_array_header_t *merge_options,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *scratch_pool)
 {
   svn_client_automatic_merge_t *merge;
 
+  if (verbose)
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("checking branch relationship...\n")));
+  SVN_ERR_W(svn_cl__check_related_source_and_target(
+              source_path_or_url, source_revision,
+              target_wcpath, &unspecified_revision, ctx, scratch_pool),
+            _("Source and target must be different but related branches"));
+
+  if (verbose)
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("calculating automatic merge...\n")));
+
   /* Find the 3-way merges needed (and check suitability of the WC). */
   SVN_ERR(svn_client_find_automatic_merge(&merge,
                                           source_path_or_url, source_revision,
@@ -156,6 +184,9 @@ automatic_merge(const char *source_path_
                                   "cannot be used with this kind of merge"));
     }
 
+  if (verbose)
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("merging...\n")));
+
   /* Perform the 3-way merges */
   SVN_ERR(svn_client_do_automatic_merge(merge, target_wcpath, depth,
                                         force, record_only,
@@ -181,7 +212,6 @@ svn_cl__merge(apr_getopt_t *os,
   svn_opt_revision_t first_range_start, first_range_end, peg_revision1,
     peg_revision2;
   apr_array_header_t *options, *ranges_to_merge = opt_state->revision_ranges;
-  svn_opt_revision_t unspecified = { svn_opt_revision_unspecified, { 0 } };
 
   /* Merge doesn't support specifying a revision or revision range
      when using --reintegrate. */
@@ -435,11 +465,6 @@ svn_cl__merge(apr_getopt_t *os,
       && first_range_start.kind == svn_opt_revision_unspecified
       && first_range_end.kind == svn_opt_revision_unspecified)
     {
-      SVN_ERR_W(svn_cl__check_related_source_and_target(
-                  sourcepath1, &peg_revision1, targetpath, &unspecified,
-                  ctx, pool),
-                _("Source and target must be different but related branches"));
-
       merge_err = automatic_merge(sourcepath1, &peg_revision1, targetpath,
                                   opt_state->depth,
                                   opt_state->force,
@@ -448,17 +473,14 @@ svn_cl__merge(apr_getopt_t *os,
                                   opt_state->allow_mixed_rev,
                                   TRUE /*allow_local_mods*/,
                                   TRUE /*allow_switched_subtrees*/,
+                                  opt_state->verbose,
                                   options, ctx, pool);
     }
   else if (opt_state->reintegrate)
     {
-      SVN_ERR_W(svn_cl__check_related_source_and_target(
-                  sourcepath1, &peg_revision1, targetpath, &unspecified,
-                  ctx, pool),
-                _("Source and target must be different but related branches"));
-
       merge_err = merge_reintegrate(sourcepath1, &peg_revision1, targetpath,
-                                    opt_state->dry_run, options, ctx, pool);
+                                    opt_state->dry_run, opt_state->verbose,
+                                    options, ctx, pool);
     }
   else if (! two_sources_specified)
     {
@@ -476,12 +498,16 @@ svn_cl__merge(apr_getopt_t *os,
           APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = range;
 
           /* This must be a 'sync' merge so check branch relationship. */
+          if (opt_state->verbose)
+            SVN_ERR(svn_cmdline_printf(pool, _("checking branch relationship...\n")));
           SVN_ERR_W(svn_cl__check_related_source_and_target(
-                      sourcepath1, &peg_revision1, targetpath, &unspecified,
-                      ctx, pool),
+                      sourcepath1, &peg_revision1,
+                      targetpath, &unspecified_revision, ctx, pool),
                 _("Source and target must be different but related branches"));
         }
 
+      if (opt_state->verbose)
+        SVN_ERR(svn_cmdline_printf(pool, _("merging...\n")));
       merge_err = svn_client_merge_peg4(sourcepath1,
                                         ranges_to_merge,
                                         &peg_revision1,
@@ -502,6 +528,9 @@ svn_cl__merge(apr_getopt_t *os,
         return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("Merge sources must both be "
                                   "either paths or URLs"));
+
+      if (opt_state->verbose)
+        SVN_ERR(svn_cmdline_printf(pool, _("merging...\n")));
       merge_err = svn_client_merge4(sourcepath1,
                                     &first_range_start,
                                     sourcepath2,

Modified: subversion/branches/tree-read-api/subversion/svn/propedit-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/propedit-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/propedit-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/propedit-cmd.c Sun Jan  6 02:33:34 2013
@@ -39,6 +39,7 @@
 #include "svn_props.h"
 #include "cl.h"
 
+#include "private/svn_cmdline_private.h"
 #include "svn_private_config.h"
 
 
@@ -137,8 +138,8 @@ svn_cl__propedit(apr_getopt_t *os,
       /* Run the editor on a temporary file which contains the
          original property value... */
       SVN_ERR(svn_io_temp_dir(&temp_dir, pool));
-      SVN_ERR(svn_cl__edit_string_externally
-              (&propval, NULL,
+      SVN_ERR(svn_cmdline__edit_string_externally(
+               &propval, NULL,
                opt_state->editor_cmd, temp_dir,
                propval, "svn-prop",
                ctx->config,
@@ -272,16 +273,16 @@ svn_cl__propedit(apr_getopt_t *os,
 
           /* Run the editor on a temporary file which contains the
              original property value... */
-          SVN_ERR(svn_cl__edit_string_externally(&edited_propval, NULL,
-                                                 opt_state->editor_cmd,
-                                                 base_dir,
-                                                 propval,
-                                                 "svn-prop",
-                                                 ctx->config,
-                                                 svn_prop_needs_translation
-                                                 (pname_utf8),
-                                                 opt_state->encoding,
-                                                 subpool));
+          SVN_ERR(svn_cmdline__edit_string_externally(&edited_propval, NULL,
+                                                      opt_state->editor_cmd,
+                                                      base_dir,
+                                                      propval,
+                                                      "svn-prop",
+                                                      ctx->config,
+                                                      svn_prop_needs_translation
+                                                      (pname_utf8),
+                                                      opt_state->encoding,
+                                                      subpool));
 
           target_local = svn_path_is_url(target) ? target
             : svn_dirent_local_style(target, subpool);

Modified: subversion/branches/tree-read-api/subversion/svn/propget-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/propget-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/propget-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/propget-cmd.c Sun Jan  6 02:33:34 2013
@@ -210,7 +210,7 @@ print_single_prop(svn_string_t *propval,
       apr_hash_t *hash = apr_hash_make(scratch_pool);
 
       apr_hash_set(hash, pname_utf8, APR_HASH_KEY_STRING, propval);
-      SVN_ERR(svn_cl__print_prop_hash(out, hash, FALSE, scratch_pool));
+      SVN_ERR(svn_cmdline__print_prop_hash(out, hash, FALSE, scratch_pool));
     }
   else
     {

Modified: subversion/branches/tree-read-api/subversion/svn/proplist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/proplist-cmd.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/proplist-cmd.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/proplist-cmd.c Sun Jan  6 02:33:34 2013
@@ -38,6 +38,8 @@
 #include "svn_props.h"
 #include "cl.h"
 
+#include "private/svn_cmdline_private.h"
+
 #include "svn_private_config.h"
 
 typedef struct proplist_baton_t
@@ -82,9 +84,9 @@ proplist_receiver_xml(void *baton,
 
           svn_xml_make_open_tag(&sb, iterpool, svn_xml_normal, "target",
                             "path", name_local, NULL);
-          SVN_ERR(svn_cl__print_xml_prop_hash(&sb, iprop->prop_hash,
-                                              (! opt_state->verbose),
-                                              TRUE, iterpool));
+          SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, iprop->prop_hash,
+                                                   (! opt_state->verbose),
+                                                   TRUE, iterpool));
           svn_xml_make_close_tag(&sb, iterpool, "target");
           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
         }
@@ -105,9 +107,9 @@ proplist_receiver_xml(void *baton,
         svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
                               "path", name_local, NULL);
 
-        SVN_ERR(svn_cl__print_xml_prop_hash(&sb, prop_hash,
-                                            (! opt_state->verbose),
-                                            FALSE, pool));
+        SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, prop_hash,
+                                                 (! opt_state->verbose),
+                                                 FALSE, pool));
 
         /* "</target>" */
         svn_xml_make_close_tag(&sb, pool, "target");
@@ -160,8 +162,9 @@ proplist_receiver(void *baton,
                                                      iterpool)));
             }
 
-          SVN_ERR(svn_cl__print_prop_hash(NULL, iprop->prop_hash,
-                                          (! opt_state->verbose), iterpool));
+          SVN_ERR(svn_cmdline__print_prop_hash(NULL, iprop->prop_hash,
+                                               (! opt_state->verbose),
+                                               iterpool));
         }
       svn_pool_destroy(iterpool);
     }
@@ -171,8 +174,8 @@ proplist_receiver(void *baton,
       if (!opt_state->quiet)
         SVN_ERR(svn_cmdline_printf(pool, _("Properties on '%s':\n"),
                                    name_local));
-      SVN_ERR(svn_cl__print_prop_hash(NULL, prop_hash, (! opt_state->verbose),
-                                      pool));
+      SVN_ERR(svn_cmdline__print_prop_hash(NULL, prop_hash,
+                                           (! opt_state->verbose), pool));
     }
 
   return SVN_NO_ERROR;
@@ -228,9 +231,9 @@ svn_cl__proplist(apr_getopt_t *os,
           svn_xml_make_open_tag(&sb, scratch_pool, svn_xml_normal,
                                 "revprops",
                                 "rev", revstr, NULL);
-          SVN_ERR(svn_cl__print_xml_prop_hash(&sb, proplist,
-                                              (! opt_state->verbose), FALSE,
-                                              scratch_pool));
+          SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, proplist,
+                                                   (! opt_state->verbose),
+                                                   FALSE, scratch_pool));
           svn_xml_make_close_tag(&sb, scratch_pool, "revprops");
 
           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
@@ -243,8 +246,9 @@ svn_cl__proplist(apr_getopt_t *os,
                                 _("Unversioned properties on revision %ld:\n"),
                                 rev));
 
-          SVN_ERR(svn_cl__print_prop_hash
-                  (NULL, proplist, (! opt_state->verbose), scratch_pool));
+          SVN_ERR(svn_cmdline__print_prop_hash(NULL, proplist,
+                                               (! opt_state->verbose),
+                                               scratch_pool));
         }
     }
   else  /* operate on normal, versioned properties (not revprops) */