You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/01/21 22:39:24 UTC

svn commit: r1726108 [3/4] - in /subversion/branches/parallel-put: ./ build/ac-macros/ notes/ notes/move-tracking/ subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/ subversion/bindings/swig/ subversion/bindings/swig/include/ subversio...

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/win32_crashrpt.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/win32_crashrpt.c Thu Jan 21 21:39:22 2016
@@ -84,32 +84,33 @@ convert_wbcs_to_ansi(const wchar_t *str)
 static const char *
 exception_string(int exception)
 {
-#define EXCEPTION(x) case EXCEPTION_##x: return (#x);
+#define EXCEPTION(x) case x: return (#x);
 
   switch (exception)
     {
-      EXCEPTION(ACCESS_VIOLATION)
-      EXCEPTION(DATATYPE_MISALIGNMENT)
-      EXCEPTION(BREAKPOINT)
-      EXCEPTION(SINGLE_STEP)
-      EXCEPTION(ARRAY_BOUNDS_EXCEEDED)
-      EXCEPTION(FLT_DENORMAL_OPERAND)
-      EXCEPTION(FLT_DIVIDE_BY_ZERO)
-      EXCEPTION(FLT_INEXACT_RESULT)
-      EXCEPTION(FLT_INVALID_OPERATION)
-      EXCEPTION(FLT_OVERFLOW)
-      EXCEPTION(FLT_STACK_CHECK)
-      EXCEPTION(FLT_UNDERFLOW)
-      EXCEPTION(INT_DIVIDE_BY_ZERO)
-      EXCEPTION(INT_OVERFLOW)
-      EXCEPTION(PRIV_INSTRUCTION)
-      EXCEPTION(IN_PAGE_ERROR)
-      EXCEPTION(ILLEGAL_INSTRUCTION)
-      EXCEPTION(NONCONTINUABLE_EXCEPTION)
-      EXCEPTION(STACK_OVERFLOW)
-      EXCEPTION(INVALID_DISPOSITION)
-      EXCEPTION(GUARD_PAGE)
-      EXCEPTION(INVALID_HANDLE)
+      EXCEPTION(EXCEPTION_ACCESS_VIOLATION)
+      EXCEPTION(EXCEPTION_DATATYPE_MISALIGNMENT)
+      EXCEPTION(EXCEPTION_BREAKPOINT)
+      EXCEPTION(EXCEPTION_SINGLE_STEP)
+      EXCEPTION(EXCEPTION_ARRAY_BOUNDS_EXCEEDED)
+      EXCEPTION(EXCEPTION_FLT_DENORMAL_OPERAND)
+      EXCEPTION(EXCEPTION_FLT_DIVIDE_BY_ZERO)
+      EXCEPTION(EXCEPTION_FLT_INEXACT_RESULT)
+      EXCEPTION(EXCEPTION_FLT_INVALID_OPERATION)
+      EXCEPTION(EXCEPTION_FLT_OVERFLOW)
+      EXCEPTION(EXCEPTION_FLT_STACK_CHECK)
+      EXCEPTION(EXCEPTION_FLT_UNDERFLOW)
+      EXCEPTION(EXCEPTION_INT_DIVIDE_BY_ZERO)
+      EXCEPTION(EXCEPTION_INT_OVERFLOW)
+      EXCEPTION(EXCEPTION_PRIV_INSTRUCTION)
+      EXCEPTION(EXCEPTION_IN_PAGE_ERROR)
+      EXCEPTION(EXCEPTION_ILLEGAL_INSTRUCTION)
+      EXCEPTION(EXCEPTION_NONCONTINUABLE_EXCEPTION)
+      EXCEPTION(EXCEPTION_STACK_OVERFLOW)
+      EXCEPTION(EXCEPTION_INVALID_DISPOSITION)
+      EXCEPTION(EXCEPTION_GUARD_PAGE)
+      EXCEPTION(EXCEPTION_INVALID_HANDLE)
+      EXCEPTION(STATUS_NO_MEMORY)
 
       default:
         return "UNKNOWN_ERROR";

Modified: subversion/branches/parallel-put/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_wc/conflicts.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_wc/conflicts.c Thu Jan 21 21:39:22 2016
@@ -3303,6 +3303,7 @@ svn_wc_create_conflict_result(svn_wc_con
   result->choice = choice;
   result->merged_file = apr_pstrdup(pool, merged_file);
   result->save_merged = FALSE;
+  result->merged_value = NULL;
 
   /* If we add more fields to svn_wc_conflict_result_t, add them here. */
 

Modified: subversion/branches/parallel-put/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_wc/update_editor.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_wc/update_editor.c Thu Jan 21 21:39:22 2016
@@ -2883,10 +2883,7 @@ absent_node(const char *path,
   if (pb->skip_this)
     return SVN_NO_ERROR;
 
-  SVN_ERR(mark_directory_edited(pb, scratch_pool));
-
   local_abspath = svn_dirent_join(pb->local_abspath, name, scratch_pool);
-
   /* If an item by this name is scheduled for addition that's a
      genuine tree-conflict.  */
   err = svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
@@ -2906,6 +2903,10 @@ absent_node(const char *path,
       kind = svn_node_unknown;
     }
 
+  if (status != svn_wc__db_status_server_excluded)
+    SVN_ERR(mark_directory_edited(pb, scratch_pool));
+  /* Else fall through as we should update the revision anyway */
+
   if (status == svn_wc__db_status_normal)
     {
       svn_boolean_t wcroot;
@@ -2929,31 +2930,53 @@ absent_node(const char *path,
         }
       else
         {
-          /* The server asks us to replace a file external
-             (Existing BASE node; not reported by the working copy crawler or
-              there would have been a delete_entry() call.
-
-             There is no way we can store this state in the working copy as
-             the BASE layer is already filled.
-
-             We could error out, but that is not helping anybody; the user is not
-             even seeing with what the file external would be replaced, so let's
-             report a skip and continue the update.
-           */
+          svn_boolean_t file_external;
+          svn_revnum_t revnum;
 
-          if (eb->notify_func)
+          SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &revnum, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL, NULL,
+                                           &file_external,
+                                           eb->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+          if (file_external)
             {
-              svn_wc_notify_t *notify;
-              notify = svn_wc_create_notify(
+              /* The server asks us to replace a file external
+                 (Existing BASE node; not reported by the working copy crawler
+                  or there would have been a delete_entry() call.
+
+                 There is no way we can store this state in the working copy as
+                 the BASE layer is already filled.
+                 We could error out, but that is not helping anybody; the user is not
+                 even seeing with what the file external would be replaced, so let's
+                 report a skip and continue the update.
+               */
+
+              if (eb->notify_func)
+                {
+                  svn_wc_notify_t *notify;
+                  notify = svn_wc_create_notify(
                                     local_abspath,
                                     svn_wc_notify_update_skip_obstruction,
                                     scratch_pool);
 
-              eb->notify_func(eb->notify_baton, notify, scratch_pool);
+                  eb->notify_func(eb->notify_baton, notify, scratch_pool);
+                }
+
+              svn_pool_destroy(scratch_pool);
+              return SVN_NO_ERROR;
             }
+          else
+            {
+              /* We have a normal local node that will now be hidden for the
+                 user. Let's try to delete what is there. This may introduce
+                 tree conflicts if there are local changes */
+              SVN_ERR(delete_entry(path, revnum, pb, scratch_pool));
 
-          svn_pool_destroy(scratch_pool);
-          return SVN_NO_ERROR;
+              /* delete_entry() promises that BASE is empty after the operation,
+                 so we can just fall through now */
+            }
         }
     }
   else if (status == svn_wc__db_status_not_present

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/activity.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/activity.c Thu Jan 21 21:39:22 2016
@@ -227,7 +227,7 @@ dav_svn__store_activity(const dav_svn_re
 
 
 dav_error *
-dav_svn__create_txn(const dav_svn_repos *repos,
+dav_svn__create_txn(dav_svn_repos *repos,
                     const char **ptxn_name,
                     apr_hash_t *revprops,
                     apr_pool_t *pool)
@@ -248,7 +248,7 @@ dav_svn__create_txn(const dav_svn_repos
                     svn_string_create(repos->username, pool));
     }
 
-  serr = svn_fs_youngest_rev(&rev, repos->fs, pool);
+  serr = dav_svn__get_youngest_rev(&rev, repos, pool);
   if (serr != NULL)
     {
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/dav_svn.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/dav_svn.h Thu Jan 21 21:39:22 2016
@@ -149,6 +149,9 @@ typedef struct dav_svn_repos {
   /* The path to the activities db */
   const char *activities_db;
 
+  /* Cached yongest revision of the repository. SVN_INVALID_REVNUM if
+     youngest revision is not fetched yet. */
+  svn_revnum_t youngest_rev;
 } dav_svn_repos;
 
 
@@ -333,6 +336,10 @@ svn_boolean_t dav_svn__get_fulltext_cach
 /* for the repository referred to by this request, is revprop caching active? */
 svn_boolean_t dav_svn__get_revprop_cache_flag(request_rec *r);
 
+/* for the repository referred to by this request, is node prop caching active? */
+svn_boolean_t
+dav_svn__get_nodeprop_cache_flag(request_rec *r);
+
 /* has block read mode been enabled for the repository referred to by this
  * request? */
 svn_boolean_t dav_svn__get_block_read_flag(request_rec *r);
@@ -462,7 +469,7 @@ const char *dav_svn__get_vtxn_root_stub(
    NOTE:  This function will overwrite the svn:author property, if
    any, found in REVPROPS.  */
 dav_error *
-dav_svn__create_txn(const dav_svn_repos *repos,
+dav_svn__create_txn(dav_svn_repos *repos,
                     const char **ptxn_name,
                     apr_hash_t *revprops,
                     apr_pool_t *pool);
@@ -1055,6 +1062,19 @@ int dav_svn__error_response_tag(request_
 int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
                                 apr_pool_t *pool);
 
+/* Set *YOUNGEST_P to the number of the youngest revision in REPOS.
+ *
+ * Youngest revision will be cached in REPOS->YOUNGEST_REV to avoid
+ * fetching the youngest revision multiple times during proccessing
+ * the request.
+ *
+ * Uses SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+dav_svn__get_youngest_rev(svn_revnum_t *youngest_p,
+                          dav_svn_repos *repos,
+                          apr_pool_t *scratch_pool);
+
 /*** mirror.c ***/
 
 /* Perform the fixup hook for the R request.  */

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/deadprops.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/deadprops.c Thu Jan 21 21:39:22 2016
@@ -110,7 +110,12 @@ get_value(dav_db *db, const dav_prop_nam
       return NULL;
     }
 
-  /* ### if db->props exists, then try in there first */
+  /* If db->props exists, then use it to obtain property value. */
+  if (db->props)
+    {
+      *pvalue = svn_hash_gets(db->props, propname);
+      return NULL;
+    }
 
   /* We've got three different types of properties (node, txn, and
      revision), and we've got two different protocol versions to deal
@@ -705,19 +710,14 @@ db_first_name(dav_db *db, dav_prop_name
         }
       else
         {
-          svn_node_kind_t kind;
           serr = svn_fs_node_proplist(&db->props,
                                       db->resource->info->root.root,
                                       get_repos_path(db->resource->info),
                                       db->p);
-          if (! serr)
-            serr = svn_fs_check_path(&kind, db->resource->info->root.root,
-                                     get_repos_path(db->resource->info),
-                                     db->p);
 
           if (! serr)
             {
-              if (kind == svn_node_dir)
+              if (db->resource->collection)
                 action = svn_log__get_dir(db->resource->info->repos_path,
                                           db->resource->info->root.rev,
                                           FALSE, TRUE, 0, db->resource->pool);

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/liveprops.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/liveprops.c Thu Jan 21 21:39:22 2016
@@ -598,8 +598,8 @@ insert_prop_internal(const dav_resource
         {
           svn_revnum_t revnum;
 
-          serr = svn_fs_youngest_rev(&revnum, resource->info->repos->fs,
-                                     scratch_pool);
+          serr = dav_svn__get_youngest_rev(&revnum, resource->info->repos,
+                                           scratch_pool);
           if (serr != NULL)
             {
               ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
@@ -720,7 +720,6 @@ insert_prop_internal(const dav_resource
               || resource->type == DAV_RESOURCE_TYPE_WORKING
               || resource->type == DAV_RESOURCE_TYPE_VERSION))
         {
-          svn_node_kind_t kind;
           svn_checksum_t *checksum;
           svn_checksum_kind_t checksum_kind;
 
@@ -733,14 +732,20 @@ insert_prop_internal(const dav_resource
               checksum_kind = svn_checksum_sha1;
             }
 
-          serr = svn_fs_check_path(&kind, resource->info->root.root,
-                                   resource->info->repos_path, scratch_pool);
-          if (!serr && kind == svn_node_file)
-            serr = svn_fs_file_checksum(&checksum, checksum_kind,
-                                        resource->info->root.root,
-                                        resource->info->repos_path, TRUE,
-                                        scratch_pool);
-          if (serr != NULL)
+          serr = svn_fs_file_checksum(&checksum, checksum_kind,
+                                      resource->info->root.root,
+                                      resource->info->repos_path, TRUE,
+                                      scratch_pool);
+          if (serr && serr->apr_err == SVN_ERR_FS_NOT_FILE)
+            {
+              /* It should not happen since we're already checked
+                 RESOURCE->COLLECTION, but svn_fs_check_path() call
+                 was added in r1239596 for some reason. Keep it for
+                 now. */
+              svn_error_clear(serr);
+              return DAV_PROP_INSERT_NOTSUPP;
+            }
+          else if (serr)
             {
               ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                             resource->info->r,
@@ -756,9 +761,6 @@ insert_prop_internal(const dav_resource
               break;
             }
 
-          if (kind != svn_node_file)
-            return DAV_PROP_INSERT_NOTSUPP;
-
           value = svn_checksum_to_cstring(checksum, scratch_pool);
 
           if (! value)

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/lock.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/lock.c Thu Jan 21 21:39:22 2016
@@ -717,7 +717,7 @@ append_locks(dav_lockdb *lockdb,
 
       /* Commit a 0-byte file: */
 
-      if ((serr = svn_fs_youngest_rev(&rev, repos->fs, resource->pool)))
+      if ((serr = dav_svn__get_youngest_rev(&rev, repos, resource->pool)))
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest revision",
                                     resource->pool);

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/merge.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/merge.c Thu Jan 21 21:39:22 2016
@@ -226,6 +226,7 @@ dav_svn__merge_response(ap_filter_t *out
   const char *post_commit_err_elem = NULL,
              *post_commit_header_info = NULL;
   apr_status_t status;
+  apr_hash_t *revprops;
 
   serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
   if (serr != NULL)
@@ -268,23 +269,17 @@ dav_svn__merge_response(ap_filter_t *out
 
 
   /* get the creationdate and creator-displayname of the new revision, too. */
-  serr = svn_fs_revision_prop2(&creationdate, repos->fs, new_rev,
-                               SVN_PROP_REVISION_DATE, TRUE, pool, pool);
+  serr = svn_fs_revision_proplist2(&revprops, repos->fs, new_rev,
+                                   TRUE, pool, pool);
   if (serr != NULL)
     {
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                  "Could not get date of newest revision",
-                                  repos->pool);
-    }
-  serr = svn_fs_revision_prop2(&creator_displayname, repos->fs, new_rev,
-                               SVN_PROP_REVISION_AUTHOR, TRUE, pool, pool);
-  if (serr != NULL)
-    {
-      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                  "Could not get author of newest revision",
-                                  repos->pool);
+                                  "Could not get date and author of newest "
+                                  "revision", repos->pool);
     }
 
+  creationdate = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+  creator_displayname = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
 
   status = ap_fputstrs(output, bb,
                      DAV_XML_HEADER DEBUG_CR

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/mod_dav_svn.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/mod_dav_svn.c Thu Jan 21 21:39:22 2016
@@ -105,6 +105,7 @@ typedef struct dir_conf_t {
   enum conf_flag txdelta_cache;      /* whether to enable txdelta caching */
   enum conf_flag fulltext_cache;     /* whether to enable fulltext caching */
   enum conf_flag revprop_cache;      /* whether to enable revprop caching */
+  enum conf_flag nodeprop_cache;     /* whether to enable nodeprop caching */
   enum conf_flag block_read;         /* whether to enable block read mode */
   const char *hooks_env;             /* path to hook script env config file */
 } dir_conf_t;
@@ -240,6 +241,7 @@ create_dir_config(apr_pool_t *p, char *d
   conf->v2_protocol = CONF_FLAG_DEFAULT;
   conf->hooks_env = NULL;
   conf->txdelta_cache = CONF_FLAG_DEFAULT;
+  conf->nodeprop_cache = CONF_FLAG_DEFAULT;
 
   return conf;
 }
@@ -270,6 +272,7 @@ merge_dir_config(apr_pool_t *p, void *ba
   newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
   newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
   newconf->revprop_cache = INHERIT_VALUE(parent, child, revprop_cache);
+  newconf->nodeprop_cache = INHERIT_VALUE(parent, child, nodeprop_cache);
   newconf->block_read = INHERIT_VALUE(parent, child, block_read);
   newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
   newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
@@ -567,6 +570,19 @@ SVNCacheRevProps_cmd(cmd_parms *cmd, voi
 }
 
 static const char *
+SVNCacheNodeProps_cmd(cmd_parms *cmd, void *config, int arg)
+{
+  dir_conf_t *conf = config;
+
+  if (arg)
+    conf->nodeprop_cache = CONF_FLAG_ON;
+  else
+    conf->nodeprop_cache = CONF_FLAG_OFF;
+
+  return NULL;
+}
+
+static const char *
 SVNBlockRead_cmd(cmd_parms *cmd, void *config, int arg)
 {
   dir_conf_t *conf = config;
@@ -991,6 +1007,15 @@ dav_svn__get_revprop_cache_flag(request_
   return conf->revprop_cache == CONF_FLAG_ON;
 }
 
+svn_boolean_t
+dav_svn__get_nodeprop_cache_flag(request_rec *r)
+{
+  dir_conf_t *conf;
+
+  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+  /* node properties caching is enabled by default. */
+  return get_conf_flag(conf->nodeprop_cache, FALSE);
+}
 
 svn_boolean_t
 dav_svn__get_block_read_flag(request_rec *r)
@@ -1343,6 +1368,13 @@ static const command_rec cmds[] =
                "(default is Off)."),
 
   /* per directory/location */
+  AP_INIT_FLAG("SVNCacheNodeProps", SVNCacheNodeProps_cmd, NULL,
+               ACCESS_CONF|RSRC_CONF,
+               "speeds up data access by caching node properties "
+               "if sufficient in-memory cache is available"
+               "(default is On)."),
+
+  /* per directory/location */
   AP_INIT_FLAG("SVNBlockRead", SVNBlockRead_cmd, NULL,
                ACCESS_CONF|RSRC_CONF,
                "speeds up operations of FSFS 1.9+ repositories if large"

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/reports/get-location-segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/reports/get-location-segments.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/reports/get-location-segments.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/reports/get-location-segments.c Thu Jan 21 21:39:22 2016
@@ -183,8 +183,8 @@ dav_svn__get_location_segments_report(co
     {
       svn_revnum_t youngest;
 
-      serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
-                                 resource->pool);
+      serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
+                                       resource->pool);
       if (serr != NULL)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest revision",

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/reports/update.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/reports/update.c Thu Jan 21 21:39:22 2016
@@ -970,7 +970,7 @@ dav_svn__update_report(const dav_resourc
   dav_error *derr = NULL;
   const char *src_path = NULL;
   const char *dst_path = NULL;
-  const dav_svn_repos *repos = resource->info->repos;
+  dav_svn_repos *repos = resource->info->repos;
   const char *target = "";
   svn_boolean_t text_deltas = TRUE;
   svn_depth_t requested_depth = svn_depth_unknown;
@@ -1028,7 +1028,7 @@ dav_svn__update_report(const dav_resourc
 
   /* Ask the repository about its youngest revision (which we'll need
      for some input validation later). */
-  if ((serr = svn_fs_youngest_rev(&youngest, repos->fs, resource->pool)))
+  if ((serr = dav_svn__get_youngest_rev(&youngest, repos, resource->pool)))
     return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                 "Could not determine the youngest "
                                 "revision for the update process.",

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/repos.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/repos.c Thu Jan 21 21:39:22 2016
@@ -810,7 +810,7 @@ prep_regular(dav_resource_combined *comb
      ### other cases besides a BC? */
   if (comb->priv.root.rev == SVN_INVALID_REVNUM)
     {
-      serr = svn_fs_youngest_rev(&comb->priv.root.rev, repos->fs, pool);
+      serr = dav_svn__get_youngest_rev(&comb->priv.root.rev, repos, pool);
       if (serr != NULL)
         {
           return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -879,9 +879,9 @@ prep_version(dav_resource_combined *comb
   /* if we don't have a revision, then assume the youngest */
   if (!SVN_IS_VALID_REVNUM(comb->priv.root.rev))
     {
-      serr = svn_fs_youngest_rev(&comb->priv.root.rev,
-                                 comb->priv.repos->fs,
-                                 pool);
+      serr = dav_svn__get_youngest_rev(&comb->priv.root.rev,
+                                       comb->priv.repos,
+                                       pool);
       if (serr != NULL)
         {
           /* ### might not be a baseline */
@@ -1583,6 +1583,7 @@ get_parentpath_resource(request_rec *r,
   repos->special_uri = dav_svn__get_special_uri(r);
   repos->username = r->user;
   repos->client_capabilities = apr_hash_make(repos->pool);
+  repos->youngest_rev = SVN_INVALID_REVNUM;
 
   /* Make sure this type of resource always has a trailing slash; if
      not, redirect to a URI that does. */
@@ -2020,7 +2021,7 @@ parse_querystring(request_rec *r, const
   else
     {
       /* No peg-rev?  Default to HEAD, just like the cmdline client. */
-      serr = svn_fs_youngest_rev(&peg_rev, comb->priv.repos->fs, pool);
+      serr = dav_svn__get_youngest_rev(&peg_rev, comb->priv.repos, pool);
       if (serr != NULL)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Couldn't fetch youngest rev.", pool);
@@ -2259,6 +2260,7 @@ get_resource(request_rec *r,
   /* create the repository structure and stash it away */
   repos = apr_pcalloc(r->pool, sizeof(*repos));
   repos->pool = r->pool;
+  repos->youngest_rev = SVN_INVALID_REVNUM;
 
   comb->priv.repos = repos;
 
@@ -2367,6 +2369,8 @@ get_resource(request_rec *r,
                     dav_svn__get_fulltext_cache_flag(r) ? "1" :"0");
       svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                     dav_svn__get_revprop_cache_flag(r) ? "2" :"0");
+      svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+                    dav_svn__get_nodeprop_cache_flag(r) ? "1" :"0");
       svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ,
                     dav_svn__get_block_read_flag(r) ? "1" :"0");
 
@@ -3034,50 +3038,6 @@ seek_stream(dav_stream *stream, apr_off_
        && resource->baselined))
 
 
-/* Return the last modification time of RESOURCE, or -1 if the DAV
-   resource type is not handled, or if an error occurs.  Temporary
-   allocations are made from RESOURCE->POOL. */
-static apr_time_t
-get_last_modified(const dav_resource *resource)
-{
-  apr_time_t last_modified;
-  svn_error_t *serr;
-  svn_revnum_t created_rev;
-  svn_string_t *date_time;
-
-  if (RESOURCE_LACKS_ETAG_POTENTIAL(resource))
-    return -1;
-
-  if ((serr = svn_fs_node_created_rev(&created_rev, resource->info->root.root,
-                                      resource->info->repos_path,
-                                      resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  if ((serr = svn_fs_revision_prop2(&date_time, resource->info->repos->fs,
-                                    created_rev, "svn:date", TRUE,
-                                    resource->pool, resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  if (date_time == NULL || date_time->data == NULL)
-    return -1;
-
-  if ((serr = svn_time_from_cstring(&last_modified, date_time->data,
-                                    resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  return last_modified;
-}
-
-
 const char *
 dav_svn__getetag(const dav_resource *resource, apr_pool_t *pool)
 {
@@ -3147,7 +3107,6 @@ set_headers(request_rec *r, const dav_re
   svn_error_t *serr;
   svn_filesize_t length;
   const char *mimetype = NULL;
-  apr_time_t last_modified;
 
   /* As version resources don't change, encourage caching. */
   if (is_cacheable(r, resource))
@@ -3159,15 +3118,6 @@ set_headers(request_rec *r, const dav_re
   if (!resource->exists)
     return NULL;
 
-  last_modified = get_last_modified(resource);
-  if (last_modified != -1)
-    {
-      /* Note the modification time for the requested resource, and
-         include the Last-Modified header in the response. */
-      ap_update_mtime(r, last_modified);
-      ap_set_last_modified(r);
-    }
-
   /* generate our etag and place it into the output */
   apr_table_setn(r->headers_out, "ETag",
                  dav_svn__getetag(resource, resource->pool));
@@ -4633,7 +4583,7 @@ dav_svn__working_to_regular_resource(dav
   /* Change the URL into either a baseline-collection or a public one. */
   if (priv->root.rev == SVN_INVALID_REVNUM)
     {
-      serr = svn_fs_youngest_rev(&priv->root.rev, repos->fs, resource->pool);
+      serr = dav_svn__get_youngest_rev(&priv->root.rev, repos, resource->pool);
       if (serr != NULL)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest rev.",

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/util.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/util.c Thu Jan 21 21:39:22 2016
@@ -870,3 +870,19 @@ dav_svn__parse_request_skel(svn_skel_t *
   *skel = svn_skel__parse(skel_str->data, skel_str->len, pool);
   return OK;
 }
+
+svn_error_t *
+dav_svn__get_youngest_rev(svn_revnum_t *youngest_p,
+                          dav_svn_repos *repos,
+                          apr_pool_t *scratch_pool)
+{
+  if (repos->youngest_rev == SVN_INVALID_REVNUM)
+    {
+      svn_revnum_t revnum;
+      SVN_ERR(svn_fs_youngest_rev(&revnum, repos->fs, scratch_pool));
+      repos->youngest_rev = revnum;
+    }
+
+   *youngest_p = repos->youngest_rev;
+   return SVN_NO_ERROR;
+}

Modified: subversion/branches/parallel-put/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/mod_dav_svn/version.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/parallel-put/subversion/mod_dav_svn/version.c Thu Jan 21 21:39:22 2016
@@ -221,8 +221,8 @@ get_option(const dav_resource *resource,
       const char *uuid;
 
       /* Got youngest revision? */
-      if ((serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
-                                      resource->pool)))
+      if ((serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
+                                            resource->pool)))
         {
           return dav_svn__convert_err
             (serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -616,8 +616,8 @@ dav_svn__checkout(dav_resource *resource
       svn_revnum_t youngest;
 
       /* make sure the baseline being checked out is the latest */
-      serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
-                                 resource->pool);
+      serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
+                                       resource->pool);
       if (serr != NULL)
         {
           /* ### correct HTTP error? */

Modified: subversion/branches/parallel-put/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/cl.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/cl.h (original)
+++ subversion/branches/parallel-put/subversion/svn/cl.h Thu Jan 21 21:39:22 2016
@@ -362,6 +362,14 @@ svn_cl__conflict_stats_resolved(svn_cl__
                                 const char *path_local,
                                 svn_wc_conflict_kind_t conflict_kind);
 
+/* Set *CONFLICTED_PATHS to the conflicted paths contained in CONFLICT_STATS.
+ * If no conflicted path exists, set *CONFLICTED_PATHS to NULL. */
+svn_error_t *
+svn_cl__conflict_stats_get_paths(apr_array_header_t **conflicted_paths,
+                                 svn_cl__conflict_stats_t *conflict_stats,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
+
 /* Print the conflict stats accumulated in CONFLICT_STATS.
  *
  * Return any error encountered during printing.
@@ -371,39 +379,11 @@ svn_error_t *
 svn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats,
                              apr_pool_t *scratch_pool);
 
-/* Create and return an baton for use with svn_cl__conflict_func_interactive
- * in *B, allocated from RESULT_POOL, and initialised with the values
- * ACCEPT_WHICH, CONFIG, EDITOR_CMD, CANCEL_FUNC and CANCEL_BATON. */
-svn_error_t *
-svn_cl__get_conflict_func_interactive_baton(
-  svn_cl__interactive_conflict_baton_t **b,
-  svn_cl__accept_t accept_which,
-  apr_hash_t *config,
-  const char *editor_cmd,
-  svn_cl__conflict_stats_t *conflict_stats,
-  svn_cancel_func_t cancel_func,
-  void *cancel_baton,
-  apr_pool_t *result_pool);
-
-/* A callback capable of doing interactive conflict resolution.
-
-   The BATON must come from svn_cl__get_conflict_func_interactive_baton().
-   Resolves based on the --accept option if one was given to that function,
-   otherwise prompts the user to choose one of the three fulltexts, edit
-   the merged file on the spot, or just skip the conflict (to be resolved
-   later), among other options.
-
-   Implements svn_wc_conflict_resolver_func2_t.
+/* 
+ * Interactively resolve the conflict a @a CONFLICT.
+ * TODO: more docs
  */
 svn_error_t *
-svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
-                                  const svn_wc_conflict_description2_t *desc,
-                                  void *baton,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool);
-
-
-svn_error_t *
 svn_cl__resolve_conflict(svn_boolean_t *resolved,
                          svn_cl__accept_t *accept_which,
                          svn_boolean_t *quit,
@@ -419,6 +399,18 @@ svn_cl__resolve_conflict(svn_boolean_t *
                          svn_client_ctx_t *ctx,
                          apr_pool_t *scratch_pool);
 
+/* 
+ * Interactively resolve conflicts for all TARGETS.
+ * TODO: more docs
+ */
+svn_error_t *
+svn_cl__walk_conflicts(apr_array_header_t *targets,
+                       svn_cl__conflict_stats_t *conflict_stats,
+                       svn_boolean_t is_resolve_cmd,
+                       svn_cl__opt_state_t *opt_state,
+                       svn_client_ctx_t *ctx,
+                       apr_pool_t *scratch_pool);
+
 
 /*** Command-line output functions -- printing to the user. ***/
 

Modified: subversion/branches/parallel-put/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/conflict-callbacks.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/parallel-put/subversion/svn/conflict-callbacks.c Thu Jan 21 21:39:22 2016
@@ -63,35 +63,6 @@ struct svn_cl__interactive_conflict_bato
   svn_boolean_t printed_summary;
 };
 
-svn_error_t *
-svn_cl__get_conflict_func_interactive_baton(
-  svn_cl__interactive_conflict_baton_t **b,
-  svn_cl__accept_t accept_which,
-  apr_hash_t *config,
-  const char *editor_cmd,
-  svn_cl__conflict_stats_t *conflict_stats,
-  svn_cancel_func_t cancel_func,
-  void *cancel_baton,
-  apr_pool_t *result_pool)
-{
-  svn_cmdline_prompt_baton_t *pb = apr_palloc(result_pool, sizeof(*pb));
-  pb->cancel_func = cancel_func;
-  pb->cancel_baton = cancel_baton;
-
-  *b = apr_palloc(result_pool, sizeof(**b));
-  (*b)->accept_which = accept_which;
-  (*b)->config = config;
-  (*b)->editor_cmd = editor_cmd;
-  (*b)->external_failed = FALSE;
-  (*b)->pb = pb;
-  SVN_ERR(svn_dirent_get_absolute(&(*b)->path_prefix, "", result_pool));
-  (*b)->quit = FALSE;
-  (*b)->conflict_stats = conflict_stats;
-  (*b)->printed_summary = FALSE;
-
-  return SVN_NO_ERROR;
-}
-
 svn_cl__accept_t
 svn_cl__accept_from_word(const char *word)
 {
@@ -424,6 +395,7 @@ typedef struct resolver_option_t
   const char *long_desc;   /* longer description (localized) */
   svn_client_conflict_option_id_t choice;
                            /* or ..._undefined if not a simple choice */
+  const char *accept_arg;  /* --accept option argument (NOT localized) */
 } resolver_option_t;
 
 /* Resolver options for a text conflict */
@@ -433,43 +405,44 @@ static const resolver_option_t text_conf
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed); don't translate the words within square
      brackets. */
-  { "e",  N_("edit file"),        N_("change merged file in an editor"
-                                     "  [edit]"),
-                                  svn_client_conflict_option_undefined },
+  { "e",  N_("edit file"),        N_("change merged file in an editor"),
+                                  svn_client_conflict_option_undefined,
+                                  SVN_CL__ACCEPT_EDIT },
   { "df", N_("show diff"),        N_("show all changes made to merged file"),
-                                  svn_client_conflict_option_undefined },
-  { "r",  N_("mark resolved"),   N_("accept merged version of file  [working]"),
-                                  svn_client_conflict_option_merged_text },
+                                  svn_client_conflict_option_undefined},
+  { "r",  N_("mark resolved"),    NULL,
+                                  svn_client_conflict_option_merged_text,
+                                  SVN_CL__ACCEPT_WORKING },
   { "",   "",                     "", svn_client_conflict_option_unspecified },
   { "dc", N_("display conflict"), N_("show all conflicts "
                                      "(ignoring merged version)"),
                                   svn_client_conflict_option_undefined },
-  { "mc", N_("my side of conflict"), N_("accept my version for all conflicts "
-                                        "(same)  [mine-conflict]"),
-                                  svn_client_conflict_option_working_text_where_conflicted },
-  { "tc", N_("their side of conflict"), N_("accept their version for all "
-                                           "conflicts (same)"
-                                           "  [theirs-conflict]"),
-                                  svn_client_conflict_option_incoming_text_where_conflicted },
+  { "mc", N_("my side of conflict"), NULL,
+                                  svn_client_conflict_option_working_text_where_conflicted,
+                                  SVN_CL__ACCEPT_MINE_CONFLICT },
+  { "tc", N_("their side of conflict"), NULL,
+                                  svn_client_conflict_option_incoming_text_where_conflicted,
+                                  SVN_CL__ACCEPT_THEIRS_CONFLICT },
   { "",   "",                     "", svn_client_conflict_option_unspecified },
-  { "mf", N_("my version"),       N_("accept my version of entire file (even "
-                                     "non-conflicts)  [mine-full]"),
-                                  svn_client_conflict_option_working_text },
-  { "tf", N_("their version"),    N_("accept their version of entire file "
-                                     "(same)  [theirs-full]"),
-                                  svn_client_conflict_option_incoming_text },
+  { "mf", N_("my version"),       NULL,
+                                  svn_client_conflict_option_working_text,
+                                  SVN_CL__ACCEPT_MINE_FULL},
+  { "tf", N_("their version"),    NULL,
+                                  svn_client_conflict_option_incoming_text,
+                                  SVN_CL__ACCEPT_THEIRS_FULL },
   { "",   "",                     "", svn_client_conflict_option_unspecified },
   { "m",  N_("merge"),            N_("use merge tool to resolve conflict"),
                                   svn_client_conflict_option_undefined },
   { "l",  N_("launch tool"),      N_("launch external merge tool to resolve "
-                                     "conflict  [launch]"),
-                                  svn_client_conflict_option_undefined },
+                                     "conflict"),
+                                  svn_client_conflict_option_undefined,
+                                  SVN_CL__ACCEPT_LAUNCH },
   { "i",  N_("internal merge tool"), N_("use built-in merge tool to "
                                      "resolve conflict"),
                                   svn_client_conflict_option_undefined },
-  { "p",  N_("postpone"),         N_("mark the conflict to be resolved later"
-                                     "  [postpone]"),
-                                  svn_client_conflict_option_postpone },
+  { "p",  N_("postpone"),         NULL,
+                                  svn_client_conflict_option_postpone,
+                                  SVN_CL__ACCEPT_POSTPONE },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { "s",  N_("show all options"), N_("show this list (also 'h', '?')"),
@@ -483,15 +456,15 @@ static const resolver_option_t binary_co
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed); don't translate the words within square
      brackets. */
-  { "r",  N_("mark resolved"),   N_("accept the working copy version of file "
-                                    " [working]"),
-                                  svn_client_conflict_option_merged_text },
-  { "tf", N_("their version"),    N_("accept the incoming version of file "
-                                     " [theirs-full]"),
-                                  svn_client_conflict_option_incoming_text },
-  { "p",  N_("postpone"),         N_("mark the conflict to be resolved later "
-                                     " [postpone]"),
-                                  svn_client_conflict_option_postpone },
+  { "r",  N_("mark resolved"),    NULL,
+                                  svn_client_conflict_option_merged_text,
+                                  SVN_CL__ACCEPT_WORKING },
+  { "tf", N_("their version"),    NULL,
+                                  svn_client_conflict_option_incoming_text,
+                                  SVN_CL__ACCEPT_THEIRS_FULL},
+  { "p",  N_("postpone"),         NULL,
+                                  svn_client_conflict_option_postpone,
+                                  SVN_CL__ACCEPT_POSTPONE},
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { "s",  N_("show all options"), N_("show this list (also 'h', '?')"),
@@ -502,22 +475,23 @@ static const resolver_option_t binary_co
 /* Resolver options for a property conflict */
 static const resolver_option_t prop_conflict_options[] =
 {
-  { "mf", N_("my version"),       N_("accept my version of entire property (even "
-                                     "non-conflicts)  [mine-full]"),
-                                  svn_client_conflict_option_working_text },
-  { "tf", N_("their version"),    N_("accept their version of entire property "
-                                     "(same)  [theirs-full]"),
-                                  svn_client_conflict_option_incoming_text },
+  { "mf", N_("my version"),       NULL,
+                                  svn_client_conflict_option_working_text,
+                                  SVN_CL__ACCEPT_MINE_FULL },
+  { "tf", N_("their version"),    NULL,
+                                  svn_client_conflict_option_incoming_text,
+                                  SVN_CL__ACCEPT_THEIRS_FULL },
   { "dc", N_("display conflict"), N_("show conflicts in this property"),
                                   svn_client_conflict_option_undefined },
-  { "e",  N_("edit property"),    N_("change merged property value in an editor"
-                                     "  [edit]"),
-                                  svn_client_conflict_option_undefined },
-  { "r",  N_("mark resolved"),    N_("accept edited version of property"),
+  { "e",  N_("edit property"),    N_("change merged property value in an "
+                                     "editor"),
+                                  svn_client_conflict_option_undefined,
+                                  SVN_CL__ACCEPT_EDIT },
+  { "r",  N_("mark resolved"),    NULL,
                                   svn_client_conflict_option_merged_text },
-  { "p",  N_("postpone"),         N_("mark the conflict to be resolved later"
-                                     "  [postpone]"),
-                                  svn_client_conflict_option_postpone },
+  { "p",  N_("postpone"),         NULL,
+                                  svn_client_conflict_option_postpone,
+                                  SVN_CL__ACCEPT_POSTPONE },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { "h",  N_("help"),             N_("show this help (also '?')"),
@@ -528,10 +502,11 @@ static const resolver_option_t prop_conf
 /* Resolver options for a tree conflict */
 static const resolver_option_t tree_conflict_options[] =
 {
-  { "r",  N_("mark resolved"),    N_("accept current working copy state"),
+  { "r",  N_("mark resolved"),    NULL,
                                   svn_client_conflict_option_merged_text },
-  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
-                                  svn_client_conflict_option_postpone },
+  { "p",  N_("postpone"),         NULL,
+                                  svn_client_conflict_option_postpone,
+                                  SVN_CL__ACCEPT_POSTPONE },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { "h",  N_("help"),             N_("show this help (also '?')"),
@@ -545,8 +520,9 @@ static const resolver_option_t tree_conf
                                   N_("apply incoming update to move destination"
                                      "  [mine-conflict]"),
                                   svn_client_conflict_option_working_text_where_conflicted },
-  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
-                                  svn_client_conflict_option_postpone },
+  { "p",  N_("postpone"),         NULL,
+                                  svn_client_conflict_option_postpone,
+                                  SVN_CL__ACCEPT_POSTPONE },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { "h",  N_("help"),             N_("show this help (also '?')"),
@@ -560,8 +536,9 @@ static const resolver_option_t tree_conf
                                   N_("allow updating moved-away children "
                                      "with 'svn resolve' [mine-conflict]"),
                                   svn_client_conflict_option_working_text_where_conflicted },
-  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
-                                  svn_client_conflict_option_postpone },
+  { "p",  N_("postpone"),         NULL,
+                                  svn_client_conflict_option_postpone,
+                                  SVN_CL__ACCEPT_POSTPONE },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { "h",  N_("help"),             N_("show this help (also '?')"),
@@ -636,34 +613,61 @@ prompt_string(const resolver_option_t *o
   return apr_pstrcat(pool, result, ": ", SVN_VA_NULL);
 }
 
-/* Return a help string listing the OPTIONS. */
-static const char *
-help_string(const resolver_option_t *options,
+/* Return a help string listing the OPTIONS. Lookup a description for
+ * the DEFAULT_OPTIONS if OPTIONS doesn't contain one. */
+static svn_error_t *
+help_string(const char **result,
+            const resolver_option_t *options,
+            apr_array_header_t *default_options,
             apr_pool_t *pool)
 {
-  const char *result = "";
   const resolver_option_t *opt;
+  apr_pool_t *iterpool;
 
+  *result = "";
+  iterpool = svn_pool_create(pool);
   for (opt = options; opt->code; opt++)
     {
+      svn_pool_clear(iterpool);
+
       /* 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);
+          const char *desc;
 
-          result = apr_psprintf(pool, "%s%-6s - %s\n",
-                                result, s, _(opt->long_desc));
+          if (opt->long_desc == NULL)
+            {
+              svn_client_conflict_option_t *option;
+
+              option = svn_client_conflict_option_find_by_id(default_options,
+                                                             opt->choice);
+              if (option == NULL)
+                desc = ""; /* ### return an error? */
+              else
+                SVN_ERR(svn_client_conflict_option_describe(&desc, option,
+                                                            pool, iterpool));
+            }
+          else
+            desc = opt->long_desc;
+
+          if (opt->accept_arg)
+            *result = apr_psprintf(pool, "%s%-6s - %s  [%s]\n",
+                                   *result, s, desc, opt->accept_arg);
+          else
+            *result = apr_psprintf(pool, "%s%-6s - %s\n", *result, s, desc);
         }
       else
         {
-          result = apr_pstrcat(pool, result, "\n", SVN_VA_NULL);
+          *result = apr_pstrcat(pool, *result, "\n", SVN_VA_NULL);
         }
     }
-  result = apr_pstrcat(pool, result,
+  svn_pool_destroy(iterpool);
+  *result = apr_pstrcat(pool, *result,
                        _("Words in square brackets are the corresponding "
                          "--accept option arguments.\n"),
                        SVN_VA_NULL);
-  return result;
+  return SVN_NO_ERROR;
 }
 
 /* Prompt the user with CONFLICT_OPTIONS, restricted to the options listed
@@ -671,12 +675,16 @@ help_string(const resolver_option_t *opt
  * one of CONFLICT_OPTIONS (not necessarily one of OPTIONS_TO_SHOW), or to
  * NULL if the answer was not one of them.
  *
+ * If CONFLICT_OPTIONS doesn't list an option, look in DEFAULT_OPTIONS for a
+ * description instead.
+ *
  * If the answer is the (globally recognized) 'help' option, then display
  * the help (on stderr) and return with *OPT == NULL.
  */
 static svn_error_t *
 prompt_user(const resolver_option_t **opt,
             const resolver_option_t *conflict_options,
+            apr_array_header_t *default_options,
             const char *const *options_to_show,
             void *prompt_baton,
             apr_pool_t *scratch_pool)
@@ -688,9 +696,11 @@ prompt_user(const resolver_option_t **op
   SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, prompt_baton, scratch_pool));
   if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
     {
-      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n",
-                                  help_string(conflict_options,
-                                              scratch_pool)));
+      const char *helpstr;
+
+      SVN_ERR(help_string(&helpstr, conflict_options, default_options,
+                          scratch_pool));
+      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n", helpstr));
       *opt = NULL;
     }
   else
@@ -714,7 +724,7 @@ handle_text_conflict(svn_client_conflict
                      svn_boolean_t *save_merged,
                      svn_cl__accept_t *accept_which,
                      svn_boolean_t *quit,
-                     const svn_client_conflict_t *conflict,
+                     svn_client_conflict_t *conflict,
                      const char *path_prefix,
                      svn_cmdline_prompt_baton_t *pb,
                      const char *editor_cmd,
@@ -739,6 +749,7 @@ handle_text_conflict(svn_client_conflict
   const char *my_abspath;
   const char *their_abspath;
   const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+  apr_array_header_t *default_options;
 
   SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
                                                 &base_abspath, &their_abspath,
@@ -771,6 +782,10 @@ handle_text_conflict(svn_client_conflict
       || (!base_abspath && my_abspath && their_abspath)))
     diff_allowed = TRUE;
 
+  SVN_ERR(svn_client_conflict_text_get_resolution_options(&default_options,
+                                                          conflict,
+                                                          scratch_pool,
+                                                          scratch_pool));
   while (TRUE)
     {
       const char *options[1 + MAX_ARRAY_LEN(binary_conflict_options,
@@ -819,7 +834,8 @@ handle_text_conflict(svn_client_conflict
       *next_option++ = "s";
       *next_option++ = NULL;
 
-      SVN_ERR(prompt_user(&opt, conflict_options, options, pb, iterpool));
+      SVN_ERR(prompt_user(&opt, conflict_options, default_options, options, pb,
+                          iterpool));
       if (! opt)
         continue;
 
@@ -832,9 +848,12 @@ handle_text_conflict(svn_client_conflict
         }
       else if (strcmp(opt->code, "s") == 0)
         {
+          const char *helpstr;
+
+          SVN_ERR(help_string(&helpstr, conflict_options, default_options,
+                              iterpool));
           SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n",
-                                      help_string(conflict_options,
-                                                  iterpool)));
+                                      helpstr));
         }
       else if (strcmp(opt->code, "dc") == 0)
         {
@@ -1056,7 +1075,7 @@ handle_prop_conflict(svn_client_conflict
                      svn_cmdline_prompt_baton_t *pb,
                      const char *editor_cmd,
                      apr_hash_t *config,
-                     const svn_client_conflict_t *conflict,
+                     svn_client_conflict_t *conflict,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
@@ -1067,6 +1086,7 @@ handle_prop_conflict(svn_client_conflict
   const svn_string_t *base_propval;
   const svn_string_t *my_propval;
   const svn_string_t *their_propval;
+  apr_array_header_t *default_options;
 
   SVN_ERR(svn_client_conflict_prop_get_propvals(NULL, &my_propval,
                                                 &base_propval, &their_propval,
@@ -1086,6 +1106,10 @@ handle_prop_conflict(svn_client_conflict
                                                                scratch_pool));
   SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n", message));
 
+  SVN_ERR(svn_client_conflict_prop_get_resolution_options(&default_options,
+                                                          conflict,
+                                                          scratch_pool,
+                                                          scratch_pool));
   iterpool = svn_pool_create(scratch_pool);
   while (TRUE)
     {
@@ -1106,8 +1130,8 @@ handle_prop_conflict(svn_client_conflict
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(prompt_user(&opt, prop_conflict_options, options, pb,
-                          iterpool));
+      SVN_ERR(prompt_user(&opt, prop_conflict_options, default_options,
+                          options, pb, iterpool));
       if (! opt)
         continue;
 
@@ -1166,7 +1190,7 @@ static svn_error_t *
 handle_tree_conflict(svn_client_conflict_option_id_t *option_id,
                      svn_cl__accept_t *accept_which,
                      svn_boolean_t *quit,
-                     const svn_client_conflict_t *conflict,
+                     svn_client_conflict_t *conflict,
                      const char *path_prefix,
                      svn_cmdline_prompt_baton_t *pb,
                      apr_pool_t *scratch_pool)
@@ -1178,6 +1202,7 @@ handle_tree_conflict(svn_client_conflict
   const char *repos_relpath;
   svn_revnum_t peg_rev;
   svn_node_kind_t node_kind;
+  apr_array_header_t *default_options;
   apr_pool_t *iterpool;
   
   SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
@@ -1217,6 +1242,10 @@ handle_tree_conflict(svn_client_conflict
     SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
                                 _("Source right"), src_right_version));
 
+  SVN_ERR(svn_client_conflict_tree_get_resolution_options(&default_options,
+                                                          conflict,
+                                                          scratch_pool,
+                                                          scratch_pool));
   iterpool = svn_pool_create(scratch_pool);
   while (1)
     {
@@ -1250,7 +1279,7 @@ handle_tree_conflict(svn_client_conflict
             }
         }
 
-      SVN_ERR(prompt_user(&opt, tc_opts, NULL, pb, iterpool));
+      SVN_ERR(prompt_user(&opt, tc_opts, default_options, NULL, pb, iterpool));
       if (! opt)
         continue;
 
@@ -1272,7 +1301,6 @@ handle_tree_conflict(svn_client_conflict
   return SVN_NO_ERROR;
 }
 
-/* The body of svn_cl__conflict_func_interactive(). */
 static svn_error_t *
 conflict_func_interactive(svn_client_conflict_option_id_t *option_id,
                           svn_boolean_t *save_merged,
@@ -1281,7 +1309,7 @@ conflict_func_interactive(svn_client_con
                           svn_boolean_t *quit,
                           svn_boolean_t *external_failed,
                           svn_boolean_t *printed_summary,
-                          const svn_client_conflict_t *conflict,
+                          svn_client_conflict_t *conflict,
                           const char *editor_cmd,
                           apr_hash_t *config,
                           const char *path_prefix,
@@ -1499,48 +1527,6 @@ conflict_option_id_to_wc_conflict_choice
 }
 
 svn_error_t *
-svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
-                                  const svn_wc_conflict_description2_t *desc,
-                                  void *baton,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool)
-{
-  svn_cl__interactive_conflict_baton_t *b = baton;
-  svn_client_conflict_t *conflict;
-  svn_client_conflict_option_id_t option_id;
-  svn_boolean_t save_merged = FALSE;
-  const svn_string_t *merged_propval = NULL;
-
-  SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc,
-                                                     scratch_pool,
-                                                     scratch_pool));
-  *result = svn_wc_create_conflict_result(svn_client_conflict_option_postpone,
-                                          NULL, result_pool);
-  SVN_ERR(conflict_func_interactive(&option_id, &save_merged, &merged_propval,
-                                    &b->accept_which, &b->quit,
-                                    &b->external_failed, &b->printed_summary,
-                                    conflict, b->editor_cmd, b->config,
-                                    b->path_prefix, b->pb, b->conflict_stats,
-                                    result_pool, scratch_pool));
-  (*result)->choice = conflict_option_id_to_wc_conflict_choice(option_id);
-  (*result)->save_merged = save_merged;
-  (*result)->merged_value = merged_propval;
-
-  /* If we are resolving a conflict, adjust the summary of conflicts. */
-  if (option_id != svn_client_conflict_option_postpone)
-    {
-      const char *local_path
-        = svn_cl__local_style_skip_ancestor(
-            b->path_prefix, svn_client_conflict_get_local_abspath(conflict),
-            scratch_pool);
-
-      svn_cl__conflict_stats_resolved(b->conflict_stats, local_path,
-                                      svn_client_conflict_get_kind(conflict));
-    }
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_cl__resolve_conflict(svn_boolean_t *resolved,
                          svn_cl__accept_t *accept_which,
                          svn_boolean_t *quit,

Modified: subversion/branches/parallel-put/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/merge-cmd.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/parallel-put/subversion/svn/merge-cmd.c Thu Jan 21 21:39:22 2016
@@ -145,6 +145,84 @@ run_merge(svn_boolean_t two_sources_spec
   return merge_err;
 }
 
+/* Baton type for conflict_func_merge_cmd(). */
+struct conflict_func_merge_cmd_baton {
+  svn_cl__accept_t accept_which;
+  const char *path_prefix;
+  svn_cl__conflict_stats_t *conflict_stats;
+};
+
+/* This implements the `svn_wc_conflict_resolver_func2_t ' interface.
+ *
+ * The merge subcommand needs to install this legacy conflict callback
+ * in case the user passed an --accept option to 'svn merge'.
+ * Otherwise, merges involving multiple editor drives might encounter a
+ * conflict during one of the editor drives and abort with an error,
+ * rather than resolving conflicts as per the --accept option and
+ * continuing with the next editor drive.
+ * ### TODO add an svn_client_merge API that makes this callback unnecessary
+ */
+static svn_error_t *
+conflict_func_merge_cmd(svn_wc_conflict_result_t **result,
+                        const svn_wc_conflict_description2_t *desc,
+                        void *baton,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
+{
+  struct conflict_func_merge_cmd_baton *b = baton;
+  svn_wc_conflict_choice_t choice;
+
+  switch (b->accept_which)
+    {
+    case svn_cl__accept_postpone:
+    case svn_cl__accept_invalid:
+    case svn_cl__accept_unspecified:
+      /* Postpone or no valid --accept option, postpone the conflict. */
+      choice = svn_wc_conflict_choose_postpone;
+      break;
+    case svn_cl__accept_base:
+      choice = svn_wc_conflict_choose_base;
+      break;
+    case svn_cl__accept_working:
+      choice = svn_wc_conflict_choose_merged;
+      break;
+    case svn_cl__accept_mine_conflict:
+      choice = svn_wc_conflict_choose_mine_conflict;
+      break;
+    case svn_cl__accept_theirs_conflict:
+      choice = svn_wc_conflict_choose_theirs_conflict;
+      break;
+    case svn_cl__accept_mine_full:
+      choice = svn_wc_conflict_choose_mine_full;
+      break;
+    case svn_cl__accept_theirs_full:
+      choice = svn_wc_conflict_choose_theirs_full;
+      break;
+    case svn_cl__accept_edit:
+    case svn_cl__accept_launch:
+      /* The 'edit' and 'launch' options used to be valid in Subversion 1.9 but
+       * we can't support these options for the purposes of this callback. */
+      choice = svn_wc_conflict_choose_postpone;
+      break;
+    }
+
+  *result = svn_wc_create_conflict_result(choice, NULL, result_pool);
+
+  /* If we are resolving a conflict, adjust the summary of conflicts. */
+  if (choice != svn_wc_conflict_choose_postpone)
+    {
+      const char *local_path;
+
+      local_path = svn_cl__local_style_skip_ancestor(b->path_prefix,
+                                                     desc->local_abspath,
+                                                     scratch_pool);
+      svn_cl__conflict_stats_resolved(b->conflict_stats, local_path,
+                                      desc->kind);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
 svn_cl__merge(apr_getopt_t *os,
@@ -152,6 +230,8 @@ svn_cl__merge(apr_getopt_t *os,
               apr_pool_t *pool)
 {
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_cl__conflict_stats_t *conflict_stats =
+    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
   const char *sourcepath1 = NULL, *sourcepath2 = NULL, *targetpath = "";
@@ -160,6 +240,7 @@ 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;
+  apr_array_header_t *conflicted_paths;
   svn_boolean_t has_explicit_target = FALSE;
 
   /* Merge doesn't support specifying a revision or revision range
@@ -427,6 +508,21 @@ svn_cl__merge(apr_getopt_t *os,
                                   "with --reintegrate"));
     }
 
+  /* Install a legacy conflict handler if the --accept option was given.
+   * Else, svn_client_merge5() may abort the merge in an undesirable way.
+   * See the docstring at conflict_func_merge_cmd() for details */
+  if (opt_state->accept_which != svn_cl__accept_unspecified)
+    {
+      struct conflict_func_merge_cmd_baton *b = apr_pcalloc(pool, sizeof(*b));
+
+      b->accept_which = opt_state->accept_which;
+      SVN_ERR(svn_dirent_get_absolute(&b->path_prefix, "", pool));
+      b->conflict_stats = conflict_stats;
+
+      ctx->conflict_func2 = conflict_func_merge_cmd;
+      ctx->conflict_baton2 = b;
+    }
+
   merge_err = run_merge(two_sources_specified,
                         sourcepath1, peg_revision1,
                         sourcepath2,
@@ -442,6 +538,13 @@ svn_cl__merge(apr_getopt_t *os,
                  "fix invalid mergeinfo in target with 'svn propset'"));
     }
 
+  /* Run the interactive resolver if conflicts were raised. */
+  SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats,
+                                           pool, pool));
+  if (conflicted_paths)
+    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, FALSE,
+                                   opt_state, ctx, pool));
+
   if (!opt_state->quiet)
     {
       svn_error_t *err = svn_cl__notifier_print_conflict_stats(

Modified: subversion/branches/parallel-put/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/notify.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/notify.c (original)
+++ subversion/branches/parallel-put/subversion/svn/notify.c Thu Jan 21 21:39:22 2016
@@ -39,6 +39,7 @@
 #include "svn_hash.h"
 #include "cl.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_sorts_private.h"
 #include "private/svn_dep_compat.h"
 
 #include "svn_private_config.h"
@@ -145,6 +146,76 @@ resolved_str(apr_pool_t *pool, int n_res
 }
 
 svn_error_t *
+svn_cl__conflict_stats_get_paths(apr_array_header_t **conflicted_paths,
+                                 svn_cl__conflict_stats_t *conflict_stats,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
+{
+
+  int n_text = apr_hash_count(conflict_stats->text_conflicts);
+  int n_prop = apr_hash_count(conflict_stats->prop_conflicts);
+  int n_tree = apr_hash_count(conflict_stats->tree_conflicts);
+  apr_hash_t *all_conflicts;
+
+  *conflicted_paths = NULL;
+  if (n_text == 0 && n_prop == 0 && n_tree == 0)
+      return SVN_NO_ERROR;
+
+  /* Use a hash table to ensure paths with multiple conflicts are
+   * returned just once. */
+  all_conflicts = apr_hash_make(result_pool);
+  if (n_text > 0)
+    {
+      apr_array_header_t *k_text;
+      int i;
+
+      SVN_ERR(svn_hash_keys(&k_text, conflict_stats->text_conflicts,
+                            scratch_pool));
+      for (i = 0; i < k_text->nelts; i++)
+        {
+          const char *path = APR_ARRAY_IDX(k_text, i, const char *);
+
+          svn_hash_sets(all_conflicts, path, "");
+        }
+    }
+
+  if (n_prop > 0)
+    {
+      apr_array_header_t *k_prop;
+      int i;
+
+      SVN_ERR(svn_hash_keys(&k_prop, conflict_stats->prop_conflicts,
+                            scratch_pool));
+      for (i = 0; i < k_prop->nelts; i++)
+        {
+          const char *path = APR_ARRAY_IDX(k_prop, i, const char *);
+
+          svn_hash_sets(all_conflicts, path, "");
+        }
+    }
+
+  if (n_tree > 0)
+    {
+      apr_array_header_t *k_tree;
+      int i;
+
+      SVN_ERR(svn_hash_keys(&k_tree, conflict_stats->tree_conflicts,
+                            scratch_pool));
+      for (i = 0; i < k_tree->nelts; i++)
+        {
+          const char *path = APR_ARRAY_IDX(k_tree, i, const char *);
+
+          svn_hash_sets(all_conflicts, path, "");
+        }
+    }
+
+  svn_hash_keys(conflicted_paths, all_conflicts, result_pool);
+  svn_sort__array(*conflicted_paths, svn_sort_compare_paths);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats,
                              apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/parallel-put/subversion/svn/resolve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/resolve-cmd.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/resolve-cmd.c (original)
+++ subversion/branches/parallel-put/subversion/svn/resolve-cmd.c Thu Jan 21 21:39:22 2016
@@ -292,84 +292,74 @@ walk_conflicts(svn_client_ctx_t *ctx,
   return SVN_NO_ERROR;
 }
 
-/* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
-svn_cl__resolve(apr_getopt_t *os,
-                void *baton,
-                apr_pool_t *scratch_pool)
+svn_cl__walk_conflicts(apr_array_header_t *targets,
+                       svn_cl__conflict_stats_t *conflict_stats,
+                       svn_boolean_t is_resolve_cmd,
+                       svn_cl__opt_state_t *opt_state,
+                       svn_client_ctx_t *ctx,
+                       apr_pool_t *scratch_pool)
 {
-  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
-  svn_cl__conflict_stats_t *conflict_stats =
-    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
-  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
-  svn_client_conflict_option_id_t option_id;
-  svn_error_t *err;
-  apr_array_header_t *targets;
-  const char *path_prefix;
-  int i;
-  apr_pool_t *iterpool;
   svn_boolean_t had_error = FALSE;
   svn_boolean_t quit = FALSE;
   svn_boolean_t external_failed = FALSE;
   svn_boolean_t printed_summary = FALSE;
+  svn_client_conflict_option_id_t option_id;
   svn_cmdline_prompt_baton_t *pb = apr_palloc(scratch_pool, sizeof(*pb));
+  const char *path_prefix;
+  svn_error_t *err;
+  int i;
+  apr_pool_t *iterpool;
+
+  SVN_ERR(svn_dirent_get_absolute(&path_prefix, "", scratch_pool));
 
   pb->cancel_func = ctx->cancel_func;
   pb->cancel_baton = ctx->cancel_baton;
 
-  option_id = svn_client_conflict_option_unspecified;
-
-  SVN_ERR(svn_dirent_get_absolute(&path_prefix, "", scratch_pool));
-
   switch (opt_state->accept_which)
     {
     case svn_cl__accept_working:
-      option_id = svn_wc_conflict_choose_merged;
+      option_id = svn_client_conflict_option_merged_text;
       break;
     case svn_cl__accept_base:
-      option_id = svn_wc_conflict_choose_base;
+      option_id = svn_client_conflict_option_base_text;
       break;
     case svn_cl__accept_theirs_conflict:
-      option_id = svn_wc_conflict_choose_theirs_conflict;
+      option_id = svn_client_conflict_option_incoming_text_where_conflicted;
       break;
     case svn_cl__accept_mine_conflict:
-      option_id = svn_wc_conflict_choose_mine_conflict;
+      option_id = svn_client_conflict_option_working_text_where_conflicted;
       break;
     case svn_cl__accept_theirs_full:
-      option_id = svn_wc_conflict_choose_theirs_full;
+      option_id = svn_client_conflict_option_incoming_text;
       break;
     case svn_cl__accept_mine_full:
-      option_id = svn_wc_conflict_choose_mine_full;
+      option_id = svn_client_conflict_option_working_text;
       break;
     case svn_cl__accept_unspecified:
-      if (opt_state->non_interactive)
+      if (is_resolve_cmd && opt_state->non_interactive)
         return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("missing --accept option"));
-      option_id = svn_wc_conflict_choose_unspecified;
+      option_id = svn_client_conflict_option_unspecified;
+      break;
+    case svn_cl__accept_postpone:
+      if (is_resolve_cmd)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("invalid 'accept' ARG"));
+      option_id = svn_client_conflict_option_postpone;
+      break;
+    case svn_cl__accept_edit:
+    case svn_cl__accept_launch:
+      if (is_resolve_cmd)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("invalid 'accept' ARG"));
+      option_id = svn_client_conflict_option_unspecified;
       break;
     default:
       return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                               _("invalid 'accept' ARG"));
     }
 
-  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
-                                                      opt_state->targets,
-                                                      ctx, FALSE,
-                                                      scratch_pool));
-  if (! targets->nelts)
-    svn_opt_push_implicit_dot_target(targets, scratch_pool);
-
-  if (opt_state->depth == svn_depth_unknown)
-    {
-      if (opt_state->accept_which == svn_cl__accept_unspecified)
-        opt_state->depth = svn_depth_infinity;
-      else
-        opt_state->depth = svn_depth_empty;
-    }
-
-  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
-
-  SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
 
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < targets->nelts; i++)
@@ -422,6 +412,42 @@ svn_cl__resolve(apr_getopt_t *os,
     return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Failure occurred resolving one or more "
                               "conflicts"));
+  return SVN_NO_ERROR;
+}
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__resolve(apr_getopt_t *os,
+                void *baton,
+                apr_pool_t *scratch_pool)
+{
+  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_cl__conflict_stats_t *conflict_stats =
+    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
+  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+  apr_array_header_t *targets;
+
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE,
+                                                      scratch_pool));
+  if (! targets->nelts)
+    svn_opt_push_implicit_dot_target(targets, scratch_pool);
+
+  if (opt_state->depth == svn_depth_unknown)
+    {
+      if (opt_state->accept_which == svn_cl__accept_unspecified)
+        opt_state->depth = svn_depth_infinity;
+      else
+        opt_state->depth = svn_depth_empty;
+    }
+
+  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
+
+  SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
+
+  SVN_ERR(svn_cl__walk_conflicts(targets, conflict_stats, TRUE,
+                                 opt_state, ctx, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/parallel-put/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/svn.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/svn.c (original)
+++ subversion/branches/parallel-put/subversion/svn/svn.c Thu Jan 21 21:39:22 2016
@@ -3035,20 +3035,12 @@ sub_main(int *exit_code, int argc, const
         opt_state.accept_which = svn_cl__accept_postpone;
     }
 
-  /* Install the default conflict handler. */
+  /* We don't use legacy libsvn_wc conflict handlers by default. */
   {
-    svn_cl__interactive_conflict_baton_t *b;
-
     ctx->conflict_func = NULL;
     ctx->conflict_baton = NULL;
-
-    ctx->conflict_func2 = svn_cl__conflict_func_interactive;
-    SVN_ERR(svn_cl__get_conflict_func_interactive_baton(
-                &b,
-                opt_state.accept_which,
-                ctx->config, opt_state.editor_cmd, conflict_stats,
-                ctx->cancel_func, ctx->cancel_baton, pool));
-    ctx->conflict_baton2 = b;
+    ctx->conflict_func2 = NULL;
+    ctx->conflict_baton2 = NULL;
   }
 
   /* And now we finally run the subcommand. */

Modified: subversion/branches/parallel-put/subversion/svn/switch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/switch-cmd.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/switch-cmd.c (original)
+++ subversion/branches/parallel-put/subversion/svn/switch-cmd.c Thu Jan 21 21:39:22 2016
@@ -96,8 +96,11 @@ svn_cl__switch(apr_getopt_t *os,
   svn_error_t *err = SVN_NO_ERROR;
   svn_error_t *externals_err = SVN_NO_ERROR;
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_cl__conflict_stats_t *conflict_stats =
+    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
+  apr_array_header_t *conflicted_paths;
   const char *target, *switch_url;
   svn_opt_revision_t peg_revision;
   svn_depth_t depth;
@@ -188,6 +191,13 @@ svn_cl__switch(apr_getopt_t *os,
                                      _("Failure occurred processing one or "
                                        "more externals definitions"));
 
+  /* Run the interactive resolver if conflicts were raised. */
+  SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats,
+                                           scratch_pool, scratch_pool));
+  if (conflicted_paths)
+    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, FALSE,
+                                   opt_state, ctx, scratch_pool));
+
   if (! opt_state->quiet)
     {
       err = svn_cl__notifier_print_conflict_stats(nwb.wrapped_baton, scratch_pool);

Modified: subversion/branches/parallel-put/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svn/update-cmd.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svn/update-cmd.c (original)
+++ subversion/branches/parallel-put/subversion/svn/update-cmd.c Thu Jan 21 21:39:22 2016
@@ -111,12 +111,15 @@ svn_cl__update(apr_getopt_t *os,
                apr_pool_t *scratch_pool)
 {
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_cl__conflict_stats_t *conflict_stats =
+    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
   svn_depth_t depth;
   svn_boolean_t depth_is_sticky;
   struct svn_cl__check_externals_failed_notify_baton nwb;
   apr_array_header_t *result_revs;
+  apr_array_header_t *conflicted_paths;
   svn_error_t *err = SVN_NO_ERROR;
   svn_error_t *externals_err = SVN_NO_ERROR;
 
@@ -177,6 +180,13 @@ svn_cl__update(apr_getopt_t *os,
                                      _("Failure occurred processing one or "
                                        "more externals definitions"));
 
+  /* Run the interactive resolver if conflicts were raised. */
+  SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats,
+                                           scratch_pool, scratch_pool));
+  if (conflicted_paths)
+    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, FALSE,
+                                   opt_state, ctx, scratch_pool));
+
   if (! opt_state->quiet)
     {
       err = print_update_summary(targets, result_revs, scratch_pool);

Modified: subversion/branches/parallel-put/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svnadmin/svnadmin.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/parallel-put/subversion/svnadmin/svnadmin.c Thu Jan 21 21:39:22 2016
@@ -126,6 +126,7 @@ open_repos(svn_repos_t **repos,
   apr_hash_t *fs_config = apr_hash_make(pool);
   svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_DELTAS, "1");
   svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS, "1");
+  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS, "1");
   svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS, "2");
   svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NS,
                            svn_uuid_generate(pool));

Modified: subversion/branches/parallel-put/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svnserve/serve.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svnserve/serve.c (original)
+++ subversion/branches/parallel-put/subversion/svnserve/serve.c Thu Jan 21 21:39:22 2016
@@ -1828,7 +1828,7 @@ get_dir(svn_ra_svn_conn_t *conn,
               entry_kind = fsent->kind;
 
           if (dirent_fields & SVN_DIRENT_SIZE)
-              if (entry_kind != svn_node_dir)
+              if (fsent->kind != svn_node_dir)
                 SVN_CMD_ERR(svn_fs_file_length(&entry_size, root, file_path,
                                                subpool));
 

Modified: subversion/branches/parallel-put/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/svnserve/svnserve.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/parallel-put/subversion/svnserve/svnserve.c Thu Jan 21 21:39:22 2016
@@ -221,6 +221,7 @@ void winservice_notify_stop(void)
 #define SVNSERVE_OPT_BLOCK_READ      273
 #define SVNSERVE_OPT_MAX_REQUEST     274
 #define SVNSERVE_OPT_MAX_RESPONSE    275
+#define SVNSERVE_OPT_CACHE_NODEPROPS 276
 
 /* Text macro because we can't use #ifdef sections inside a N_("...")
    macro expansion. */
@@ -318,6 +319,12 @@ static const apr_getopt_option_t svnserv
         "Default is no.\n"
         "                             "
         "[used for FSFS and FSX repositories only]")},
+    {"cache-nodeprops", SVNSERVE_OPT_CACHE_NODEPROPS, 1,
+     N_("enable or disable caching of node properties\n"
+        "                             "
+        "Default is yes.\n"
+        "                             "
+        "[used for FSFS repositories only]")},
     {"client-speed", SVNSERVE_OPT_CLIENT_SPEED, 1,
      N_("Optimize network handling based on the assumption\n"
         "                             "
@@ -714,6 +721,7 @@ sub_main(int *exit_code, int argc, const
   svn_boolean_t is_multi_threaded;
   enum connection_handling_mode handling_mode = CONNECTION_DEFAULT;
   svn_boolean_t cache_fulltexts = TRUE;
+  svn_boolean_t cache_nodeprops = TRUE;
   svn_boolean_t cache_txdeltas = TRUE;
   svn_boolean_t cache_revprops = FALSE;
   svn_boolean_t use_block_read = FALSE;
@@ -906,6 +914,10 @@ sub_main(int *exit_code, int argc, const
           cache_revprops = svn_tristate__from_word(arg) == svn_tristate_true;
           break;
 
+        case SVNSERVE_OPT_CACHE_NODEPROPS:
+          cache_nodeprops = svn_tristate__from_word(arg) == svn_tristate_true;
+          break;
+
         case SVNSERVE_OPT_BLOCK_READ:
           use_block_read = svn_tristate__from_word(arg) == svn_tristate_true;
           break;
@@ -1024,6 +1036,8 @@ sub_main(int *exit_code, int argc, const
                 cache_txdeltas ? "1" :"0");
   svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
                 cache_fulltexts ? "1" :"0");
+  svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+                cache_nodeprops ? "1" :"0");
   svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                 cache_revprops ? "2" :"0");
   svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ,