You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by iv...@apache.org on 2015/09/11 17:51:34 UTC

svn commit: r1702504 [16/19] - in /subversion/branches/reuse-ra-session: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ notes/ subversion/bindings/ctypes-python/csvn/ext/ subversion/bindings/javahl/native/ ...

Modified: subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c Fri Sep 11 15:51:30 2015
@@ -128,9 +128,10 @@ svn_cl__accept_from_word(const char *wor
 
 
 /* Print on stdout a diff that shows incoming conflicting changes
- * corresponding to the conflict described in DESC. */
+ * corresponding to the conflict described in CONFLICT. */
 static svn_error_t *
-show_diff(const svn_wc_conflict_description2_t *desc,
+show_diff(const svn_client_conflict_t *conflict,
+          const char *merged_abspath,
           const char *path_prefix,
           svn_cancel_func_t cancel_func,
           void *cancel_baton,
@@ -141,10 +142,13 @@ show_diff(const svn_wc_conflict_descript
   svn_diff_t *diff;
   svn_stream_t *output;
   svn_diff_file_options_t *options;
-  const char *merged_file;
+  const char *my_abspath;
+  const char *their_abspath;
 
-  merged_file = svn_client_conflict_get_merged_file(desc);
-  if (merged_file)
+  SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath, NULL,
+                                                &their_abspath,
+                                                conflict, pool, pool));
+  if (merged_abspath)
     {
       /* For conflicts recorded by the 'merge' operation, show a diff between
        * 'mine' (the working version of the file as it appeared before the
@@ -158,26 +162,26 @@ show_diff(const svn_wc_conflict_descript
        *
        * This way, the diff is always minimal and clearly identifies changes
        * brought into the working copy by the update/switch/merge operation. */
-      if (svn_client_conflict_get_operation(desc) == svn_wc_operation_merge)
+      if (svn_client_conflict_get_operation(conflict) == svn_wc_operation_merge)
         {
-          path1 = svn_client_conflict_get_my_abspath(desc);
+          path1 = my_abspath;
           label1 = _("MINE");
         }
       else
         {
-          path1 = svn_client_conflict_get_their_abspath(desc);
+          path1 = their_abspath;
           label1 = _("THEIRS");
         }
-      path2 = merged_file;
+      path2 = merged_abspath;
       label2 = _("MERGED");
     }
   else
     {
       /* There's no merged file, but we can show the
          difference between mine and theirs. */
-      path1 = svn_client_conflict_get_their_abspath(desc);
+      path1 = their_abspath;
       label1 = _("THEIRS");
-      path2 = svn_client_conflict_get_my_abspath(desc);
+      path2 = my_abspath;
       label2 = _("MINE");
     }
 
@@ -206,9 +210,9 @@ show_diff(const svn_wc_conflict_descript
 
 
 /* Print on stdout just the conflict hunks of a diff among the 'base', 'their'
- * and 'my' files of DESC. */
+ * and 'my' files of CONFLICT. */
 static svn_error_t *
-show_conflicts(const svn_wc_conflict_description2_t *desc,
+show_conflicts(const svn_client_conflict_t *conflict,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                apr_pool_t *pool)
@@ -216,22 +220,22 @@ show_conflicts(const svn_wc_conflict_des
   svn_diff_t *diff;
   svn_stream_t *output;
   svn_diff_file_options_t *options;
-
+  const char *base_abspath;
+  const char *my_abspath;
+  const char *their_abspath;
+
+  SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                &base_abspath, &their_abspath,
+                                                conflict, pool, pool));
   options = svn_diff_file_options_create(pool);
   options->ignore_eol_style = TRUE;
   SVN_ERR(svn_stream_for_stdout(&output, pool));
-  SVN_ERR(svn_diff_file_diff3_2(&diff,
-                                svn_client_conflict_get_base_abspath(desc),
-                                svn_client_conflict_get_my_abspath(desc),
-                                svn_client_conflict_get_their_abspath(desc),
+  SVN_ERR(svn_diff_file_diff3_2(&diff, base_abspath, my_abspath, their_abspath,
                                 options, pool));
   /* ### Consider putting the markers/labels from
      ### svn_wc__merge_internal in the conflict description. */
   return svn_diff_file_output_merge3(
-           output, diff,
-           svn_client_conflict_get_base_abspath(desc),
-           svn_client_conflict_get_my_abspath(desc),
-           svn_client_conflict_get_their_abspath(desc),
+           output, diff, base_abspath, my_abspath, their_abspath,
            _("||||||| ORIGINAL"),
            _("<<<<<<< MINE (select with 'mc')"),
            _(">>>>>>> THEIRS (select with 'tc')"),
@@ -245,61 +249,49 @@ show_conflicts(const svn_wc_conflict_des
 /* Perform a 3-way merge of the conflicting values of a property,
  * and write the result to the OUTPUT stream.
  *
- * If MERGED_ABSPATH is non-NULL, use it as 'my' version instead of
- * DESC->MY_ABSPATH.
+ * If MERGED_PROPVAL is non-NULL, use it as 'my' version instead of
+ * MY_ABSPATH.
  *
  * Assume the values are printable UTF-8 text.
  */
 static svn_error_t *
 merge_prop_conflict(svn_stream_t *output,
-                    const svn_wc_conflict_description2_t *desc,
-                    const char *merged_abspath,
+                    const svn_string_t *base_propval,
+                    const svn_string_t *my_propval,
+                    const svn_string_t *their_propval,
+                    const svn_string_t *merged_propval,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *pool)
 {
-  const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
-  const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
-  const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
   svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
   svn_diff_t *diff;
 
-  /* If any of the property values is missing, use an empty file instead
+  /* If any of the property values is missing, use an empty value instead
    * for the purpose of showing a diff. */
-  if (! base_abspath || ! my_abspath || ! their_abspath)
-    {
-      const char *empty_file;
-
-      SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file,
-                                       NULL, svn_io_file_del_on_pool_cleanup,
-                                       pool, pool));
-      if (! base_abspath)
-        base_abspath = empty_file;
-      if (! my_abspath)
-        my_abspath = empty_file;
-      if (! their_abspath)
-        their_abspath = empty_file;
-    }
-
+  if (base_propval == NULL)
+    base_propval = svn_string_create_empty(pool);
+  if (my_propval == NULL)
+    my_propval = svn_string_create_empty(pool);
+  if (my_propval == NULL)
+    my_propval = svn_string_create_empty(pool);
+    
   options->ignore_eol_style = TRUE;
-  SVN_ERR(svn_diff_file_diff3_2(&diff,
-                                base_abspath,
-                                merged_abspath ? merged_abspath : my_abspath,
-                                their_abspath,
-                                options, pool));
-  SVN_ERR(svn_diff_file_output_merge3(output, diff,
-                                      base_abspath,
-                                      merged_abspath ? merged_abspath
-                                                     : my_abspath,
-                                      their_abspath,
-                                      _("||||||| ORIGINAL"),
-                                      _("<<<<<<< MINE"),
-                                      _(">>>>>>> THEIRS"),
-                                      "=======",
-                                      svn_diff_conflict_display_modified_original_latest,
-                                      cancel_func,
-                                      cancel_baton,
-                                      pool));
+  SVN_ERR(svn_diff_mem_string_diff3(&diff, base_propval,
+                                    merged_propval ?
+                                      merged_propval : my_propval,
+                                    their_propval, options, pool));
+  SVN_ERR(svn_diff_mem_string_output_merge3(
+            output, diff, base_propval,
+            merged_propval ? merged_propval : my_propval, their_propval,
+            _("||||||| ORIGINAL"),
+            _("<<<<<<< MINE"),
+            _(">>>>>>> THEIRS"),
+            "=======",
+            svn_diff_conflict_display_modified_original_latest,
+            cancel_func,
+            cancel_baton,
+            pool));
 
   return SVN_NO_ERROR;
 }
@@ -312,8 +304,10 @@ merge_prop_conflict(svn_stream_t *output
  * Assume the values are printable UTF-8 text.
  */
 static svn_error_t *
-show_prop_conflict(const svn_wc_conflict_description2_t *desc,
-                   const char *merged_abspath,
+show_prop_conflict(const svn_string_t *base_propval,
+                   const svn_string_t *my_propval,
+                   const svn_string_t *their_propval,
+                   const svn_string_t *merged_propval,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *pool)
@@ -321,13 +315,13 @@ show_prop_conflict(const svn_wc_conflict
   svn_stream_t *output;
 
   SVN_ERR(svn_stream_for_stdout(&output, pool));
-  SVN_ERR(merge_prop_conflict(output, desc, merged_abspath,
-                              cancel_func, cancel_baton, pool));
+  SVN_ERR(merge_prop_conflict(output, base_propval, my_propval, their_propval,
+                              merged_propval, cancel_func, cancel_baton, pool));
 
   return SVN_NO_ERROR;
 }
 
-/* Run an external editor, passing it the MERGED_FILE, or, if the
+/* Run an external editor, passing it the MERGED_ABSPATH, or, if the
  * 'merged' file is null, return an error. The tool to use is determined by
  * B->editor_cmd, B->config and environment variables; see
  * svn_cl__edit_file_externally() for details.
@@ -338,15 +332,15 @@ show_prop_conflict(const svn_wc_conflict
  * return that error. */
 static svn_error_t *
 open_editor(svn_boolean_t *performed_edit,
-            const char *merged_file,
+            const char *merged_abspath,
             svn_cl__interactive_conflict_baton_t *b,
             apr_pool_t *pool)
 {
   svn_error_t *err;
 
-  if (merged_file)
+  if (merged_abspath)
     {
-      err = svn_cmdline__edit_file_externally(merged_file, b->editor_cmd,
+      err = svn_cmdline__edit_file_externally(merged_abspath, b->editor_cmd,
                                               b->config, pool);
       if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
                   err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
@@ -371,12 +365,16 @@ open_editor(svn_boolean_t *performed_edi
   return SVN_NO_ERROR;
 }
 
-/* Run an external editor, passing it the 'merged' property in DESC.
+/* Run an external editor on the merged property value with conflict markers.
+ * Return the edited result in *MERGED_PROPVAL.
+ * If the edit is aborted, set *MERGED_ABSPATH and *MERGED_PROPVAL to NULL.
  * The tool to use is determined by B->editor_cmd, B->config and
  * environment variables; see svn_cl__edit_file_externally() for details. */
 static svn_error_t *
-edit_prop_conflict(const char **merged_file_path,
-                   const svn_wc_conflict_description2_t *desc,
+edit_prop_conflict(const svn_string_t **merged_propval,
+                   const svn_string_t *base_propval,
+                   const svn_string_t *my_propval,
+                   const svn_string_t *their_propval,
                    svn_cl__interactive_conflict_baton_t *b,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
@@ -391,14 +389,23 @@ edit_prop_conflict(const char **merged_f
                                    result_pool, scratch_pool));
   merged_prop = svn_stream_from_aprfile2(file, TRUE /* disown */,
                                          scratch_pool);
-  SVN_ERR(merge_prop_conflict(merged_prop, desc, NULL,
+  SVN_ERR(merge_prop_conflict(merged_prop, base_propval, my_propval,
+                              their_propval, NULL,
                               b->pb->cancel_func,
                               b->pb->cancel_baton,
                               scratch_pool));
   SVN_ERR(svn_stream_close(merged_prop));
   SVN_ERR(svn_io_file_flush(file, scratch_pool));
   SVN_ERR(open_editor(&performed_edit, file_path, b, scratch_pool));
-  *merged_file_path = (performed_edit ? file_path : NULL);
+  if (performed_edit)
+    {
+      svn_stringbuf_t *buf;
+
+      SVN_ERR(svn_stringbuf_from_file2(&buf, file_path, scratch_pool));
+      *merged_propval = svn_string_create_from_buf(buf, result_pool); 
+    }
+  else
+    *merged_propval = NULL;
 
   return SVN_NO_ERROR;
 }
@@ -695,13 +702,13 @@ prompt_user(const resolver_option_t **op
   return SVN_NO_ERROR;
 }
 
-/* Ask the user what to do about the text conflict described by DESC.
+/* Ask the user what to do about the text conflict described by CONFLICT.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_text_conflict(svn_wc_conflict_result_t *result,
-                     const svn_wc_conflict_description2_t *desc,
+                     const svn_client_conflict_t *conflict,
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
@@ -715,15 +722,19 @@ handle_text_conflict(svn_wc_conflict_res
      give them a rational basis for choosing (r)esolved? */
   svn_boolean_t knows_something = FALSE;
   const char *local_relpath;
-  const char *local_abspath = svn_client_conflict_get_local_abspath(desc);
-  svn_boolean_t is_binary = svn_client_conflict_get_is_binary(desc);
-  const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
-  const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
-  const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
-  const char *merged_file = svn_client_conflict_get_merged_file(desc);
-
-  SVN_ERR_ASSERT(svn_client_conflict_get_kind(desc) ==
-                 svn_wc_conflict_kind_text);
+  const char *local_abspath = svn_client_conflict_get_local_abspath(conflict);
+  const char *mime_type = svn_client_conflict_text_get_mime_type(conflict);
+  svn_boolean_t is_binary = mime_type ? svn_mime_type_is_binary(mime_type)
+                                      : FALSE;
+  const char *base_abspath;
+  const char *my_abspath;
+  const char *their_abspath;
+  const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                &base_abspath, &their_abspath,
+                                                conflict, scratch_pool,
+                                                scratch_pool));
 
   local_relpath = svn_cl__local_style_skip_ancestor(b->path_prefix,
                                                     local_abspath,
@@ -747,7 +758,7 @@ handle_text_conflict(svn_wc_conflict_res
      scenario), or if no base is available, we can show a diff
      between mine and theirs. */
   if (!is_binary &&
-      ((merged_file && base_abspath)
+      ((merged_abspath && base_abspath)
       || (!base_abspath && my_abspath && their_abspath)))
     diff_allowed = TRUE;
 
@@ -833,7 +844,7 @@ handle_text_conflict(svn_wc_conflict_res
                                             "files not available.\n\n")));
               continue;
             }
-          SVN_ERR(show_conflicts(desc,
+          SVN_ERR(show_conflicts(conflict,
                                  b->pb->cancel_func,
                                  b->pb->cancel_baton,
                                  iterpool));
@@ -850,14 +861,14 @@ handle_text_conflict(svn_wc_conflict_res
               continue;
             }
 
-          SVN_ERR(show_diff(desc, b->path_prefix,
+          SVN_ERR(show_diff(conflict, merged_abspath, b->path_prefix,
                             b->pb->cancel_func, b->pb->cancel_baton,
                             iterpool));
           knows_something = TRUE;
         }
       else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
         {
-          SVN_ERR(open_editor(&performed_edit, merged_file, b, iterpool));
+          SVN_ERR(open_editor(&performed_edit, merged_abspath, b, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
@@ -878,7 +889,7 @@ handle_text_conflict(svn_wc_conflict_res
           err = svn_cl__merge_file_externally(base_abspath,
                                               their_abspath,
                                               my_abspath,
-                                              merged_file,
+                                              merged_abspath,
                                               local_abspath, b->config,
                                               NULL, iterpool);
           if (err)
@@ -893,7 +904,7 @@ handle_text_conflict(svn_wc_conflict_res
                                              base_abspath,
                                              their_abspath,
                                              my_abspath,
-                                             merged_file,
+                                             merged_abspath,
                                              local_abspath,
                                              b->path_prefix,
                                              b->editor_cmd,
@@ -931,9 +942,9 @@ handle_text_conflict(svn_wc_conflict_res
         {
           /* ### This check should be earlier as it's nasty to offer an option
            *     and then when the user chooses it say 'Invalid option'. */
-          /* ### 'merged_file' shouldn't be necessary *before* we launch the
+          /* ### 'merged_abspath' shouldn't be necessary *before* we launch the
            *     resolver: it should be the *result* of doing so. */
-          if (base_abspath && their_abspath && my_abspath && merged_file)
+          if (base_abspath && their_abspath && my_abspath && merged_abspath)
             {
               svn_error_t *err;
               char buf[1024];
@@ -942,7 +953,7 @@ handle_text_conflict(svn_wc_conflict_res
               err = svn_cl__merge_file_externally(base_abspath,
                                                   their_abspath,
                                                   my_abspath,
-                                                  merged_file,
+                                                  merged_abspath,
                                                   local_abspath,
                                                   b->config, NULL, iterpool);
               if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
@@ -973,7 +984,7 @@ handle_text_conflict(svn_wc_conflict_res
                                      base_abspath,
                                      their_abspath,
                                      my_abspath,
-                                     merged_file,
+                                     merged_abspath,
                                      local_abspath,
                                      b->path_prefix,
                                      b->editor_cmd,
@@ -1022,41 +1033,40 @@ handle_text_conflict(svn_wc_conflict_res
   return SVN_NO_ERROR;
 }
 
-/* Ask the user what to do about the property conflict described by DESC.
+/* Ask the user what to do about the property conflict described by CONFLICT.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_prop_conflict(svn_wc_conflict_result_t *result,
-                     const svn_wc_conflict_description2_t *desc,
+                     const svn_client_conflict_t *conflict,
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool;
   const char *message;
-  const char *merged_file_path = NULL;
+  const svn_string_t *merged_propval = NULL;
   svn_boolean_t resolved_allowed = FALSE;
-
-  /* ### Work around a historical bug in the provider: the path to the
-   *     conflict description file was put in the 'theirs' field, and
-   *     'theirs' was put in the 'merged' field. */
-  ((svn_wc_conflict_description2_t *)desc)->their_abspath = desc->merged_file;
-  ((svn_wc_conflict_description2_t *)desc)->merged_file = NULL;
-
-  SVN_ERR_ASSERT(svn_client_conflict_get_kind(desc) ==
-                 svn_wc_conflict_kind_property);
+  const svn_string_t *base_propval;
+  const svn_string_t *my_propval;
+  const svn_string_t *their_propval;
+
+  SVN_ERR(svn_client_conflict_prop_get_propvals(NULL, &my_propval,
+                                                &base_propval, &their_propval,
+                                                conflict, scratch_pool));
 
   SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
                               _("Conflict for property '%s' discovered"
                                 " on '%s'.\n"),
-                              svn_client_conflict_get_property_name(desc),
+                              svn_client_conflict_prop_get_propname(conflict),
                               svn_cl__local_style_skip_ancestor(
                                 b->path_prefix,
-                                svn_client_conflict_get_local_abspath(desc),
+                                svn_client_conflict_get_local_abspath(conflict),
                                 scratch_pool)));
 
-  SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message, desc,
+  SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message,
+                                                               conflict,
                                                                scratch_pool));
   SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n", message));
 
@@ -1094,15 +1104,17 @@ handle_prop_conflict(svn_wc_conflict_res
         }
       else if (strcmp(opt->code, "dc") == 0)
         {
-          SVN_ERR(show_prop_conflict(desc, merged_file_path,
+          SVN_ERR(show_prop_conflict(base_propval, my_propval, their_propval,
+                                     merged_propval,
                                      b->pb->cancel_func, b->pb->cancel_baton,
                                      scratch_pool));
         }
       else if (strcmp(opt->code, "e") == 0)
         {
-          SVN_ERR(edit_prop_conflict(&merged_file_path, desc, b,
-                                     result_pool, scratch_pool));
-          resolved_allowed = (merged_file_path != NULL);
+          SVN_ERR(edit_prop_conflict(&merged_propval,
+                                     base_propval, my_propval, their_propval,
+                                     b, result_pool, scratch_pool));
+          resolved_allowed = (merged_propval != NULL);
         }
       else if (strcmp(opt->code, "r") == 0)
         {
@@ -1114,7 +1126,7 @@ handle_prop_conflict(svn_wc_conflict_res
               continue;
             }
 
-          result->merged_file = merged_file_path;
+          result->merged_value = merged_propval;
           result->choice = svn_wc_conflict_choose_merged;
           break;
         }
@@ -1129,43 +1141,58 @@ handle_prop_conflict(svn_wc_conflict_res
   return SVN_NO_ERROR;
 }
 
-/* Ask the user what to do about the tree conflict described by DESC.
+/* Ask the user what to do about the tree conflict described by CONFLICT.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_tree_conflict(svn_wc_conflict_result_t *result,
-                     const svn_wc_conflict_description2_t *desc,
+                     const svn_client_conflict_t *conflict,
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
   const char *readable_desc;
   const char *src_left_version;
   const char *src_right_version;
+  const char *repos_root_url;
+  const char *repos_relpath;
+  svn_revnum_t peg_rev;
+  svn_node_kind_t node_kind;
   apr_pool_t *iterpool;
-
+  
   SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
-           &readable_desc, desc, scratch_pool));
+           &readable_desc, conflict, scratch_pool));
   SVN_ERR(svn_cmdline_fprintf(
                stderr, scratch_pool,
                _("Tree conflict on '%s'\n   > %s\n"),
                svn_cl__local_style_skip_ancestor(b->path_prefix,
-                 svn_client_conflict_get_local_abspath(desc), scratch_pool),
+                 svn_client_conflict_get_local_abspath(conflict), scratch_pool),
                readable_desc));
 
+  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
+                                             scratch_pool, scratch_pool));
+  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              scratch_pool,
+                                                              scratch_pool));
   src_left_version =
-              svn_cl__node_description(
-                svn_client_conflict_get_src_left_version(desc),
-                svn_client_conflict_get_src_left_version(desc)->repos_url,
-                scratch_pool);
+              svn_cl__node_description(repos_root_url, repos_relpath, peg_rev,
+                                       node_kind, repos_root_url, scratch_pool);
   if (src_left_version)
     SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
                                 _("Source  left"), src_left_version));
+
+  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              scratch_pool,
+                                                              scratch_pool));
   src_right_version =
-              svn_cl__node_description(
-                svn_client_conflict_get_src_right_version(desc),
-                svn_client_conflict_get_src_right_version(desc)->repos_url,
-                scratch_pool);
+              svn_cl__node_description(repos_root_url, repos_relpath, peg_rev,
+                                       node_kind, repos_root_url, scratch_pool);
   if (src_right_version)
     SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
                                 _("Source right"), src_right_version));
@@ -1180,12 +1207,14 @@ handle_tree_conflict(svn_wc_conflict_res
 
       tc_opts = tree_conflict_options;
 
-      if (svn_client_conflict_get_operation(desc) == svn_wc_operation_update ||
-          svn_client_conflict_get_operation(desc) == svn_wc_operation_switch)
+      if (svn_client_conflict_get_operation(conflict) ==
+          svn_wc_operation_update ||
+          svn_client_conflict_get_operation(conflict) ==
+          svn_wc_operation_switch)
         {
           svn_wc_conflict_reason_t reason;
 
-          reason = svn_client_conflict_get_local_change(desc);
+          reason = svn_client_conflict_get_local_change(conflict);
           if (reason == svn_wc_conflict_reason_moved_away)
             {
               tc_opts = tree_conflict_options_update_moved_away;
@@ -1193,9 +1222,10 @@ handle_tree_conflict(svn_wc_conflict_res
           else if (reason == svn_wc_conflict_reason_deleted ||
                    reason == svn_wc_conflict_reason_replaced)
             {
-              if (svn_client_conflict_get_incoming_change(desc) ==
+              if (svn_client_conflict_get_incoming_change(conflict) ==
                   svn_wc_conflict_action_edit &&
-                  svn_client_conflict_get_node_kind(desc) == svn_node_dir)
+                  svn_client_conflict_tree_get_victim_node_kind(conflict) ==
+                  svn_node_dir)
                 tc_opts = tree_conflict_options_update_edit_deleted_dir;
             }
         }
@@ -1225,17 +1255,24 @@ handle_tree_conflict(svn_wc_conflict_res
 /* The body of svn_cl__conflict_func_interactive(). */
 static svn_error_t *
 conflict_func_interactive(svn_wc_conflict_result_t **result,
-                          const svn_wc_conflict_description2_t *desc,
+                          const svn_client_conflict_t *conflict,
                           void *baton,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
   svn_cl__interactive_conflict_baton_t *b = baton;
   svn_error_t *err;
-  const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
-  const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
-  const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
-  const char *merged_file = svn_client_conflict_get_merged_file(desc);
+  const char *base_abspath = NULL;
+  const char *my_abspath = NULL;
+  const char *their_abspath = NULL;
+  const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_text)
+    SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                  &base_abspath,
+                                                  &their_abspath,
+                                                  conflict, scratch_pool,
+                                                  scratch_pool));
 
   /* Start out assuming we're going to postpone the conflict. */
   *result = svn_wc_create_conflict_result(svn_wc_conflict_choose_postpone,
@@ -1254,10 +1291,6 @@ conflict_func_interactive(svn_wc_conflic
       (*result)->choice = svn_wc_conflict_choose_base;
       return SVN_NO_ERROR;
     case svn_cl__accept_working:
-      /* If the caller didn't merge the property values, then I guess
-       * 'choose working' means 'choose mine'... */
-      if (! merged_file)
-        (*result)->merged_file = my_abspath;
       (*result)->choice = svn_wc_conflict_choose_merged;
       return SVN_NO_ERROR;
     case svn_cl__accept_mine_conflict:
@@ -1273,7 +1306,7 @@ conflict_func_interactive(svn_wc_conflic
       (*result)->choice = svn_wc_conflict_choose_theirs_full;
       return SVN_NO_ERROR;
     case svn_cl__accept_edit:
-      if (merged_file)
+      if (merged_abspath)
         {
           if (b->external_failed)
             {
@@ -1281,7 +1314,7 @@ conflict_func_interactive(svn_wc_conflic
               return SVN_NO_ERROR;
             }
 
-          err = svn_cmdline__edit_file_externally(merged_file,
+          err = svn_cmdline__edit_file_externally(merged_abspath,
                                                   b->editor_cmd, b->config,
                                                   scratch_pool);
           if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
@@ -1304,7 +1337,7 @@ conflict_func_interactive(svn_wc_conflic
       /* else, fall through to prompting. */
       break;
     case svn_cl__accept_launch:
-      if (base_abspath && their_abspath && my_abspath && merged_file)
+      if (base_abspath && their_abspath && my_abspath && merged_abspath)
         {
           svn_boolean_t remains_in_conflict;
           const char *local_abspath;
@@ -1315,11 +1348,11 @@ conflict_func_interactive(svn_wc_conflic
               return SVN_NO_ERROR;
             }
 
-          local_abspath = svn_client_conflict_get_local_abspath(desc);
+          local_abspath = svn_client_conflict_get_local_abspath(conflict);
           err = svn_cl__merge_file_externally(base_abspath,
                                               their_abspath,
                                               my_abspath,
-                                              merged_file,
+                                              merged_abspath,
                                               local_abspath,
                                               b->config,
                                               &remains_in_conflict,
@@ -1364,16 +1397,18 @@ conflict_func_interactive(svn_wc_conflic
      Conflicting edits on a file's text, or
      Conflicting edits on a property.
   */
-  if (((svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_text)
-       && (svn_client_conflict_get_incoming_change(desc) ==
+  if (((svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_text)
+       && (svn_client_conflict_get_incoming_change(conflict) ==
            svn_wc_conflict_action_edit)
-       && (svn_client_conflict_get_local_change(desc) ==
+       && (svn_client_conflict_get_local_change(conflict) ==
            svn_wc_conflict_reason_edited)))
-    SVN_ERR(handle_text_conflict(*result, desc, b, scratch_pool));
-  else if (svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_property)
-    SVN_ERR(handle_prop_conflict(*result, desc, b, result_pool, scratch_pool));
-  else if (svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_tree)
-    SVN_ERR(handle_tree_conflict(*result, desc, b, scratch_pool));
+    SVN_ERR(handle_text_conflict(*result, conflict, b, scratch_pool));
+  else if (svn_client_conflict_get_kind(conflict) ==
+           svn_wc_conflict_kind_property)
+    SVN_ERR(handle_prop_conflict(*result, conflict, b, result_pool,
+                                 scratch_pool));
+  else if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_tree)
+    SVN_ERR(handle_tree_conflict(*result, conflict, b, scratch_pool));
 
   else /* other types of conflicts -- do nothing about them. */
     {
@@ -1391,8 +1426,12 @@ svn_cl__conflict_func_interactive(svn_wc
                                   apr_pool_t *scratch_pool)
 {
   svn_cl__interactive_conflict_baton_t *b = baton;
+  svn_client_conflict_t *conflict;
 
-  SVN_ERR(conflict_func_interactive(result, desc, baton,
+  SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc,
+                                                     scratch_pool,
+                                                     scratch_pool));
+  SVN_ERR(conflict_func_interactive(result, conflict, baton,
                                     result_pool, scratch_pool));
 
   /* If we are resolving a conflict, adjust the summary of conflicts. */
@@ -1400,11 +1439,11 @@ svn_cl__conflict_func_interactive(svn_wc
     {
       const char *local_path
         = svn_cl__local_style_skip_ancestor(
-            b->path_prefix, svn_client_conflict_get_local_abspath(desc),
+            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(desc));
+                                      svn_client_conflict_get_kind(conflict));
     }
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/help-cmd.c Fri Sep 11 15:51:30 2015
@@ -53,8 +53,9 @@ svn_cl__help(apr_getopt_t *os,
   N_("usage: svn <subcommand> [options] [args]\n"
      "Subversion command-line client.\n"
      "Type 'svn help <subcommand>' for help on a specific subcommand.\n"
-     "Type 'svn --version' to see the program version and RA modules\n"
-     "  or 'svn --version --quiet' to see just the version number.\n"
+     "Type 'svn --version' to see the program version and RA modules,\n"
+     "     'svn --version --verbose' to see dependency versions as well,\n"
+     "     'svn --version --quiet' to see just the version number.\n"
      "\n"
      "Most subcommands take file and/or directory arguments, recursing\n"
      "on the directories.  If no arguments are supplied to such a\n"

Modified: subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/info-cmd.c Fri Sep 11 15:51:30 2015
@@ -391,15 +391,24 @@ print_info_xml(void *baton,
   if (info->wc_info && info->wc_info->conflicts)
     {
       int i;
+      apr_pool_t *iterpool;
 
+      iterpool = svn_pool_create(pool);
       for (i = 0; i < info->wc_info->conflicts->nelts; i++)
         {
-          const svn_wc_conflict_description2_t *conflict =
+          const svn_wc_conflict_description2_t *desc =
                       APR_ARRAY_IDX(info->wc_info->conflicts, i,
                                     const svn_wc_conflict_description2_t *);
+          svn_client_conflict_t *conflict;
 
-          SVN_ERR(svn_cl__append_conflict_info_xml(sb, conflict, pool));
+          svn_pool_clear(iterpool);
+
+          SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc,
+                                                             iterpool,
+                                                             iterpool));
+          SVN_ERR(svn_cl__append_conflict_info_xml(sb, conflict, iterpool));
         }
+      svn_pool_destroy(iterpool);
     }
 
   if (info->lock)
@@ -581,27 +590,37 @@ print_info(void *baton,
 
       if (info->wc_info->conflicts)
         {
-          svn_boolean_t printed_prop_conflict_file = FALSE;
           svn_boolean_t printed_tc = FALSE;
+          svn_stringbuf_t *conflicted_props = NULL;
           int i;
+          apr_pool_t *iterpool;
 
+          iterpool = svn_pool_create(pool);
           for (i = 0; i < info->wc_info->conflicts->nelts; i++)
             {
-              const svn_wc_conflict_description2_t *conflict =
+              const svn_wc_conflict_description2_t *desc2 =
                     APR_ARRAY_IDX(info->wc_info->conflicts, i,
                                   const svn_wc_conflict_description2_t *);
               const char *desc;
-              const char *base_abspath;
-              const char *my_abspath;
-              const char *their_abspath;
-
-              base_abspath = svn_client_conflict_get_base_abspath(conflict);
-              my_abspath = svn_client_conflict_get_my_abspath(conflict);
-              their_abspath = svn_client_conflict_get_their_abspath(conflict);
-
+              const char *base_abspath = NULL;
+              const char *my_abspath = NULL;
+              const char *their_abspath = NULL;
+              svn_client_conflict_t *conflict;
+
+              svn_pool_clear(iterpool);
+
+              SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict,
+                                                                 desc2,
+                                                                 iterpool,
+                                                                 iterpool));
               switch (svn_client_conflict_get_kind(conflict))
                 {
                   case svn_wc_conflict_kind_text:
+
+                    SVN_ERR(svn_client_conflict_text_get_contents(
+                              NULL, &my_abspath, &base_abspath, &their_abspath,
+                              conflict, pool, pool));
+
                     if (base_abspath)
                       SVN_ERR(svn_cmdline_printf(pool,
                                 _("Conflict Previous Base File: %s\n"),
@@ -628,15 +647,18 @@ print_info(void *baton,
                   break;
 
                   case svn_wc_conflict_kind_property:
-                    if (! printed_prop_conflict_file)
-                      SVN_ERR(svn_cmdline_printf(pool,
-                                _("Conflict Properties File: %s\n"),
-                                svn_cl__local_style_skip_ancestor(
-                                  receiver_baton->path_prefix,
-                                  svn_client_conflict_get_prop_reject_abspath(
-                                    conflict),
-                                  pool)));
-                    printed_prop_conflict_file = TRUE;
+                    {
+                      const char *name;
+
+                      name = svn_client_conflict_prop_get_propname(conflict);
+                      if (conflicted_props == NULL)
+                        conflicted_props = svn_stringbuf_create(name, pool);
+                      else
+                        {
+                          svn_stringbuf_appendbyte(conflicted_props, ' ');
+                          svn_stringbuf_appendcstr(conflicted_props, name);
+                        }
+                    }
                   break;
 
                   case svn_wc_conflict_kind_tree:
@@ -650,6 +672,11 @@ print_info(void *baton,
                   break;
                 }
             }
+          svn_pool_destroy(iterpool);
+
+          if (conflicted_props)
+            SVN_ERR(svn_cmdline_printf(pool, _("Conflicted Properties: %s\n"),
+                                       conflicted_props->data));
 
           /* We only store one left and right version for all conflicts, which is
              referenced from all conflicts.
@@ -658,10 +685,18 @@ print_info(void *baton,
           {
             const char *src_left_version;
             const char *src_right_version;
-            const svn_wc_conflict_description2_t *conflict =
+            const char *repos_root_url;
+            const char *repos_relpath;
+            svn_revnum_t peg_rev;
+            svn_node_kind_t node_kind;
+            const svn_wc_conflict_description2_t *desc2 =
                   APR_ARRAY_IDX(info->wc_info->conflicts, 0,
                                 const svn_wc_conflict_description2_t *);
 
+            svn_client_conflict_t *conflict;
+
+            SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc2,
+                                                               pool, pool));
             if (!printed_tc)
               {
                 const char *desc;
@@ -669,21 +704,28 @@ print_info(void *baton,
                 SVN_ERR(svn_cl__get_human_readable_action_description(&desc,
                           svn_wc_conflict_action_edit,
                           svn_client_conflict_get_operation(conflict),
-                          svn_client_conflict_get_node_kind(conflict), pool));
+                          info->kind,
+                          pool));
 
                 SVN_ERR(svn_cmdline_printf(pool, "%s: %s\n",
                                                _("Conflict Details"), desc));
               }
 
+            SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL,
+                                                       conflict, pool, pool));
+            SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+                      &repos_relpath, &peg_rev, &node_kind, conflict,
+                      pool, pool));
             src_left_version =
-                        svn_cl__node_description(
-                          svn_client_conflict_get_src_left_version(conflict),
-                          info->repos_root_URL, pool);
+                        svn_cl__node_description(repos_root_url, repos_relpath,
+                          peg_rev, node_kind, info->repos_root_URL, pool);
 
+            SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
+                      &repos_relpath, &peg_rev, &node_kind, conflict,
+                      pool, pool));
             src_right_version =
-                        svn_cl__node_description(
-                          svn_client_conflict_get_src_right_version(conflict),
-                          info->repos_root_URL, pool);
+                        svn_cl__node_description(repos_root_url, repos_relpath,
+                          peg_rev, node_kind, info->repos_root_URL, pool);
 
             if (src_left_version)
               SVN_ERR(svn_cmdline_printf(pool, "  %s: %s\n",

Modified: subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/lock-cmd.c Fri Sep 11 15:51:30 2015
@@ -80,6 +80,29 @@ get_comment(const char **comment, svn_cl
   return SVN_NO_ERROR;
 }
 
+/* Baton for notify_lock_handler */
+struct notify_lock_baton_t
+{
+  void *inner_baton;
+  svn_wc_notify_func2_t inner_notify;
+  svn_boolean_t had_failure;
+};
+
+/* Implements svn_wc_notify_func2_t for svn_cl__lock */
+static void
+notify_lock_handler(void *baton,
+                    const svn_wc_notify_t *notify,
+                    apr_pool_t *scratch_pool)
+{
+  struct notify_lock_baton_t *nlb = baton;
+
+  if (notify->action == svn_wc_notify_failed_lock)
+    nlb->had_failure = TRUE;
+
+  if (nlb->inner_notify)
+    nlb->inner_notify(nlb->inner_baton, notify, scratch_pool);
+}
+
 /* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
 svn_cl__lock(apr_getopt_t *os,
@@ -90,6 +113,7 @@ svn_cl__lock(apr_getopt_t *os,
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
   const char *comment;
+  struct notify_lock_baton_t nlb;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -106,5 +130,18 @@ svn_cl__lock(apr_getopt_t *os,
 
   SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
 
-  return svn_client_lock(targets, comment, opt_state->force, ctx, pool);
+  nlb.inner_notify = ctx->notify_func2;
+  nlb.inner_baton = ctx->notify_baton2;
+  nlb.had_failure = FALSE;
+
+  ctx->notify_func2 = notify_lock_handler;
+  ctx->notify_baton2 = &nlb;
+
+  SVN_ERR(svn_client_lock(targets, comment, opt_state->force, ctx, pool));
+
+  if (nlb.had_failure)
+    return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
+                            _("One or more locks could not be obtained"));
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/reuse-ra-session/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/status.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/status.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/status.c Fri Sep 11 15:51:30 2015
@@ -282,11 +282,16 @@ print_status(const char *target_abspath,
 
       if (tree_conflicted)
         {
-          const svn_wc_conflict_description2_t *tree_conflict;
-          SVN_ERR(svn_wc__get_tree_conflict(&tree_conflict, ctx->wc_ctx,
+          const svn_wc_conflict_description2_t *desc2;
+          svn_client_conflict_t *tree_conflict;
+
+          SVN_ERR(svn_wc__get_tree_conflict(&desc2, ctx->wc_ctx,
                                             local_abspath, pool, pool));
-          SVN_ERR_ASSERT(tree_conflict != NULL);
+          SVN_ERR_ASSERT(desc2 != NULL);
 
+          SVN_ERR(svn_client_conflict_from_wc_description2_t(&tree_conflict,
+                                                             desc2,
+                                                             pool, pool));
           tree_status_code = 'C';
           SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
                             &desc, tree_conflict, pool));

Modified: subversion/branches/reuse-ra-session/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/svn.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/svn.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/svn.c Fri Sep 11 15:51:30 2015
@@ -415,7 +415,39 @@ const apr_getopt_option_t svn_cl__option
                           "                             "
                           "current revision (recommended when tagging)")},
   {"show-item", opt_show_item, 1,
-                       N_("print only the item identified by ARG")},
+                       N_("print only the item identified by ARG:\n"
+                          "                             "
+                          "   'kind'       node kind of TARGET\n"
+                          "                             "
+                          "   'url'        URL of TARGET in the repository\n"
+                          "                             "
+                          "   'relative-url'\n"
+                          "                             "
+                          "                repository-relative URL of TARGET\n"
+                          "                             "
+                          "   'repos-root-url'\n"
+                          "                             "
+                          "                root URL of repository\n"
+                          "                             "
+                          "   'repos-uuid' UUID of repository\n"
+                          "                             "
+                          "   'revision'   specified or implied revision\n"
+                          "                             "
+                          "   'last-changed-revision'\n"
+                          "                             "
+                          "                last change of TARGET at or before\n"
+                          "                             "
+                          "                'revision'\n"
+                          "                             "
+                          "   'last-changed-date'\n"
+                          "                             "
+                          "                date of 'last-changed-revision'\n"
+                          "                             "
+                          "   'last-changed-author'\n"
+                          "                             "
+                          "                author of 'last-changed-revision'\n"
+                          "                             "
+                          "   'wc-root'    root of TARGET's working copy")},
 
   /* Long-opt Aliases
    *
@@ -726,23 +758,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "usage: info [TARGET[@REV]...]\n"
      "\n"
      "  Print information about each TARGET (default: '.').\n"
-     "  TARGET may be either a working-copy path or URL.  If specified, REV\n"
-     "  determines in which revision the target is first looked up.\n"
+     "  TARGET may be either a working-copy path or a URL.  If specified, REV\n"
+     "  determines in which revision the target is first looked up; the default\n"
+     "  is HEAD for a URL or BASE for a WC path.\n"
      "\n"
      "  With --show-item, print only the value of one item of information\n"
-     "  about TARGET. One of the following items can be selected:\n"
-     "     kind                  the kind of TARGET\n"
-     "     url                   the URL of TARGET in the repository\n"
-     "     relative-url          the repository-relative URL\n"
-     "     repos-root-url        the repository root URL\n"
-     "     repos-uuid            the repository UUID\n"
-     "     revision              the revision of TARGET (defaults to BASE\n"
-     "                           for working copy paths and HEAD for URLs)\n"
-     "     last-changed-revision the most recent revision in which TARGET\n"
-     "                           was changed\n"
-     "     last-changed-date     the date of the last-changed revision\n"
-     "     last-changed-author   the author of the last-changed revision\n"
-     "     wc-root               the root of TARGET's working copy"),
+     "  about TARGET.\n"),
     {'r', 'R', opt_depth, opt_targets, opt_incremental, opt_xml,
      opt_changelist, opt_include_externals, opt_show_item, opt_no_newline}
   },

Modified: subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/unlock-cmd.c Fri Sep 11 15:51:30 2015
@@ -39,6 +39,29 @@
 
 /*** Code. ***/
 
+/* Baton for notify_unlock_handler */
+struct notify_unlock_baton_t
+{
+  void *inner_baton;
+  svn_wc_notify_func2_t inner_notify;
+  svn_boolean_t had_failure;
+};
+
+/* Implements svn_wc_notify_func2_t for svn_cl__unlock */
+static void
+notify_unlock_handler(void *baton,
+                      const svn_wc_notify_t *notify,
+                      apr_pool_t *scratch_pool)
+{
+  struct notify_unlock_baton_t *nub = baton;
+
+  if (notify->action == svn_wc_notify_failed_unlock)
+    nub->had_failure = TRUE;
+
+  if (nub->inner_notify)
+    nub->inner_notify(nub->inner_baton, notify, scratch_pool);
+}
+
 
 /* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
@@ -49,6 +72,7 @@ svn_cl__unlock(apr_getopt_t *os,
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
+  struct notify_unlock_baton_t nub;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -63,6 +87,18 @@ svn_cl__unlock(apr_getopt_t *os,
 
   SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
 
-  return svn_error_trace(
-    svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));
+  nub.inner_notify = ctx->notify_func2;
+  nub.inner_baton = ctx->notify_baton2;
+  nub.had_failure = FALSE;
+
+  ctx->notify_func2 = notify_unlock_handler;
+  ctx->notify_baton2 = &nub;
+
+  SVN_ERR(svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));
+
+  if (nub.had_failure)
+    return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
+                            _("One or more locks could not be released"));
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/reuse-ra-session/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svn/util.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svn/util.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svn/util.c Fri Sep 11 15:51:30 2015
@@ -907,14 +907,17 @@ svn_cl__time_cstring_to_human_cstring(co
 }
 
 const char *
-svn_cl__node_description(const svn_wc_conflict_version_t *node,
+svn_cl__node_description(const char *repos_root_url,
+                         const char *repos_relpath,
+                         svn_revnum_t peg_rev,
+                         svn_node_kind_t node_kind,
                          const char *wc_repos_root_URL,
                          apr_pool_t *pool)
 {
   const char *root_str = "^";
   const char *path_str = "...";
 
-  if (!node)
+  if (!repos_root_url || !repos_relpath || !SVN_IS_VALID_REVNUM(peg_rev))
     /* Printing "(none)" the harder way to ensure conformity (mostly with
      * translations). */
     return apr_psprintf(pool, "(%s)",
@@ -923,18 +926,18 @@ svn_cl__node_description(const svn_wc_co
   /* Construct a "caret notation" ^/URL if NODE matches WC_REPOS_ROOT_URL.
    * Otherwise show the complete URL, and if we can't, show dots. */
 
-  if (node->repos_url &&
+  if (repos_root_url &&
       (wc_repos_root_URL == NULL ||
-       strcmp(node->repos_url, wc_repos_root_URL) != 0))
-    root_str = node->repos_url;
+       strcmp(repos_root_url, wc_repos_root_URL) != 0))
+    root_str = repos_root_url;
 
-  if (node->path_in_repos)
-    path_str = node->path_in_repos;
+  if (repos_relpath)
+    path_str = repos_relpath;
 
   return apr_psprintf(pool, "(%s) %s@%ld",
-                      svn_cl__node_kind_str_human_readable(node->node_kind),
+                      svn_cl__node_kind_str_human_readable(node_kind),
                       svn_path_url_add_component2(root_str, path_str, pool),
-                      node->peg_rev);
+                      peg_rev);
 }
 
 svn_error_t *

Modified: subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/reuse-ra-session/subversion/svnadmin/svnadmin.c Fri Sep 11 15:51:30 2015
@@ -166,11 +166,13 @@ static svn_opt_subcommand_t
   subcommand_delrevprop,
   subcommand_deltify,
   subcommand_dump,
+  subcommand_dump_revprops,
   subcommand_freeze,
   subcommand_help,
   subcommand_hotcopy,
   subcommand_info,
   subcommand_load,
+  subcommand_load_revprops,
   subcommand_list_dblogs,
   subcommand_list_unused_dblogs,
   subcommand_lock,
@@ -392,6 +394,15 @@ static const svn_opt_subcommand_desc2_t
     "changed in those revisions.)\n"),
   {'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M'} },
 
+  {"dump-revprops", subcommand_dump_revprops, {0}, N_
+   ("usage: svnadmin dump-revprops REPOS_PATH [-r LOWER[:UPPER]]\n\n"
+    "Dump the revision properties of filesystem to stdout in a 'dumpfile'\n"
+    "portable format, sending feedback to stderr.  Dump revisions\n"
+    "LOWER rev through UPPER rev.  If no revisions are given, dump the\n"
+    "properties for all revisions.  If only LOWER is given, dump the\n"
+    "properties for that one revision.\n"),
+  {'r', 'q'} },
+
   {"freeze", subcommand_freeze, {0}, N_
    ("usage: 1. svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n"
     "               2. svnadmin freeze -F FILE PROGRAM [ARG...]\n\n"
@@ -444,6 +455,15 @@ static const svn_opt_subcommand_desc2_t
     svnadmin__use_pre_commit_hook, svnadmin__use_post_commit_hook,
     svnadmin__parent_dir, svnadmin__bypass_prop_validation, 'M'} },
 
+  {"load-revprops", subcommand_load_revprops, {0}, N_
+   ("usage: svnadmin load-revprops REPOS_PATH\n\n"
+    "Read a 'dumpfile'-formatted stream from stdin, setting the revision\n"
+    "properties in the repository's filesystem.  Revisions not found in the\n"
+    "repository will cause an error.  Progress feedback is sent to stdout.\n"
+    "If --revision is specified, limit the loaded revisions to only those\n"
+    "in the dump stream whose revision numbers match the specified range.\n"),
+   {'q', 'r', svnadmin__force_uuid, svnadmin__bypass_prop_validation} },
+
   {"lock", subcommand_lock, {0}, N_
    ("usage: svnadmin lock REPOS_PATH PATH USERNAME COMMENT-FILE [TOKEN]\n\n"
     "Lock PATH by USERNAME setting comments from COMMENT-FILE.\n"
@@ -864,25 +884,60 @@ err_cleanup(void *data)
   return APR_SUCCESS;
 }
 
-struct repos_notify_handler_baton {
-  /* Stream to write progress and other non-error output to. */
-  svn_stream_t *feedback_stream;
-
-  /* Suppress notifications that are neither errors nor warnings. */
-  svn_boolean_t silent_running;
-
-  /* Whether errors contained in notifications should be printed along
-     with the notification. If FALSE, any errors will only be
-     summarized. */
-  svn_boolean_t silent_errors;
+struct repos_verify_callback_baton
+{
+  /* Should we continue after receiving a first verification error? */
+  svn_boolean_t keep_going;
 
   /* List of errors encountered during 'svnadmin verify --keep-going'. */
   apr_array_header_t *error_summary;
 
-  /* Pool for data collected during notifications. */
+  /* Pool for data collected during callback invocations. */
   apr_pool_t *result_pool;
 };
 
+/* Implementation of svn_repos_verify_callback_t to handle errors coming
+   from svn_repos_verify_fs3(). */
+static svn_error_t *
+repos_verify_callback(void *baton,
+                      svn_revnum_t revision,
+                      svn_error_t *verify_err,
+                      apr_pool_t *scratch_pool)
+{
+  struct repos_verify_callback_baton *b = baton;
+
+  if (revision == SVN_INVALID_REVNUM)
+    {
+      SVN_ERR(svn_cmdline_fputs(_("* Error verifying repository metadata.\n"),
+                                stderr, scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+                                  _("* Error verifying revision %ld.\n"),
+                                  revision));
+    }
+
+  if (b->keep_going)
+    {
+      struct verification_error *verr;
+
+      svn_handle_error2(verify_err, stderr, FALSE, "svnadmin: ");
+
+      /* Remember the error in B->ERROR_SUMMARY. */
+      verr = apr_palloc(b->result_pool, sizeof(*verr));
+      verr->rev = revision;
+      verr->err = svn_error_dup(verify_err);
+      apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup,
+                                apr_pool_cleanup_null);
+      APR_ARRAY_PUSH(b->error_summary, struct verification_error *) = verr;
+
+      return SVN_NO_ERROR;
+    }
+  else
+    return svn_error_trace(svn_error_dup(verify_err));
+}
+
 /* Implementation of svn_repos_notify_func_t to wrap the output to a
    response stream for svn_repos_dump_fs2(), svn_repos_verify_fs(),
    svn_repos_hotcopy3() and others. */
@@ -891,16 +946,7 @@ repos_notify_handler(void *baton,
                      const svn_repos_notify_t *notify,
                      apr_pool_t *scratch_pool)
 {
-  struct repos_notify_handler_baton *b = baton;
-  svn_stream_t *feedback_stream = b->feedback_stream;
-
-  /* Don't print anything if the feedback stream isn't provided.
-     Only print errors and warnings in silent mode. */
-  if (!feedback_stream
-      || (b->silent_running
-          && notify->action != svn_repos_notify_warning
-          && notify->action != svn_repos_notify_failure))
-    return;
+  svn_stream_t *feedback_stream = baton;
 
   switch (notify->action)
   {
@@ -910,32 +956,6 @@ repos_notify_handler(void *baton,
                                         notify->warning_str));
       return;
 
-    case svn_repos_notify_failure:
-      if (notify->revision != SVN_INVALID_REVNUM)
-        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                    _("* Error verifying revision %ld.\n"),
-                                    notify->revision));
-      if (notify->err)
-        {
-          if (!b->silent_errors)
-            svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */,
-                              "svnadmin: ");
-
-          if (b->error_summary && notify->revision != SVN_INVALID_REVNUM)
-            {
-              struct verification_error *verr;
-
-              verr = apr_palloc(b->result_pool, sizeof(*verr));
-              verr->rev = notify->revision;
-              verr->err = svn_error_dup(notify->err);
-              apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup,
-                                        apr_pool_cleanup_null);
-              APR_ARRAY_PUSH(b->error_summary,
-                             struct verification_error *) = verr;
-            }
-        }
-      return;
-
     case svn_repos_notify_dump_rev_end:
       svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
                                         _("* Dumped revision %ld.\n"),
@@ -1126,6 +1146,24 @@ repos_notify_handler(void *baton,
                                _("* Copied revisions from %ld to %ld.\n"),
                                notify->start_revision, notify->end_revision));
         }
+      return;
+
+    case svn_repos_notify_pack_noop:
+      /* For best backward compatibility, we keep silent if there were just
+         no more shards to pack. */
+      if (notify->shard == -1)
+        {
+          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                     _("svnadmin: Warning - this repository is not sharded."
+                       " Packing has no effect.\n")));
+        }
+      return;
+
+    case svn_repos_notify_load_revprop_set:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                        _("Properties set on revision %ld.\n"),
+                        notify->new_revision));
+      return;
 
     default:
       return;
@@ -1172,57 +1210,106 @@ recode_stream_create(FILE *std_stream, a
   return rw_stream;
 }
 
-
-/* This implements `svn_opt_subcommand_t'. */
-static svn_error_t *
-subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+/* Read the min / max revision from the OPT_STATE, verify them against REPOS
+   and return them in *LOWER and *UPPER, respectively.  Use SCRATCH_POOL
+   for temporary allocations. */
+static svn_error_t *
+get_dump_range(svn_revnum_t *lower,
+               svn_revnum_t *upper,
+               svn_repos_t *repos,
+               struct svnadmin_opt_state *opt_state,
+               apr_pool_t *scratch_pool)
 {
-  struct svnadmin_opt_state *opt_state = baton;
-  svn_repos_t *repos;
   svn_fs_t *fs;
-  svn_stream_t *stdout_stream;
-  svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
   svn_revnum_t youngest;
-  struct repos_notify_handler_baton notify_baton = { 0 };
 
-  /* Expect no more arguments. */
-  SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+  *lower = SVN_INVALID_REVNUM;
+  *upper = SVN_INVALID_REVNUM;
 
-  SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
   fs = svn_repos_fs(repos);
-  SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
+  SVN_ERR(svn_fs_youngest_rev(&youngest, fs, scratch_pool));
 
   /* Find the revision numbers at which to start and end. */
-  SVN_ERR(get_revnum(&lower, &opt_state->start_revision,
-                     youngest, repos, pool));
-  SVN_ERR(get_revnum(&upper, &opt_state->end_revision,
-                     youngest, repos, pool));
+  SVN_ERR(get_revnum(lower, &opt_state->start_revision,
+                     youngest, repos, scratch_pool));
+  SVN_ERR(get_revnum(upper, &opt_state->end_revision,
+                     youngest, repos, scratch_pool));
 
   /* Fill in implied revisions if necessary. */
-  if (lower == SVN_INVALID_REVNUM)
+  if (*lower == SVN_INVALID_REVNUM)
     {
-      lower = 0;
-      upper = youngest;
+      *lower = 0;
+      *upper = youngest;
     }
-  else if (upper == SVN_INVALID_REVNUM)
+  else if (*upper == SVN_INVALID_REVNUM)
     {
-      upper = lower;
+      *upper = *lower;
     }
 
-  if (lower > upper)
+  if (*lower > *upper)
     return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
        _("First revision cannot be higher than second"));
 
+  return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+  struct svnadmin_opt_state *opt_state = baton;
+  svn_repos_t *repos;
+  svn_stream_t *stdout_stream;
+  svn_revnum_t lower, upper;
+  svn_stream_t *feedback_stream = NULL;
+
+  /* Expect no more arguments. */
+  SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+  SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+  SVN_ERR(get_dump_range(&lower, &upper, repos, opt_state, pool));
+
   SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
 
   /* Progress feedback goes to STDERR, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    notify_baton.feedback_stream = recode_stream_create(stderr, pool);
+    feedback_stream = recode_stream_create(stderr, pool);
 
-  SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
+  SVN_ERR(svn_repos_dump_fs4(repos, stdout_stream, lower, upper,
                              opt_state->incremental, opt_state->use_deltas,
+                             TRUE, TRUE,
+                             !opt_state->quiet ? repos_notify_handler : NULL,
+                             feedback_stream, check_cancel, NULL, pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_dump_revprops(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+  struct svnadmin_opt_state *opt_state = baton;
+  svn_repos_t *repos;
+  svn_stream_t *stdout_stream;
+  svn_revnum_t lower, upper;
+  svn_stream_t *feedback_stream = NULL;
+
+  /* Expect no more arguments. */
+  SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+  SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+  SVN_ERR(get_dump_range(&lower, &upper, repos, opt_state, pool));
+
+  SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+
+  /* Progress feedback goes to STDERR, unless they asked to suppress it. */
+  if (! opt_state->quiet)
+    feedback_stream = recode_stream_create(stderr, pool);
+
+  SVN_ERR(svn_repos_dump_fs4(repos, stdout_stream, lower, upper,
+                             FALSE, FALSE, TRUE, FALSE,
                              !opt_state->quiet ? repos_notify_handler : NULL,
-                             &notify_baton, check_cancel, NULL, pool));
+                             feedback_stream, check_cancel, NULL, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1362,43 +1449,57 @@ optrev_to_revnum(svn_revnum_t *revnum, c
   return SVN_NO_ERROR;
 }
 
-
-/* This implements `svn_opt_subcommand_t'. */
+/* Read the min / max revision from the OPT_STATE, verify them and return
+   them in *LOWER and *UPPER, respectively. */
 static svn_error_t *
-subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+get_load_range(svn_revnum_t *lower,
+               svn_revnum_t *upper,
+               struct svnadmin_opt_state *opt_state)
 {
-  svn_error_t *err;
-  struct svnadmin_opt_state *opt_state = baton;
-  svn_repos_t *repos;
-  svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
-  svn_stream_t *stdin_stream;
-  struct repos_notify_handler_baton notify_baton = { 0 };
-
-  /* Expect no more arguments. */
-  SVN_ERR(parse_args(NULL, os, 0, 0, pool));
-
   /* Find the revision numbers at which to start and end.  We only
      support a limited set of revision kinds: number and unspecified. */
-  SVN_ERR(optrev_to_revnum(&lower, &opt_state->start_revision));
-  SVN_ERR(optrev_to_revnum(&upper, &opt_state->end_revision));
+  SVN_ERR(optrev_to_revnum(lower, &opt_state->start_revision));
+  SVN_ERR(optrev_to_revnum(upper, &opt_state->end_revision));
 
   /* Fill in implied revisions if necessary. */
-  if ((upper == SVN_INVALID_REVNUM) && (lower != SVN_INVALID_REVNUM))
+  if ((*upper == SVN_INVALID_REVNUM) && (*lower != SVN_INVALID_REVNUM))
     {
-      upper = lower;
+      *upper = *lower;
     }
-  else if ((upper != SVN_INVALID_REVNUM) && (lower == SVN_INVALID_REVNUM))
+  else if ((*upper != SVN_INVALID_REVNUM) && (*lower == SVN_INVALID_REVNUM))
     {
-      lower = upper;
+      *lower = *upper;
     }
 
   /* Ensure correct range ordering. */
-  if (lower > upper)
+  if (*lower > *upper)
     {
       return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                               _("First revision cannot be higher than second"));
     }
 
+  return SVN_NO_ERROR;
+}
+
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+  svn_error_t *err;
+  struct svnadmin_opt_state *opt_state = baton;
+  svn_repos_t *repos;
+  svn_revnum_t lower, upper;
+  svn_stream_t *stdin_stream;
+  svn_stream_t *feedback_stream = NULL;
+
+  /* Expect no more arguments. */
+  SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+  /* Find the revision numbers at which to start and end.  We only
+     support a limited set of revision kinds: number and unspecified. */
+  SVN_ERR(get_load_range(&lower, &upper, opt_state));
+
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
 
   /* Read the stream from STDIN.  Users can redirect a file. */
@@ -1406,7 +1507,7 @@ subcommand_load(apr_getopt_t *os, void *
 
   /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+    feedback_stream = recode_stream_create(stdout, pool);
 
   err = svn_repos_load_fs5(repos, stdin_stream, lower, upper,
                            opt_state->uuid_action, opt_state->parent_dir,
@@ -1415,7 +1516,7 @@ subcommand_load(apr_getopt_t *os, void *
                            !opt_state->bypass_prop_validation,
                            opt_state->ignore_dates,
                            opt_state->quiet ? NULL : repos_notify_handler,
-                           &notify_baton, check_cancel, NULL, pool);
+                           feedback_stream, check_cancel, NULL, pool);
   if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
     return svn_error_quick_wrap(err,
                                 _("Invalid property value found in "
@@ -1425,6 +1526,48 @@ subcommand_load(apr_getopt_t *os, void *
   return err;
 }
 
+static svn_error_t *
+subcommand_load_revprops(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+  svn_error_t *err;
+  struct svnadmin_opt_state *opt_state = baton;
+  svn_repos_t *repos;
+  svn_revnum_t lower, upper;
+  svn_stream_t *stdin_stream;
+
+  svn_stream_t *feedback_stream = NULL;
+
+  /* Expect no more arguments. */
+  SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+  /* Find the revision numbers at which to start and end.  We only
+     support a limited set of revision kinds: number and unspecified. */
+  SVN_ERR(get_load_range(&lower, &upper, opt_state));
+
+  SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+
+  /* Read the stream from STDIN.  Users can redirect a file. */
+  SVN_ERR(svn_stream_for_stdin(&stdin_stream, pool));
+  stdin_stream = svn_stream_wrap_buffered_read(stdin_stream, pool);
+
+  /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
+  if (! opt_state->quiet)
+    feedback_stream = recode_stream_create(stdout, pool);
+
+  err = svn_repos_load_fs_revprops(repos, stdin_stream, lower, upper,
+                                   !opt_state->bypass_prop_validation,
+                                   opt_state->ignore_dates,
+                                   opt_state->quiet ? NULL
+                                                    : repos_notify_handler,
+                                   feedback_stream, check_cancel, NULL, pool);
+  if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
+    return svn_error_quick_wrap(err,
+                                _("Invalid property value found in "
+                                  "dumpstream; consider repairing the source "
+                                  "or using --bypass-prop-validation while "
+                                  "loading."));
+  return err;
+}
 
 /* This implements `svn_opt_subcommand_t'. */
 static svn_error_t *
@@ -1462,12 +1605,12 @@ subcommand_recover(apr_getopt_t *os, voi
   svn_repos_t *repos;
   svn_error_t *err;
   struct svnadmin_opt_state *opt_state = baton;
-  struct repos_notify_handler_baton notify_baton = { 0 };
+  svn_stream_t *feedback_stream = NULL;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
 
-  SVN_ERR(svn_stream_for_stdout(&notify_baton.feedback_stream, pool));
+  SVN_ERR(svn_stream_for_stdout(&feedback_stream, pool));
 
   /* Restore default signal handlers until after we have acquired the
    * exclusive lock so that the user interrupt before we actually
@@ -1475,7 +1618,7 @@ subcommand_recover(apr_getopt_t *os, voi
   setup_cancellation_signals(SIG_DFL);
 
   err = svn_repos_recover4(opt_state->repository_path, TRUE,
-                           repos_notify_handler, &notify_baton,
+                           repos_notify_handler, feedback_stream,
                            check_cancel, NULL, pool);
   if (err)
     {
@@ -1493,7 +1636,7 @@ subcommand_recover(apr_getopt_t *os, voi
                                    " another process has it open?\n")));
       SVN_ERR(svn_cmdline_fflush(stdout));
       SVN_ERR(svn_repos_recover4(opt_state->repository_path, FALSE,
-                                 repos_notify_handler, &notify_baton,
+                                 repos_notify_handler, feedback_stream,
                                  check_cancel, NULL, pool));
     }
 
@@ -1779,7 +1922,7 @@ subcommand_pack(apr_getopt_t *os, void *
 {
   struct svnadmin_opt_state *opt_state = baton;
   svn_repos_t *repos;
-  struct repos_notify_handler_baton notify_baton = { 0 };
+  svn_stream_t *feedback_stream = NULL;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1788,11 +1931,11 @@ subcommand_pack(apr_getopt_t *os, void *
 
   /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+    feedback_stream = recode_stream_create(stdout, pool);
 
   return svn_error_trace(
     svn_repos_fs_pack2(repos, !opt_state->quiet ? repos_notify_handler : NULL,
-                       &notify_baton, check_cancel, NULL, pool));
+                       feedback_stream, check_cancel, NULL, pool));
 }
 
 
@@ -1804,10 +1947,8 @@ subcommand_verify(apr_getopt_t *os, void
   svn_repos_t *repos;
   svn_fs_t *fs;
   svn_revnum_t youngest, lower, upper;
-  struct repos_notify_handler_baton notify_baton = { 0 };
-  struct repos_notify_handler_baton *notify_baton_p = &notify_baton;
-  svn_repos_notify_func_t notify_func = repos_notify_handler;
-  svn_error_t *verify_err;
+  svn_stream_t *feedback_stream = NULL;
+  struct repos_verify_callback_baton verify_baton = { 0 };
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1851,42 +1992,27 @@ subcommand_verify(apr_getopt_t *os, void
       upper = lower;
     }
 
-  /* Set up the notification handler. */
-  if (!opt_state->quiet || opt_state->keep_going)
-    {
-      if (opt_state->quiet)
-        {
-          notify_baton.silent_running = TRUE;
-          notify_baton.feedback_stream = recode_stream_create(stderr, pool);
-        }
-      else
-        notify_baton.feedback_stream = recode_stream_create(stdout, pool);
-
-      if (opt_state->keep_going)
-        notify_baton.error_summary =
-          apr_array_make(pool, 0, sizeof(struct verification_error *));
-      else
-        notify_baton.silent_errors = TRUE;
-
-      notify_baton.result_pool = pool;
-    }
-  else
-    {
-      notify_func = NULL;
-      notify_baton_p = NULL;
-    }
+  if (!opt_state->quiet)
+    feedback_stream = recode_stream_create(stdout, pool);
 
-  verify_err = svn_repos_verify_fs3(repos, lower, upper,
-                                    opt_state->keep_going,
-                                    opt_state->check_normalization,
-                                    opt_state->metadata_only,
-                                    notify_func, notify_baton_p,
-                                    check_cancel, NULL, pool);
+  verify_baton.keep_going = opt_state->keep_going;
+  verify_baton.error_summary =
+    apr_array_make(pool, 0, sizeof(struct verification_error *));
+  verify_baton.result_pool = pool;
+
+  SVN_ERR(svn_repos_verify_fs3(repos, lower, upper,
+                               opt_state->check_normalization,
+                               opt_state->metadata_only,
+                               !opt_state->quiet
+                                 ? repos_notify_handler : NULL,
+                               feedback_stream,
+                               repos_verify_callback, &verify_baton,
+                               check_cancel, NULL, pool));
 
   /* Show the --keep-going error summary. */
   if (!opt_state->quiet
       && opt_state->keep_going
-      && notify_baton.error_summary->nelts > 0)
+      && verify_baton.error_summary->nelts > 0)
     {
       int rev_maxlength;
       svn_revnum_t end_revnum;
@@ -1894,15 +2020,15 @@ subcommand_verify(apr_getopt_t *os, void
       int i;
 
       svn_error_clear(
-        svn_stream_puts(notify_baton.feedback_stream,
+        svn_stream_puts(feedback_stream,
                           _("\n-----Summary of corrupt revisions-----\n")));
 
       /* The standard column width for the revision number is 6 characters.
          If the revision number can potentially be larger (i.e. if end_revnum
          is larger than 1000000), we increase the column width as needed. */
       rev_maxlength = 6;
-      end_revnum = APR_ARRAY_IDX(notify_baton.error_summary,
-                                 notify_baton.error_summary->nelts - 1,
+      end_revnum = APR_ARRAY_IDX(verify_baton.error_summary,
+                                 verify_baton.error_summary->nelts - 1,
                                  struct verification_error *)->rev;
       while (end_revnum >= 1000000)
         {
@@ -1911,7 +2037,7 @@ subcommand_verify(apr_getopt_t *os, void
         }
 
       iterpool = svn_pool_create(pool);
-      for (i = 0; i < notify_baton.error_summary->nelts; i++)
+      for (i = 0; i < verify_baton.error_summary->nelts; i++)
         {
           struct verification_error *verr;
           svn_error_t *err;
@@ -1919,29 +2045,40 @@ subcommand_verify(apr_getopt_t *os, void
 
           svn_pool_clear(iterpool);
 
-          verr = APR_ARRAY_IDX(notify_baton.error_summary, i,
+          verr = APR_ARRAY_IDX(verify_baton.error_summary, i,
                                struct verification_error *);
-          rev_str = apr_psprintf(iterpool, "r%ld", verr->rev);
-          rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str);
-          for (err = svn_error_purge_tracing(verr->err);
-               err != SVN_NO_ERROR; err = err->child)
-            {
-              char buf[512];
-              const char *message;
 
-              message = svn_err_best_message(err, buf, sizeof(buf));
-              svn_error_clear(svn_stream_printf(notify_baton.feedback_stream,
-                                                iterpool,
-                                                "%s: E%06d: %s\n",
-                                                rev_str, err->apr_err,
-                                                message));
+          if (verr->rev != SVN_INVALID_REVNUM)
+            {
+              rev_str = apr_psprintf(iterpool, "r%ld", verr->rev);
+              rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str);
+              for (err = svn_error_purge_tracing(verr->err);
+                   err != SVN_NO_ERROR; err = err->child)
+                {
+                  char buf[512];
+                  const char *message;
+
+                  message = svn_err_best_message(err, buf, sizeof(buf));
+                  svn_error_clear(svn_stream_printf(feedback_stream, iterpool,
+                                                    "%s: E%06d: %s\n",
+                                                    rev_str, err->apr_err,
+                                                    message));
+                }
             }
         }
 
        svn_pool_destroy(iterpool);
     }
 
-  return svn_error_trace(verify_err);
+  if (verify_baton.error_summary->nelts > 0)
+    {
+      return svn_error_createf(SVN_ERR_CL_REPOS_VERIFY_FAILED, NULL,
+                               _("Failed to verify repository '%s'"),
+                               svn_dirent_local_style(
+                                 opt_state->repository_path, pool));
+    }
+
+  return SVN_NO_ERROR;
 }
 
 /* This implements `svn_opt_subcommand_t'. */
@@ -1949,7 +2086,7 @@ svn_error_t *
 subcommand_hotcopy(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
   struct svnadmin_opt_state *opt_state = baton;
-  struct repos_notify_handler_baton notify_baton = { 0 };
+  svn_stream_t *feedback_stream = NULL;
   apr_array_header_t *targets;
   const char *new_repos_path;
 
@@ -1960,12 +2097,12 @@ subcommand_hotcopy(apr_getopt_t *os, voi
 
   /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+    feedback_stream = recode_stream_create(stdout, pool);
 
   return svn_repos_hotcopy3(opt_state->repository_path, new_repos_path,
                             opt_state->clean_logs, opt_state->incremental,
                             !opt_state->quiet ? repos_notify_handler : NULL,
-                            &notify_baton, check_cancel, NULL, pool);
+                            feedback_stream, check_cancel, NULL, pool);
 }
 
 svn_error_t *
@@ -1976,6 +2113,7 @@ subcommand_info(apr_getopt_t *os, void *
   svn_fs_t *fs;
   int fs_format;
   const char *uuid;
+  svn_revnum_t head_rev;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1988,6 +2126,9 @@ subcommand_info(apr_getopt_t *os, void *
 
   SVN_ERR(svn_fs_get_uuid(fs, &uuid, pool));
   SVN_ERR(svn_cmdline_printf(pool, _("UUID: %s\n"), uuid));
+
+  SVN_ERR(svn_fs_youngest_rev(&head_rev, fs, pool));
+  SVN_ERR(svn_cmdline_printf(pool, _("Revisions: %ld\n"), head_rev));
   {
     int repos_format, minor;
     svn_version_t *repos_version, *fs_version;
@@ -2349,18 +2490,18 @@ subcommand_upgrade(apr_getopt_t *os, voi
 {
   svn_error_t *err;
   struct svnadmin_opt_state *opt_state = baton;
-  struct repos_notify_handler_baton notify_baton = { 0 };
+  svn_stream_t *feedback_stream = NULL;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
 
-  SVN_ERR(svn_stream_for_stdout(&notify_baton.feedback_stream, pool));
+  SVN_ERR(svn_stream_for_stdout(&feedback_stream, pool));
 
   /* Restore default signal handlers. */
   setup_cancellation_signals(SIG_DFL);
 
   err = svn_repos_upgrade2(opt_state->repository_path, TRUE,
-                           repos_notify_handler, &notify_baton, pool);
+                           repos_notify_handler, feedback_stream, pool);
   if (err)
     {
       if (APR_STATUS_IS_EAGAIN(err->apr_err))
@@ -2378,7 +2519,7 @@ subcommand_upgrade(apr_getopt_t *os, voi
                                        " another process has it open?\n")));
           SVN_ERR(svn_cmdline_fflush(stdout));
           SVN_ERR(svn_repos_upgrade2(opt_state->repository_path, FALSE,
-                                     repos_notify_handler, &notify_baton,
+                                     repos_notify_handler, feedback_stream,
                                      pool));
         }
       else if (err->apr_err == SVN_ERR_FS_UNSUPPORTED_UPGRADE)