You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2018/09/30 18:26:49 UTC

svn commit: r1842404 [8/11] - in /subversion/branches/better-pristines: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/svn_load_dirs/ doc/user/ notes/logo/ notes/shelving/ subversion/bindings/javahl/ subversi...

Modified: subversion/branches/better-pristines/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svn/cl.h?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svn/cl.h (original)
+++ subversion/branches/better-pristines/subversion/svn/cl.h Sun Sep 30 18:26:47 2018
@@ -257,7 +257,11 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t adds_as_modification; /* update 'add vs add' no tree conflict */
   svn_boolean_t vacuum_pristines; /* remove unreferenced pristines */
   svn_boolean_t drop;             /* drop shelf after successful unshelve */
-  svn_boolean_t viewspec;
+  enum svn_cl__viewspec_t {
+      svn_cl__viewspec_unspecified = 0 /* default */,
+      svn_cl__viewspec_classic,
+      svn_cl__viewspec_svn11
+  } viewspec;                     /* value of --x-viewspec */
   svn_version_t *compatible_version; /* working copy compatibility version */
 } svn_cl__opt_state_t;
 
@@ -922,6 +926,20 @@ svn_cl__similarity_check(const char *key
                          apr_size_t token_count,
                          apr_pool_t *scratch_pool);
 
+/* Return in FUNC_P and BATON_P a callback that prints a summary diff,
+ * according to the options XML and IGNORE_PROPERTIES.
+ *
+ * ANCHOR is a URL or local path to be prefixed to the printed paths.
+ */
+svn_error_t *
+svn_cl__get_diff_summary_writer(svn_client_diff_summarize_func_t *func_p,
+                                void **baton_p,
+                                svn_boolean_t xml,
+                                svn_boolean_t ignore_properties,
+                                const char *anchor,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/better-pristines/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svn/conflict-callbacks.c?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/better-pristines/subversion/svn/conflict-callbacks.c Sun Sep 30 18:26:47 2018
@@ -440,6 +440,11 @@ static const resolver_option_t builtin_r
 
   /* Options for local move vs incoming edit. */
   { "m", svn_client_conflict_option_local_move_file_text_merge },
+  { "m", svn_client_conflict_option_local_move_dir_merge },
+
+  /* Options for local missing vs incoming edit. */
+  { "m", svn_client_conflict_option_sibling_move_file_text_merge },
+  { "m", svn_client_conflict_option_sibling_move_dir_merge },
 
   { NULL }
 };
@@ -1529,17 +1534,16 @@ build_tree_conflict_options(
           id != svn_client_conflict_option_accept_current_wc_state)
         *all_options_are_dumb = FALSE;
 
-      if (id == svn_client_conflict_option_incoming_move_file_text_merge ||
-          id == svn_client_conflict_option_incoming_move_dir_merge)
-        {
+        if (*possible_moved_to_repos_relpaths == NULL)
           SVN_ERR(
-            svn_client_conflict_option_get_moved_to_repos_relpath_candidates(
+            svn_client_conflict_option_get_moved_to_repos_relpath_candidates2(
               possible_moved_to_repos_relpaths, builtin_option,
               result_pool, iterpool));
-          SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates(
+
+        if (*possible_moved_to_abspaths == NULL)
+          SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates2(
                     possible_moved_to_abspaths, builtin_option,
                     result_pool, iterpool));
-        }
     }
 
   svn_pool_destroy(iterpool);
@@ -1670,6 +1674,69 @@ prompt_move_target_path(int *preferred_m
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+find_conflict_option_with_repos_move_targets(
+  svn_client_conflict_option_t **option_with_move_targets,
+  apr_array_header_t *options,
+  apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int i;
+  apr_array_header_t *possible_moved_to_repos_relpaths = NULL;
+  
+  *option_with_move_targets = NULL;
+
+  for (i = 0; i < options->nelts; i++)
+    {
+      svn_client_conflict_option_t *option;
+
+      svn_pool_clear(iterpool);
+      option = APR_ARRAY_IDX(options, i, svn_client_conflict_option_t *);
+      SVN_ERR(svn_client_conflict_option_get_moved_to_repos_relpath_candidates2(
+        &possible_moved_to_repos_relpaths, option, iterpool, iterpool));
+      if (possible_moved_to_repos_relpaths)
+        {
+          *option_with_move_targets = option;
+          break;
+        }
+    }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+find_conflict_option_with_working_copy_move_targets(
+  svn_client_conflict_option_t **option_with_move_targets,
+  apr_array_header_t *options,
+  apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int i;
+  apr_array_header_t *possible_moved_to_abspaths = NULL;
+  
+  *option_with_move_targets = NULL;
+
+  for (i = 0; i < options->nelts; i++)
+    {
+      svn_client_conflict_option_t *option;
+
+      svn_pool_clear(iterpool);
+      option = APR_ARRAY_IDX(options, i, svn_client_conflict_option_t *);
+      SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates2(
+              &possible_moved_to_abspaths, option, scratch_pool,
+              iterpool));
+      if (possible_moved_to_abspaths)
+        {
+          *option_with_move_targets = option;
+          break;
+        }
+    }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 /* Ask the user what to do about the tree conflict described by CONFLICT
  * and either resolve the conflict accordingly or postpone resolution.
  * SCRATCH_POOL is used for temporary allocations. */
@@ -1797,7 +1864,7 @@ handle_tree_conflict(svn_boolean_t *reso
         {
           int preferred_move_target_idx;
           apr_array_header_t *options;
-          svn_client_conflict_option_t *conflict_option;
+          svn_client_conflict_option_t *option;
 
           SVN_ERR(prompt_move_target_path(&preferred_move_target_idx,
                                           possible_moved_to_repos_relpaths,
@@ -1810,22 +1877,12 @@ handle_tree_conflict(svn_boolean_t *reso
                                                                   ctx,
                                                                   iterpool,
                                                                   iterpool));
-          conflict_option =
-            svn_client_conflict_option_find_by_id( 
-              options,
-              svn_client_conflict_option_incoming_move_file_text_merge);
-          if (conflict_option == NULL)
+          SVN_ERR(find_conflict_option_with_repos_move_targets(
+            &option, options, iterpool));
+          if (option)
             {
-              conflict_option =
-                svn_client_conflict_option_find_by_id( 
-                  options, svn_client_conflict_option_incoming_move_dir_merge);
-            }
-
-          if (conflict_option)
-            {
-              SVN_ERR(svn_client_conflict_option_set_moved_to_repos_relpath(
-                        conflict_option, preferred_move_target_idx,
-                        ctx, iterpool));
+              SVN_ERR(svn_client_conflict_option_set_moved_to_repos_relpath2(
+                        option, preferred_move_target_idx, ctx, iterpool));
               repos_move_target_chosen = TRUE;
               wc_move_target_chosen = FALSE;
 
@@ -1851,7 +1908,7 @@ handle_tree_conflict(svn_boolean_t *reso
         {
           int preferred_move_target_idx;
           apr_array_header_t *options;
-          svn_client_conflict_option_t *conflict_option;
+          svn_client_conflict_option_t *option;
 
           SVN_ERR(prompt_move_target_path(&preferred_move_target_idx,
                                            possible_moved_to_abspaths, TRUE,
@@ -1863,22 +1920,12 @@ handle_tree_conflict(svn_boolean_t *reso
                                                                   ctx,
                                                                   iterpool,
                                                                   iterpool));
-          conflict_option =
-            svn_client_conflict_option_find_by_id( 
-              options,
-              svn_client_conflict_option_incoming_move_file_text_merge);
-          if (conflict_option == NULL)
-            {
-              conflict_option =
-                svn_client_conflict_option_find_by_id( 
-                  options, svn_client_conflict_option_incoming_move_dir_merge);
-            }
-
-          if (conflict_option)
+          SVN_ERR(find_conflict_option_with_working_copy_move_targets(
+            &option, options, iterpool));
+          if (option)
             {
-              SVN_ERR(svn_client_conflict_option_set_moved_to_abspath(
-                        conflict_option, preferred_move_target_idx, ctx,
-                        iterpool));
+              SVN_ERR(svn_client_conflict_option_set_moved_to_abspath2(
+                        option, preferred_move_target_idx, ctx, iterpool));
               wc_move_target_chosen = TRUE;
 
               /* Update option description. */
@@ -1930,7 +1977,6 @@ resolve_conflict_interactively(svn_boole
                                svn_cmdline_prompt_baton_t *pb,
                                svn_cl__conflict_stats_t *conflict_stats,
                                svn_client_ctx_t *ctx,
-                               apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
 {
   svn_boolean_t text_conflicted;
@@ -1964,7 +2010,7 @@ resolve_conflict_interactively(svn_boole
   if (props_conflicted->nelts > 0)
     SVN_ERR(handle_prop_conflicts(resolved, postponed, quit, &merged_propval,
                                   path_prefix, pb, editor_cmd, config, conflict,
-                                  conflict_stats, ctx, result_pool, scratch_pool));
+                                  conflict_stats, ctx, scratch_pool, scratch_pool));
   if (tree_conflicted)
     SVN_ERR(handle_tree_conflict(resolved, postponed, quit, printed_description,
                                  conflict, path_prefix, pb, conflict_stats, ctx,
@@ -2201,11 +2247,14 @@ svn_cl__resolve_conflict(svn_boolean_t *
       svn_boolean_t postponed = FALSE;
       svn_boolean_t printed_description = FALSE;
       svn_error_t *err;
+      apr_pool_t *iterpool;
 
       *quit = FALSE;
 
+      iterpool = svn_pool_create(scratch_pool);
       while (!resolved && !postponed && !*quit)
         {
+          svn_pool_clear(iterpool);
           err = resolve_conflict_interactively(&resolved, &postponed, quit,
                                                external_failed,
                                                printed_summary,
@@ -2214,7 +2263,7 @@ svn_cl__resolve_conflict(svn_boolean_t *
                                                editor_cmd, ctx->config,
                                                path_prefix, pb,
                                                conflict_stats, ctx,
-                                               scratch_pool, scratch_pool);
+                                               iterpool);
           if (err && err->apr_err == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE)
             {
               /* Conflict resolution has failed. Let the user try again.
@@ -2226,6 +2275,7 @@ svn_cl__resolve_conflict(svn_boolean_t *
             }
           SVN_ERR(err);
         }
+      svn_pool_destroy(iterpool);
     }
   else if (option_id != svn_client_conflict_option_postpone)
     SVN_ERR(mark_conflict_resolved(conflict, option_id,

Modified: subversion/branches/better-pristines/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svn/diff-cmd.c?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/better-pristines/subversion/svn/diff-cmd.c Sun Sep 30 18:26:47 2018
@@ -181,6 +181,24 @@ summarize_regular(const svn_client_diff_
   return svn_cmdline_fflush(stdout);
 }
 
+svn_error_t *
+svn_cl__get_diff_summary_writer(svn_client_diff_summarize_func_t *func_p,
+                                void **baton_p,
+                                svn_boolean_t xml,
+                                svn_boolean_t ignore_properties,
+                                const char *anchor,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool)
+{
+  struct summarize_baton_t *b = apr_pcalloc(result_pool, sizeof(*b));
+
+  b->anchor = anchor;
+  b->ignore_properties = ignore_properties;
+  *func_p = xml ? summarize_xml : summarize_regular;
+  *baton_p = b;
+  return SVN_NO_ERROR;
+}
+
 /* An svn_opt_subcommand_t to handle the 'diff' command.
    This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
@@ -203,9 +221,6 @@ svn_cl__diff(apr_getopt_t *os,
   svn_boolean_t ignore_properties =
     opt_state->diff.patch_compatible || opt_state->diff.ignore_properties;
   int i;
-  struct summarize_baton_t summarize_baton;
-  const svn_client_diff_summarize_func_t summarize_func =
-    (opt_state->xml ? summarize_xml : summarize_regular);
 
   if (opt_state->extensions)
     options = svn_cstring_split(opt_state->extensions, " \t\n\r", TRUE, pool);
@@ -448,9 +463,13 @@ svn_cl__diff(apr_getopt_t *os,
 
           if (opt_state->diff.summarize)
             {
-              summarize_baton.anchor = target1;
-              summarize_baton.ignore_properties = ignore_properties;
+              svn_client_diff_summarize_func_t summarize_func;
+              void *summarize_baton;
 
+              SVN_ERR(svn_cl__get_diff_summary_writer(
+                                &summarize_func, &summarize_baton,
+                                opt_state->xml, ignore_properties, target1,
+                                iterpool, iterpool));
               SVN_ERR(svn_client_diff_summarize2(
                                 target1,
                                 &opt_state->start_revision,
@@ -459,7 +478,7 @@ svn_cl__diff(apr_getopt_t *os,
                                 opt_state->depth,
                                 ! opt_state->diff.notice_ancestry,
                                 opt_state->changelists,
-                                summarize_func, &summarize_baton,
+                                summarize_func, summarize_baton,
                                 ctx, iterpool));
             }
           else
@@ -502,8 +521,13 @@ svn_cl__diff(apr_getopt_t *os,
 
           if (opt_state->diff.summarize)
             {
-              summarize_baton.anchor = truepath;
-              summarize_baton.ignore_properties = ignore_properties;
+              svn_client_diff_summarize_func_t summarize_func;
+              void *summarize_baton;
+
+              SVN_ERR(svn_cl__get_diff_summary_writer(
+                                &summarize_func, &summarize_baton,
+                                opt_state->xml, ignore_properties, truepath,
+                                iterpool, iterpool));
               SVN_ERR(svn_client_diff_summarize_peg2(
                                 truepath,
                                 &peg_revision,
@@ -512,7 +536,7 @@ svn_cl__diff(apr_getopt_t *os,
                                 opt_state->depth,
                                 ! opt_state->diff.notice_ancestry,
                                 opt_state->changelists,
-                                summarize_func, &summarize_baton,
+                                summarize_func, summarize_baton,
                                 ctx, iterpool));
             }
           else

Modified: subversion/branches/better-pristines/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svn/info-cmd.c?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svn/info-cmd.c (original)
+++ subversion/branches/better-pristines/subversion/svn/info-cmd.c Sun Sep 30 18:26:47 2018
@@ -21,6 +21,10 @@
  * ====================================================================
  */
 
+/* We define this here to remove any further warnings about the usage of
+   experimental functions in this file. */
+#define SVN_EXPERIMENTAL
+
 /* ==================================================================== */
 
 
@@ -56,7 +60,7 @@ struct layout_list_baton_t
 
 /* Output as 'svn' command-line commands.
  *
- * Implements svn_client_layout_func_t
+ * Implements svn_client__layout_func_t
  */
 static svn_error_t *
 output_svn_command_line(void *layout_baton,
@@ -159,7 +163,7 @@ depth_to_viewspec_py(svn_depth_t depth,
 
 /* Output in the format used by 'tools/client-side/viewspec.py'
  *
- * Implements svn_client_layout_func_t
+ * Implements svn_client__layout_func_t
  */
 static svn_error_t *
 output_svn_viewspec_py(void *layout_baton,
@@ -238,8 +242,13 @@ output_svn_viewspec_py(void *layout_bato
   return SVN_NO_ERROR;
 }
 
+/*
+ * Call svn_client__layout_list(), using a receiver function decided
+ * by VIEWSPEC.
+ */
 static svn_error_t *
 cl_layout_list(apr_array_header_t *targets,
+               enum svn_cl__viewspec_t viewspec,
                void *baton,
                svn_client_ctx_t *ctx,
                apr_pool_t *scratch_pool)
@@ -265,22 +274,26 @@ cl_layout_list(apr_array_header_t *targe
   llb.target_abspath = list_abspath;
   llb.with_revs = TRUE;
 
-  if (TRUE)
+  switch (viewspec)
     {
+    case svn_cl__viewspec_classic:
       /* svn-viewspec.py format */
       llb.vs_py_format = 2;
 
-      SVN_ERR(svn_client_layout_list(list_abspath,
-                                     output_svn_viewspec_py, &llb,
-                                     ctx, scratch_pool));
-    }
-  else
-    {
+      SVN_ERR(svn_client__layout_list(list_abspath,
+                                      output_svn_viewspec_py, &llb,
+                                      ctx, scratch_pool));
+      break;
+    case svn_cl__viewspec_svn11:
       /* svn command-line format */
-      SVN_ERR(svn_client_layout_list(list_abspath,
-                                     output_svn_command_line, &llb,
-                                     ctx, scratch_pool));
+      SVN_ERR(svn_client__layout_list(list_abspath,
+                                      output_svn_command_line, &llb,
+                                      ctx, scratch_pool));
+      break;
+    default:
+      SVN_ERR_MALFUNCTION();
     }
+
   return SVN_NO_ERROR;
 }
 
@@ -1177,7 +1190,7 @@ svn_cl__info(apr_getopt_t *os,
 
   if (opt_state->viewspec)
     {
-      SVN_ERR(cl_layout_list(targets, baton, ctx, pool));
+      SVN_ERR(cl_layout_list(targets, opt_state->viewspec, baton, ctx, pool));
       return SVN_NO_ERROR;
     }
 

Modified: subversion/branches/better-pristines/subversion/svn/shelf-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svn/shelf-cmd.c?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svn/shelf-cmd.c (original)
+++ subversion/branches/better-pristines/subversion/svn/shelf-cmd.c Sun Sep 30 18:26:47 2018
@@ -1,5 +1,5 @@
 /*
- * shelve-cmd.c -- Shelve commands.
+ * shelf-cmd.c -- Shelving commands.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -31,14 +31,35 @@
 #include "svn_hash.h"
 #include "svn_path.h"
 #include "svn_props.h"
+#include "svn_pools.h"
 #include "svn_utf.h"
 
 #include "cl.h"
 
 #include "svn_private_config.h"
 #include "private/svn_sorts_private.h"
+#include "private/svn_client_private.h"
 
 
+/* Open the newest version of SHELF; error if no versions found. */
+static svn_error_t *
+get_newest_version_existing(svn_client__shelf_version_t **shelf_version_p,
+                            svn_client__shelf_t *shelf,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_client__shelf_get_newest_version(shelf_version_p, shelf,
+                                              result_pool, scratch_pool));
+  if (!*shelf_version_p)
+    {
+      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                               _("Shelf '%s': no versions found"),
+                               shelf->name);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Fetch the next argument. */
 static svn_error_t *
 get_next_argument(const char **arg,
@@ -64,10 +85,10 @@ get_next_argument(const char **arg,
  */
 static svn_error_t *
 targets_relative_to_wcs(apr_hash_t **targets_by_wcroot_p,
-                         apr_array_header_t *targets,
-                         svn_client_ctx_t *ctx,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool)
+                        apr_array_header_t *targets,
+                        svn_client_ctx_t *ctx,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
 {
   apr_hash_t *targets_by_wcroot = apr_hash_make(result_pool);
   int i;
@@ -162,14 +183,14 @@ static int
 compare_shelf_infos_by_mtime(const svn_sort__item_t *a,
                              const svn_sort__item_t *b)
 {
-  svn_client_shelf_info_t *a_val = a->value;
-  svn_client_shelf_info_t *b_val = b->value;
+  svn_client__shelf_info_t *a_val = a->value;
+  svn_client__shelf_info_t *b_val = b->value;
 
   return (a_val->mtime < b_val->mtime)
-           ? -1 : (a_val->mtime > b_val->mtime) ? 1 : 0;
+    ? -1 : (a_val->mtime > b_val->mtime) ? 1 : 0;
 }
 
-/* Return a list of shelves sorted by patch file mtime, oldest first.
+/* Return a list of shelves sorted by their mtime, oldest first.
  */
 static svn_error_t *
 list_sorted_by_date(apr_array_header_t **list,
@@ -179,7 +200,7 @@ list_sorted_by_date(apr_array_header_t *
 {
   apr_hash_t *shelf_infos;
 
-  SVN_ERR(svn_client_shelf_list(&shelf_infos, local_abspath,
+  SVN_ERR(svn_client__shelf_list(&shelf_infos, local_abspath,
                                 ctx, scratch_pool, scratch_pool));
   *list = svn_sort__hash(shelf_infos,
                          compare_shelf_infos_by_mtime,
@@ -189,9 +210,9 @@ list_sorted_by_date(apr_array_header_t *
 
 /*  */
 static svn_error_t *
-stats(svn_client_shelf_t *shelf,
+stats(svn_client__shelf_t *shelf,
       int version,
-      svn_client_shelf_version_t *shelf_version,
+      svn_client__shelf_version_t *shelf_version,
       apr_time_t time_now,
       svn_boolean_t with_logmsg,
       apr_pool_t *scratch_pool)
@@ -215,7 +236,7 @@ stats(svn_client_shelf_t *shelf,
                                Q_("version %d of %d", "version %d of %d",
                                   shelf->max_version),
                                version, shelf->max_version);
-  SVN_ERR(svn_client_shelf_paths_changed(&paths, shelf_version,
+  SVN_ERR(svn_client__shelf_paths_changed(&paths, shelf_version,
                                          scratch_pool, scratch_pool));
   paths_str = apr_psprintf(scratch_pool,
                            Q_("%d path changed", "%d paths changed",
@@ -229,7 +250,7 @@ stats(svn_client_shelf_t *shelf,
     {
       char *log_message;
 
-      SVN_ERR(svn_client_shelf_get_log_message(&log_message, shelf,
+      SVN_ERR(svn_client__shelf_get_log_message(&log_message, shelf,
                                                scratch_pool));
       if (log_message)
         {
@@ -260,19 +281,22 @@ shelves_list(const char *local_abspath,
     {
       const svn_sort__item_t *item = &APR_ARRAY_IDX(list, i, svn_sort__item_t);
       const char *name = item->key;
-      svn_client_shelf_t *shelf;
-      svn_client_shelf_version_t *shelf_version;
+      svn_client__shelf_t *shelf;
+      svn_client__shelf_version_t *shelf_version;
 
-      SVN_ERR(svn_client_shelf_open_existing(&shelf, name, local_abspath,
+      SVN_ERR(svn_client__shelf_open_existing(&shelf, name, local_abspath,
                                              ctx, scratch_pool));
-      SVN_ERR(svn_client_shelf_get_newest_version(&shelf_version, shelf,
+      SVN_ERR(svn_client__shelf_get_newest_version(&shelf_version, shelf,
                                                   scratch_pool, scratch_pool));
-      if (quiet || !shelf_version)
+      if (quiet)
         SVN_ERR(svn_cmdline_printf(scratch_pool, "%s\n", shelf->name));
+      else if (!shelf_version)
+        SVN_ERR(svn_cmdline_printf(scratch_pool, "%-30s no versions\n",
+                                   shelf->name));
       else
         SVN_ERR(stats(shelf, shelf->max_version, shelf_version, time_now,
                       TRUE /*with_logmsg*/, scratch_pool));
-      SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+      SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -287,24 +311,24 @@ shelf_log(const char *name,
           apr_pool_t *scratch_pool)
 {
   apr_time_t time_now = apr_time_now();
-  svn_client_shelf_t *shelf;
+  svn_client__shelf_t *shelf;
   apr_array_header_t *versions;
   int i;
 
-  SVN_ERR(svn_client_shelf_open_existing(&shelf, name, local_abspath,
+  SVN_ERR(svn_client__shelf_open_existing(&shelf, name, local_abspath,
                                          ctx, scratch_pool));
-  SVN_ERR(svn_client_shelf_get_all_versions(&versions, shelf,
-                                        scratch_pool, scratch_pool));
+  SVN_ERR(svn_client__shelf_get_all_versions(&versions, shelf,
+                                            scratch_pool, scratch_pool));
   for (i = 0; i < versions->nelts; i++)
     {
-      svn_client_shelf_version_t *shelf_version
+      svn_client__shelf_version_t *shelf_version
         = APR_ARRAY_IDX(versions, i, void *);
 
       SVN_ERR(stats(shelf, i + 1, shelf_version, time_now,
                     FALSE /*with_logmsg*/, scratch_pool));
     }
 
-  SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+  SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -331,45 +355,6 @@ name_of_youngest(const char **name_p,
   return SVN_NO_ERROR;
 }
 
-/*
- * PATHS are relative to WC_ROOT_ABSPATH.
- */
-static svn_error_t *
-run_status_on_wc_paths(const char *paths_base_abspath,
-                       const apr_array_header_t *paths,
-                       svn_depth_t depth,
-                       const apr_array_header_t *changelists,
-                       svn_client_status_func_t status_func,
-                       void *status_baton,
-                       svn_client_ctx_t *ctx,
-                       apr_pool_t *scratch_pool)
-{
-  int i;
-
-  for (i = 0; i < paths->nelts; i++)
-    {
-      const char *path = APR_ARRAY_IDX(paths, i, const char *);
-      const char *abspath = svn_dirent_join(paths_base_abspath, path,
-                                            scratch_pool);
-
-      SVN_ERR(svn_client_status6(NULL /*result_rev*/,
-                                 ctx, abspath,
-                                 NULL /*revision*/,
-                                 depth,
-                                 FALSE /*get_all*/,
-                                 FALSE /*check_out_of_date*/,
-                                 TRUE /*check_working_copy*/,
-                                 TRUE /*no_ignore*/,
-                                 TRUE /*ignore_externals*/,
-                                 FALSE /*depth_as_sticky*/,
-                                 changelists,
-                                 status_func, status_baton,
-                                 scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 struct status_baton
 {
   /* These fields correspond to the ones in the
@@ -377,9 +362,9 @@ struct status_baton
   const char *target_abspath;
   const char *target_path;
 
-  const char *header;
-  svn_boolean_t quiet;  /* don't display statuses while checking them */
-  svn_boolean_t modified;  /* set to TRUE when any modification is found */
+  svn_boolean_t quiet;  /* don't display statuses while shelving them */
+  int num_paths_shelved;
+  int num_paths_not_shelved;
   svn_client_ctx_t *ctx;
 };
 
@@ -388,7 +373,7 @@ static svn_error_t *
 print_status(void *baton,
              const char *path,
              const svn_client_status_t *status,
-             apr_pool_t *pool)
+             apr_pool_t *scratch_pool)
 {
   struct status_baton *sb = baton;
   unsigned int conflicts;
@@ -402,37 +387,39 @@ print_status(void *baton,
                               FALSE /*repos_locks*/,
                               &conflicts, &conflicts, &conflicts,
                               sb->ctx,
-                              pool);
+                              scratch_pool);
 }
 
-/* Set BATON->modified to true if TARGET has any local modification or
- * any status that means we should not attempt to patch it.
- *
- * A callback of type svn_client_status_func_t. */
+/* A callback function for shelved paths. */
 static svn_error_t *
-modification_checker(void *baton,
-                     const char *target,
-                     const svn_client_status_t *status,
-                     apr_pool_t *scratch_pool)
+was_shelved(void *baton,
+            const char *path,
+            const svn_client_status_t *status,
+            apr_pool_t *scratch_pool)
 {
   struct status_baton *sb = baton;
 
-  if (status->conflicted
-      || ! (status->node_status == svn_wc_status_none
-            || status->node_status == svn_wc_status_unversioned
-            || status->node_status == svn_wc_status_normal))
+  if (!sb->quiet)
     {
-      if (!sb->quiet)
-        {
-          if (!sb->modified)  /* print the header only once */
-            {
-              SVN_ERR(svn_cmdline_printf(scratch_pool, "%s", sb->header));
-            }
-          SVN_ERR(print_status(baton, target, status, scratch_pool));
-        }
-
-      sb->modified = TRUE;
+      SVN_ERR(print_status(baton, path, status, scratch_pool));
     }
+
+  ++sb->num_paths_shelved;
+  return SVN_NO_ERROR;
+}
+
+/* A callback function for not-shelved paths. */
+static svn_error_t *
+was_not_shelved(void *baton,
+                const char *path,
+                const svn_client_status_t *status,
+                apr_pool_t *scratch_pool)
+{
+  struct status_baton *sb = baton;
+
+  SVN_ERR(print_status(baton, path, status, scratch_pool));
+  SVN_ERR(svn_cmdline_printf(scratch_pool, "      >   not shelved\n"));
+  ++sb->num_paths_not_shelved;
   return SVN_NO_ERROR;
 }
 
@@ -463,65 +450,67 @@ shelve(int *new_version_p,
        svn_client_ctx_t *ctx,
        apr_pool_t *scratch_pool)
 {
-  svn_client_shelf_t *shelf;
-  svn_client_shelf_version_t *previous_version;
-  svn_client_shelf_version_t *new_version;
-  const char *cwd_abspath;
+  svn_client__shelf_t *shelf;
+  svn_client__shelf_version_t *previous_version;
+  svn_client__shelf_version_t *new_version;
   struct status_baton sb;
 
-  SVN_ERR(svn_client_shelf_open_or_create(&shelf,
+  SVN_ERR(svn_client__shelf_open_or_create(&shelf,
                                           name, local_abspath,
                                           ctx, scratch_pool));
-  SVN_ERR(svn_client_shelf_get_newest_version(&previous_version, shelf,
+  SVN_ERR(svn_client__shelf_get_newest_version(&previous_version, shelf,
                                               scratch_pool, scratch_pool));
 
   if (! quiet)
     {
       SVN_ERR(svn_cmdline_printf(scratch_pool, keep_local
-        ? _("--- Save a new version of '%s' in WC root '%s'\n")
-        : _("--- Shelve '%s' in WC root '%s'\n"),
-        shelf->name, shelf->wc_root_abspath));
+                                 ? _("--- Save a new version of '%s' in WC root '%s'\n")
+                                 : _("--- Shelve '%s' in WC root '%s'\n"),
+                                 shelf->name, shelf->wc_root_abspath));
       SVN_ERR(stats(shelf, shelf->max_version, previous_version, apr_time_now(),
                     TRUE /*with_logmsg*/, scratch_pool));
     }
 
-  sb.header = (keep_local
-               ? _("--- Modifications to save:\n")
-               : _("--- Modifications to shelve:\n"));
+  sb.target_abspath = shelf->wc_root_abspath;
+  sb.target_path = "";
   sb.quiet = quiet;
-  sb.modified = FALSE;
+  sb.num_paths_shelved = 0;
+  sb.num_paths_not_shelved = 0;
   sb.ctx = ctx;
-  SVN_ERR(svn_dirent_get_absolute(&cwd_abspath, "", scratch_pool));
-  SVN_ERR(run_status_on_wc_paths(cwd_abspath, paths, depth, changelists,
-                                 modification_checker, &sb,
-                                 ctx, scratch_pool));
-
-  if (!sb.modified)
-    {
-      SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
-      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                               _("No local modifications found"));
-    }
 
   if (! quiet)
     SVN_ERR(svn_cmdline_printf(scratch_pool,
                                keep_local ? _("--- Saving...\n")
-                                          : _("--- Shelving...\n")));
-  SVN_ERR(svn_client_shelf_save_new_version2(&new_version, shelf,
+                               : _("--- Shelving...\n")));
+  SVN_ERR(svn_client__shelf_save_new_version3(&new_version, shelf,
                                              paths, depth, changelists,
+                                             was_shelved, &sb,
+                                             was_not_shelved, &sb,
                                              scratch_pool));
-  if (! new_version)
+  if (sb.num_paths_not_shelved > 0)
     {
-      SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+      SVN_ERR(svn_client__shelf_delete_newer_versions(shelf, previous_version,
+                                                     scratch_pool));
+      SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
       return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-        keep_local ? _("None of the local modifications could be saved")
-                   : _("None of the local modifications could be shelved"));
+                               Q_("%d path could not be shelved",
+                                  "%d paths could not be shelved",
+                                  sb.num_paths_not_shelved),
+                               sb.num_paths_not_shelved);
+    }
+  if (sb.num_paths_shelved == 0
+      || ! new_version)
+    {
+      SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
+      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                               keep_local ? _("No local modifications could be saved")
+                               : _("No local modifications could be shelved"));
     }
 
-  /* Un-apply the patch, if required. */
+  /* Un-apply the changes, if required. */
   if (!keep_local)
     {
-      SVN_ERR(svn_client_shelf_unapply(new_version,
+      SVN_ERR(svn_client__shelf_unapply(new_version,
                                        dry_run, scratch_pool));
     }
 
@@ -549,69 +538,84 @@ shelve(int *new_version_p,
         }
     }
 
-  SVN_ERR(svn_client_shelf_revprop_set_all(shelf, revprop_table, scratch_pool));
+  SVN_ERR(svn_client__shelf_revprop_set_all(shelf, revprop_table, scratch_pool));
 
   if (new_version_p)
     *new_version_p = shelf->max_version;
 
   if (dry_run)
     {
-      SVN_ERR(svn_client_shelf_delete_newer_versions(shelf, previous_version,
+      SVN_ERR(svn_client__shelf_delete_newer_versions(shelf, previous_version,
                                                      scratch_pool));
     }
 
-  SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+  SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
   return SVN_NO_ERROR;
 }
 
+/* Return the single character representation of STATUS.
+ * (Similar to subversion/svn/status.c:generate_status_code()
+ * and subversion/tests/libsvn_client/client-test.c:status_to_char().) */
+static char
+status_to_char(enum svn_wc_status_kind status)
+{
+  switch (status)
+    {
+    case svn_wc_status_none:        return '.';
+    case svn_wc_status_unversioned: return '?';
+    case svn_wc_status_normal:      return ' ';
+    case svn_wc_status_added:       return 'A';
+    case svn_wc_status_missing:     return '!';
+    case svn_wc_status_deleted:     return 'D';
+    case svn_wc_status_replaced:    return 'R';
+    case svn_wc_status_modified:    return 'M';
+    case svn_wc_status_merged:      return 'G';
+    case svn_wc_status_conflicted:  return 'C';
+    case svn_wc_status_ignored:     return 'I';
+    case svn_wc_status_obstructed:  return '~';
+    case svn_wc_status_external:    return 'X';
+    case svn_wc_status_incomplete:  return ':';
+    default:                        return '*';
+    }
+}
+
 /* Throw an error if any path affected by SHELF_VERSION gives a conflict
  * when applied (as a dry-run) to the WC. */
 static svn_error_t *
-test_apply(svn_client_shelf_version_t *shelf_version,
+test_apply(svn_client__shelf_version_t *shelf_version,
            svn_client_ctx_t *ctx,
            apr_pool_t *scratch_pool)
 {
   apr_hash_t *paths;
   apr_hash_index_t *hi;
 
-  SVN_ERR(svn_client_shelf_paths_changed(&paths, shelf_version,
+  SVN_ERR(svn_client__shelf_paths_changed(&paths, shelf_version,
                                          scratch_pool, scratch_pool));
   for (hi = apr_hash_first(scratch_pool, paths); hi; hi = apr_hash_next(hi))
     {
       const char *path = apr_hash_this_key(hi);
       svn_boolean_t conflict;
 
-      SVN_ERR(svn_client_shelf_test_apply_file(&conflict, shelf_version, path,
+      SVN_ERR(svn_client__shelf_test_apply_file(&conflict, shelf_version, path,
                                                scratch_pool));
       if (conflict)
-        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                                 _("Conflict in applying shelf '%s' path '%s'"),
-                                 shelf_version->shelf->name, path);
+        {
+          char *to_wc_abspath
+            = svn_dirent_join(shelf_version->shelf->wc_root_abspath, path,
+                              scratch_pool);
+          svn_wc_status3_t *status;
+
+          SVN_ERR(svn_wc_status3(&status, ctx->wc_ctx, to_wc_abspath,
+                                 scratch_pool, scratch_pool));
+          return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                   _("Shelved path '%s' already has "
+                                     "status '%c' in the working copy"),
+                                   path, status_to_char(status->node_status));
+        }
     }
   return SVN_NO_ERROR;
 }
 
-/* Intercept patch notifications to detect when there is a conflict */
-struct patch_notify_baton_t
-{
-  svn_wc_notify_func2_t notify_func;
-  void *notify_baton;
-  svn_boolean_t rejects;
-};
-
-/* Intercept patch notifications to detect when there is a conflict */
-static void
-patch_notify(void *baton,
-             const svn_wc_notify_t *notify,
-             apr_pool_t *pool)
-{
-  struct patch_notify_baton_t *b = baton;
-
-  if (notify->action == svn_wc_notify_patch_rejected_hunk)
-    b->rejects = TRUE;
-  b->notify_func(b->notify_baton, notify, pool);
-}
-
 /** Restore/unshelve a given or newest version of changes.
  *
  * Restore local modifications from shelf @a name version @a arg,
@@ -633,26 +637,25 @@ shelf_restore(const char *name,
 {
   int version, old_version;
   apr_time_t time_now = apr_time_now();
-  svn_client_shelf_t *shelf;
-  svn_client_shelf_version_t *shelf_version;
-  struct patch_notify_baton_t b;
+  svn_client__shelf_t *shelf;
+  svn_client__shelf_version_t *shelf_version;
 
-  SVN_ERR(svn_client_shelf_open_existing(&shelf, name, local_abspath,
+  SVN_ERR(svn_client__shelf_open_existing(&shelf, name, local_abspath,
                                          ctx, scratch_pool));
 
   old_version = shelf->max_version;
   if (arg)
     {
       SVN_ERR(svn_cstring_atoi(&version, arg));
-      SVN_ERR(svn_client_shelf_version_open(&shelf_version,
+      SVN_ERR(svn_client__shelf_version_open(&shelf_version,
                                             shelf, version,
                                             scratch_pool, scratch_pool));
     }
   else
     {
       version = shelf->max_version;
-      SVN_ERR(svn_client_shelf_get_newest_version(&shelf_version, shelf,
-                                                  scratch_pool, scratch_pool));
+      SVN_ERR(get_newest_version_existing(&shelf_version, shelf,
+                                          scratch_pool, scratch_pool));
     }
 
   if (! quiet)
@@ -666,30 +669,17 @@ shelf_restore(const char *name,
   if (! force_if_conflict)
     {
       SVN_ERR_W(test_apply(shelf_version, ctx, scratch_pool),
-                _("Cannot unshelve/restore, as at least one "
-                  "path would conflict"));
+                _("Cannot unshelve/restore, as at least one shelved "
+                  "path would conflict with a local modification "
+                  "or other status in the working copy"));
     }
 
-  b.rejects = FALSE;
-  b.notify_func = ctx->notify_func2;
-  b.notify_baton = ctx->notify_baton2;
-  ctx->notify_func2 = patch_notify;
-  ctx->notify_baton2 = &b;
-
-  SVN_ERR(svn_client_shelf_apply(shelf_version,
+  SVN_ERR(svn_client__shelf_apply(shelf_version,
                                  dry_run, scratch_pool));
-  ctx->notify_func2 = b.notify_func;
-  ctx->notify_baton2 = b.notify_baton;
-
-  if (b.rejects)
-    {
-      return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
-                              _("Unshelve/restore failed due to conflicts"));
-    }
 
   if (! dry_run)
     {
-      SVN_ERR(svn_client_shelf_delete_newer_versions(shelf, shelf_version,
+      SVN_ERR(svn_client__shelf_delete_newer_versions(shelf, shelf_version,
                                                      scratch_pool));
     }
 
@@ -697,17 +687,17 @@ shelf_restore(const char *name,
     {
       if (version < old_version)
         SVN_ERR(svn_cmdline_printf(scratch_pool,
-                  Q_("restored '%s' version %d and deleted %d newer version\n",
-                     "restored '%s' version %d and deleted %d newer versions\n",
-                     old_version - version),
-                  name, version, old_version - version));
+                                   Q_("restored '%s' version %d and deleted %d newer version\n",
+                                      "restored '%s' version %d and deleted %d newer versions\n",
+                                      old_version - version),
+                                   name, version, old_version - version));
       else
         SVN_ERR(svn_cmdline_printf(scratch_pool,
                                    _("restored '%s' version %d (the newest version)\n"),
                                    name, version));
     }
 
-  SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+  SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -715,14 +705,18 @@ static svn_error_t *
 shelf_diff(const char *name,
            const char *arg,
            const char *local_abspath,
+           svn_boolean_t summarize,
+           svn_depth_t depth,
+           svn_boolean_t ignore_ancestry,
            svn_client_ctx_t *ctx,
            apr_pool_t *scratch_pool)
 {
-  svn_client_shelf_t *shelf;
-  svn_client_shelf_version_t *shelf_version;
-  svn_stream_t *stream;
+  svn_client__shelf_t *shelf;
+  svn_client__shelf_version_t *shelf_version;
+  svn_stream_t *stream, *errstream;
+  svn_diff_tree_processor_t *diff_processor;
 
-  SVN_ERR(svn_client_shelf_open_existing(&shelf, name, local_abspath,
+  SVN_ERR(svn_client__shelf_open_existing(&shelf, name, local_abspath,
                                          ctx, scratch_pool));
 
   if (arg)
@@ -730,22 +724,60 @@ shelf_diff(const char *name,
       int version;
 
       SVN_ERR(svn_cstring_atoi(&version, arg));
-      SVN_ERR(svn_client_shelf_version_open(&shelf_version,
+      SVN_ERR(svn_client__shelf_version_open(&shelf_version,
                                             shelf, version,
                                             scratch_pool, scratch_pool));
     }
   else
     {
-      SVN_ERR(svn_client_shelf_get_newest_version(&shelf_version, shelf,
-                                                  scratch_pool, scratch_pool));
+      SVN_ERR(get_newest_version_existing(&shelf_version, shelf,
+                                          scratch_pool, scratch_pool));
     }
 
   SVN_ERR(svn_stream_for_stdout(&stream, scratch_pool));
-  SVN_ERR(svn_client_shelf_export_patch(shelf_version, stream,
-                                        scratch_pool));
+  errstream = svn_stream_empty(scratch_pool);
+
+  if (summarize)
+    {
+      svn_client_diff_summarize_func_t func;
+      void *baton;
+
+      SVN_ERR(svn_cl__get_diff_summary_writer(&func, &baton,
+                                              FALSE /*xml*/,
+                                              FALSE /*ignore_properties*/,
+                                              "" /*anchor/prefix*/,
+                                              scratch_pool, scratch_pool));
+      SVN_ERR(svn_client__get_diff_summarize_callbacks(&diff_processor,
+                                                       func, baton,
+                                                       scratch_pool,
+                                                       scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(svn_client__get_diff_writer_svn(
+                &diff_processor,
+                NULL /*anchor*/,
+                "", "", /*orig_path_1, orig_path_2,*/
+                NULL /*options*/,
+                "" /*relative_to_dir*/,
+                FALSE /*no_diff_added*/,
+                FALSE /*no_diff_deleted*/,
+                FALSE /*show_copies_as_adds*/,
+                FALSE /*ignore_content_type*/,
+                FALSE /*ignore_properties*/,
+                FALSE /*properties_only*/,
+                TRUE /*pretty_print_mergeinfo*/,
+                svn_cmdline_output_encoding(scratch_pool),
+                stream, errstream,
+                ctx, scratch_pool));
+    }
+
+  SVN_ERR(svn_client__shelf_diff(shelf_version, "",
+                                 depth, ignore_ancestry,
+                                 diff_processor, scratch_pool));
   SVN_ERR(svn_stream_close(stream));
 
-  SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+  SVN_ERR(svn_client__shelf_close(shelf, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -758,7 +790,7 @@ shelf_drop(const char *name,
            svn_client_ctx_t *ctx,
            apr_pool_t *scratch_pool)
 {
-  SVN_ERR(svn_client_shelf_delete(name, local_abspath, dry_run,
+  SVN_ERR(svn_client__shelf_delete(name, local_abspath, dry_run,
                                   ctx, scratch_pool));
   if (! quiet)
     SVN_ERR(svn_cmdline_printf(scratch_pool,
@@ -840,35 +872,35 @@ svn_cl__shelf_shelve(apr_getopt_t *os,
                                                       opt_state->targets,
                                                       ctx, FALSE, pool));
   {
-      int new_version;
-      svn_error_t *err;
+    int new_version;
+    svn_error_t *err;
 
-      if (ctx->log_msg_func3)
-        SVN_ERR(svn_cl__make_log_msg_baton(&ctx->log_msg_baton3,
-                                           opt_state, NULL, ctx->config,
-                                           pool));
-      err = shelf_shelve(&new_version, name,
-                         targets, opt_state->depth, opt_state->changelists,
-                         opt_state->revprop_table,
-                         opt_state->keep_local, opt_state->dry_run,
-                         opt_state->quiet, ctx, pool);
-      if (ctx->log_msg_func3)
-        SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3,
-                                        err, pool));
-      else
-        SVN_ERR(err);
+    if (ctx->log_msg_func3)
+      SVN_ERR(svn_cl__make_log_msg_baton(&ctx->log_msg_baton3,
+                                         opt_state, NULL, ctx->config,
+                                         pool));
+    err = shelf_shelve(&new_version, name,
+                       targets, opt_state->depth, opt_state->changelists,
+                       opt_state->revprop_table,
+                       opt_state->keep_local, opt_state->dry_run,
+                       opt_state->quiet, ctx, pool);
+    if (ctx->log_msg_func3)
+      SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3,
+                                      err, pool));
+    else
+      SVN_ERR(err);
 
       if (! opt_state->quiet)
-        {
-          if (opt_state->keep_local)
-            SVN_ERR(svn_cmdline_printf(pool,
-                                       _("saved '%s' version %d\n"),
-                                       name, new_version));
-          else
-            SVN_ERR(svn_cmdline_printf(pool,
-                                       _("shelved '%s' version %d\n"),
-                                       name, new_version));
-        }
+      {
+        if (opt_state->keep_local)
+          SVN_ERR(svn_cmdline_printf(pool,
+                                     _("saved '%s' version %d\n"),
+                                     name, new_version));
+        else
+          SVN_ERR(svn_cmdline_printf(pool,
+                                     _("shelved '%s' version %d\n"),
+                                     name, new_version));
+      }
   }
 
   return SVN_NO_ERROR;
@@ -934,16 +966,31 @@ svn_cl__shelf_list(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;
-  const char *local_abspath;
+  apr_array_header_t *targets = NULL;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  int i;
 
-  /* There should be no remaining arguments. */
-  if (os->ind < os->argc)
-    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE, pool));
+  /* Add "." if user passed 0 arguments */
+  svn_opt_push_implicit_dot_target(targets, pool);
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
-  SVN_ERR(shelves_list(local_abspath,
-                       opt_state->quiet,
-                       ctx, pool));
+  for (i = 0; i < targets->nelts; ++i)
+    {
+      const char *local_abspath;
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
+
+      SVN_ERR(shelves_list(local_abspath,
+                           opt_state->quiet,
+                           ctx, iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -982,19 +1029,21 @@ shelf_list_by_paths(apr_array_header_t *
     {
       svn_sort__item_t *item = &APR_ARRAY_IDX(shelves, i, svn_sort__item_t);
       const char *name = item->key;
-      svn_client_shelf_t *shelf;
-      svn_client_shelf_version_t *shelf_version;
+      svn_client__shelf_t *shelf;
+      svn_client__shelf_version_t *shelf_version;
       apr_hash_t *shelf_paths;
       int j;
 
-      SVN_ERR(svn_client_shelf_open_existing(&shelf,
-                                             name, wc_root_abspath,
-                                             ctx, scratch_pool));
-      SVN_ERR(svn_client_shelf_get_newest_version(&shelf_version, shelf,
-                                                  scratch_pool, scratch_pool));
-      SVN_ERR(svn_client_shelf_paths_changed(&shelf_paths,
-                                             shelf_version,
-                                             scratch_pool, scratch_pool));
+      SVN_ERR(svn_client__shelf_open_existing(&shelf,
+                                              name, wc_root_abspath,
+                                              ctx, scratch_pool));
+      SVN_ERR(svn_client__shelf_get_newest_version(&shelf_version, shelf,
+                                                   scratch_pool, scratch_pool));
+      if (!shelf_version)
+        continue;
+      SVN_ERR(svn_client__shelf_paths_changed(&shelf_paths,
+                                              shelf_version,
+                                              scratch_pool, scratch_pool));
       for (j = 0; j < target_relpaths->nelts; j++)
         {
           char *target_relpath = APR_ARRAY_IDX(target_relpaths, j, char *);
@@ -1059,6 +1108,7 @@ svn_cl__shelf_diff(apr_getopt_t *os,
                    void *baton,
                    apr_pool_t *pool)
 {
+  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;
   const char *local_abspath;
   const char *name;
@@ -1076,7 +1126,10 @@ svn_cl__shelf_diff(apr_getopt_t *os,
     return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                             _("Too many arguments"));
 
-  SVN_ERR(shelf_diff(name, arg, local_abspath, ctx, pool));
+  SVN_ERR(shelf_diff(name, arg, local_abspath,
+                     opt_state->diff.summarize,
+                     opt_state->depth, opt_state->ignore_ancestry,
+                     ctx, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1090,18 +1143,31 @@ svn_cl__shelf_drop(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;
   const char *name;
-  const char *local_abspath;
+  apr_array_header_t *targets = NULL;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  int i;
 
   SVN_ERR(get_next_argument(&name, os, pool, pool));
 
-  /* There should be no remaining arguments. */
-  if (os->ind < os->argc)
-    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE, pool));
+  svn_opt_push_implicit_dot_target(targets, pool);
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
-  SVN_ERR(shelf_drop(name, local_abspath,
-                     opt_state->dry_run, opt_state->quiet,
-                     ctx, pool));
+  for (i = 0; i < targets->nelts; ++i)
+    {
+      const char *local_abspath;
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
+      SVN_ERR(shelf_drop(name, local_abspath,
+                         opt_state->dry_run, opt_state->quiet,
+                         ctx, iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -1112,20 +1178,32 @@ svn_cl__shelf_log(apr_getopt_t *os,
                   void *baton,
                   apr_pool_t *pool)
 {
+  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;
   const char *name;
-  const char *local_abspath;
+  apr_array_header_t *targets = NULL;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  int i;
 
   SVN_ERR(get_next_argument(&name, os, pool, pool));
 
-  /* There should be no remaining arguments. */
-  if (os->ind < os->argc)
-    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
-                            _("Too many arguments"));
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE, pool));
+  svn_opt_push_implicit_dot_target(targets, pool);
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
-  SVN_ERR(shelf_log(name, local_abspath,
-                    ctx, pool));
+  for (i = 0; i < targets->nelts; ++i)
+    {
+      const char *local_abspath;
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
+      SVN_ERR(shelf_log(name, local_abspath, ctx, iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/better-pristines/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svn/svn.c?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svn/svn.c (original)
+++ subversion/branches/better-pristines/subversion/svn/svn.c Sun Sep 30 18:26:47 2018
@@ -481,8 +481,10 @@ const apr_getopt_option_t svn_cl__option
   {"drop", opt_drop, 0,
    N_("drop shelf after successful unshelve")},
 
-  {"viewspec", opt_viewspec, 0,
-   N_("print the working copy layout")},
+  {"x-viewspec", opt_viewspec, 1,
+                       N_("print the working copy layout, formatted according\n"
+                          "                             "
+                          "to ARG: 'classic' or 'svn11'")},
 
   {"compatible-version", opt_compatible_version, 1,
                        N_("use working copy format compatible with Subversion\n"
@@ -830,7 +832,7 @@ const svn_opt_subcommand_desc3_t svn_cl_
      "  about TARGET.\n"
      "\n"), N_(
      "  EXPERIMENTAL:\n"
-     "  With --viewspec, print the working copy layout.\n"
+     "  With --x-viewspec, print the working copy layout.\n"
     )},
     {'r', 'R', opt_depth, opt_targets, opt_incremental, opt_xml,
      opt_changelist, opt_include_externals, opt_show_item, opt_no_newline,
@@ -993,6 +995,10 @@ const svn_opt_subcommand_desc3_t svn_cl_
      "    was created:\n"
      "      svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\n"
      "\n"), N_(
+     "    Show all log messages for commits between the tags ^/tags/2.0 and\n"
+     "    ^/tags/3.0; assuming that tag 2.0 was created in revision 100:\n"
+     "      svn log -rHEAD:100 ^/tags/3.0\n"
+     "\n"), N_(
      "    If ^/trunk/foo.c was moved to ^/trunk/bar.c' in revision 22, 'svn log -v'\n"
      "    shows a deletion and a copy in its changed paths list, such as:\n"
      "       D /trunk/foo.c\n"
@@ -1956,35 +1962,40 @@ const svn_opt_subcommand_desc3_t svn_cl_
     )},
     { 'q', opt_compatible_version } },
 
-  { "x-shelf-diff", svn_cl__shelf_diff, {"shelf-diff"}, {N_(
+  { "x-shelf-diff", svn_cl__shelf_diff, {0}, {N_(
      "Show shelved changes as a diff.\n"
-     "usage: x-shelf-diff NAME [VERSION]\n"
+     "usage: x-shelf-diff SHELF [VERSION]\n"
+     "\n"), N_(
+     "  Show the changes in SHELF:VERSION (default: latest) as a diff.\n"
      "\n"), N_(
-     "  Show the changes in shelf NAME:VERSION (default: latest) as a diff.\n"
+     "  See also: 'svn diff --cl=svn:shelf:SHELF' which supports most options of\n"
+     "  'svn diff'.\n"
      "\n"), N_(
      "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
      "  in the next release, and there is no promise of backward compatibility.\n"
     )},
+    {opt_summarize},
   },
 
-  { "x-shelf-drop", svn_cl__shelf_drop, {"shelf-drop"}, {N_(
+  { "x-shelf-drop", svn_cl__shelf_drop, {0}, {N_(
      "Delete a shelf.\n"
-     "usage: x-shelf-drop NAME\n"
+     "usage: x-shelf-drop SHELF [PATH ...]\n"
      "\n"), N_(
-     "  Delete the shelf named NAME.\n"
+     "  Delete the shelves named SHELF from the working copies containing PATH\n"
+     "  (default PATH is '.')\n"
      "\n"), N_(
      "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
      "  in the next release, and there is no promise of backward compatibility.\n"
     )},
   },
 
-  { "x-shelf-list", svn_cl__shelf_list, {"shelf-list", "shelves"}, {N_(
+  { "x-shelf-list", svn_cl__shelf_list, {"x-shelves"}, {N_(
      "List shelves.\n"
-     "usage: x-shelf-list\n"
+     "usage: x-shelf-list [PATH ...]\n"
      "\n"), N_(
-     "  List shelves. Include the first line of any log message\n"
-     "  and some details about the contents of the shelf, unless '-q' is\n"
-     "  given.\n"
+     "  List shelves for each working copy containing PATH (default is '.')\n"
+     "  Include the first line of any log message and some details about the\n"
+     "  contents of the shelf, unless '-q' is given.\n"
      "\n"), N_(
      "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
      "  in the next release, and there is no promise of backward compatibility.\n"
@@ -1992,7 +2003,7 @@ const svn_opt_subcommand_desc3_t svn_cl_
     {'q', 'v'}
   },
 
-  { "x-shelf-list-by-paths", svn_cl__shelf_list_by_paths, {"shelf-list-by-paths"}, {N_(
+  { "x-shelf-list-by-paths", svn_cl__shelf_list_by_paths, {0}, {N_(
      "List which shelf affects each path.\n"
      "usage: x-shelf-list-by-paths [PATH...]\n"
      "\n"), N_(
@@ -2003,11 +2014,12 @@ const svn_opt_subcommand_desc3_t svn_cl_
     )},
   },
 
-  { "x-shelf-log", svn_cl__shelf_log, {"shelf-log"}, {N_(
+  { "x-shelf-log", svn_cl__shelf_log, {0}, {N_(
      "Show the versions of a shelf.\n"
-     "usage: x-shelf-log NAME\n"
+     "usage: x-shelf-log SHELF [PATH...]\n"
      "\n"), N_(
-     "  Show all versions of shelf NAME.\n"
+     "  Show all versions of SHELF for each working copy containing PATH (the\n"
+     "  default PATH is '.').\n"
      "\n"), N_(
      "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
      "  in the next release, and there is no promise of backward compatibility.\n"
@@ -2015,11 +2027,11 @@ const svn_opt_subcommand_desc3_t svn_cl_
     {'q', 'v'}
   },
 
-  { "x-shelf-save", svn_cl__shelf_save, {"shelf-save"}, {N_(
+  { "x-shelf-save", svn_cl__shelf_save, {0}, {N_(
      "Copy local changes onto a new version of a shelf.\n"
-     "usage: x-shelf-save NAME [PATH...]\n"
+     "usage: x-shelf-save SHELF [PATH...]\n"
      "\n"), N_(
-     "  Save local changes in the given PATHs as a new version of shelf NAME.\n"
+     "  Save local changes in the given PATHs as a new version of SHELF.\n"
      "  The shelf's log message can be set with -m, -F, etc.\n"
      "\n"), N_(
      "  The same as 'svn shelve --keep-local'.\n"
@@ -2033,24 +2045,30 @@ const svn_opt_subcommand_desc3_t svn_cl_
     }
   },
 
-  { "x-shelve", svn_cl__shelf_shelve, {"shelve"}, {N_(
+  { "x-shelve", svn_cl__shelf_shelve, {0}, {N_(
      "Move local changes onto a shelf.\n"
-     "usage: x-shelve [--keep-local] NAME [PATH...]\n"
+     "usage: x-shelve [--keep-local] SHELF [PATH...]\n"
      "\n"), N_(
-     "  Save the local changes in the given PATHs to a shelf named NAME.\n"
+     "  Save the local changes in the given PATHs to a new or existing SHELF.\n"
      "  Revert those changes from the WC unless '--keep-local' is given.\n"
      "  The shelf's log message can be set with -m, -F, etc.\n"
      "\n"), N_(
      "  'svn shelve --keep-local' is the same as 'svn shelf-save'.\n"
      "\n"), N_(
-     "  The kinds of change you can shelve are those supported by 'svn diff'\n"
-     "  and 'svn patch'. The following are currently NOT supported:\n"
-     "     copies, moves, mkdir, rmdir,\n"
-     "     'binary' content, uncommittable states\n"
-     "\n"), N_(
-     "  To bring back shelved changes, use 'svn unshelve NAME'.\n"
-     "\n"), N_(
-     "  Shelves are stored in <WC>/.svn/shelves/\n"
+     "  The kinds of change you can shelve are committable changes to files and\n"
+     "  properties, except the following kinds which are not yet supported:\n"
+     "     * copies and moves\n"
+     "     * mkdir and rmdir\n"
+     "  Uncommittable states such as conflicts, unversioned and missing cannot\n"
+     "  be shelved.\n"
+     "\n"), N_(
+     "  To bring back shelved changes, use 'svn unshelve SHELF'.\n"
+     "\n"), N_(
+     "  Shelves are currently stored under <WC>/.svn/experimental/shelves/ .\n"
+     "  (In Subversion 1.10, shelves were stored under <WC>/.svn/shelves/ as\n"
+     "  patch files. To recover a shelf created by 1.10, either use a 1.10\n"
+     "  client to find and unshelve it, or find the patch file and use any\n"
+     "  1.10 or later 'svn patch' to apply it.)\n"
      "\n"), N_(
      "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
      "  in the next release, and there is no promise of backward compatibility.\n"
@@ -2060,21 +2078,30 @@ const svn_opt_subcommand_desc3_t svn_cl_
      SVN_CL__LOG_MSG_OPTIONS,
     } },
 
-  { "x-unshelve", svn_cl__shelf_unshelve, {"unshelve"}, {N_(
+  { "x-unshelve", svn_cl__shelf_unshelve, {0}, {N_(
      "Copy shelved changes back into the WC.\n"
-     "usage: x-unshelve [--drop] [NAME [VERSION]]\n"
-     "\n"), N_(
-     "  Apply the shelf named NAME to the working copy.\n"
-     "  NAME defaults to the newest shelf.\n"
+     "usage: x-unshelve [--drop] [SHELF [VERSION]]\n"
      "\n"), N_(
-     "  Unshelve normally refuses to run if any of the files are already\n"
-     "  modified in the WC. With --force, it does not check. In that case,\n"
-     "  any conflict between the change being unshelved and a change\n"
-     "  already in the WC is handled the same way as by 'svn patch',\n"
-     "  creating a 'reject' file.\n"
+     "  Apply the changes stored in SHELF to the working copy.\n"
+     "  SHELF defaults to the newest shelf.\n"
      "\n"), N_(
-     "  With --drop, delete the shelf (like shelf-drop) after successfully\n"
-     "  unshelving with no conflicts.\n"
+     "  Apply the newest version of the shelf, by default. If VERSION is\n"
+     "  specified, apply that version and discard all versions newer than that.\n"
+     "  In any case, retain the unshelved version and versions older than that\n"
+     "  (unless --drop is specified).\n"
+     "\n"), N_(
+     "  With --drop, delete the entire shelf (like 'svn shelf-drop') after\n"
+     "  successfully unshelving with no conflicts.\n"
+     "\n"), N_(
+     "  The working files involved should be in a clean, unmodified state\n"
+     "  before using this command. To roll back to an older version of the\n"
+     "  shelf, first ensure any current working changes are removed, such as\n"
+     "  by shelving or reverting them, and then unshelve the desired version.\n"
+     "\n"), N_(
+     "  Unshelve normally refuses to apply any changes if any path involved is\n"
+     "  already modified (or has any other abnormal status) in the WC. With\n"
+     "  --force, it does not check and may error out and/or produce partial or\n"
+     "  unexpected results.\n"
      "\n"), N_(
      "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
      "  in the next release, and there is no promise of backward compatibility.\n"
@@ -2146,6 +2173,22 @@ add_search_pattern_to_latest_group(svn_c
   APR_ARRAY_PUSH(group, const char *) = pattern;
 }
 
+/* Parse the argument to the --x-viewspec option. */
+static svn_error_t *
+viewspec_from_word(enum svn_cl__viewspec_t *viewspec,
+                   const char *utf8_opt_arg)
+{
+  if (!strcmp(utf8_opt_arg, "classic"))
+    *viewspec = svn_cl__viewspec_classic;
+  else if (!strcmp(utf8_opt_arg, "svn11"))
+    *viewspec = svn_cl__viewspec_svn11;
+  else
+    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                             _("'%s' is not a valid --x-viewspec value"),
+                             utf8_opt_arg);
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 parse_compatible_version(svn_cl__opt_state_t* opt_state,
                          const char *opt_arg,
@@ -2833,6 +2876,8 @@ sub_main(int *exit_code, int argc, const
         break;
       case opt_viewspec:
         opt_state.viewspec = TRUE;
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(viewspec_from_word(&opt_state.viewspec, utf8_opt_arg));
         break;
       case opt_compatible_version:
         SVN_ERR(parse_compatible_version(&opt_state, opt_arg, pool));

Modified: subversion/branches/better-pristines/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/svnadmin/svnadmin.c?rev=1842404&r1=1842403&r2=1842404&view=diff
==============================================================================
--- subversion/branches/better-pristines/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/better-pristines/subversion/svnadmin/svnadmin.c Sun Sep 30 18:26:47 2018
@@ -2257,15 +2257,16 @@ subcommand_verify(apr_getopt_t *os, void
                                check_cancel, NULL, pool));
 
   /* Show the --keep-going error summary. */
-  if (!opt_state->quiet
-      && opt_state->keep_going
-      && verify_baton.error_summary->nelts > 0)
+  if (opt_state->keep_going && verify_baton.error_summary->nelts > 0)
     {
       int rev_maxlength;
       svn_revnum_t end_revnum;
       apr_pool_t *iterpool;
       int i;
 
+      if (feedback_stream == NULL) /* happens when we are in --quiet mode */
+        feedback_stream = recode_stream_create(stdout, pool);
+
       svn_error_clear(
         svn_stream_puts(feedback_stream,
                           _("\n-----Summary of corrupt revisions-----\n")));