You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2016/12/13 12:36:57 UTC

svn commit: r1773992 [5/8] - in /subversion/branches/ra-git: ./ build/ac-macros/ notes/ subversion/bindings/javahl/native/ subversion/bindings/swig/perl/libsvn_swig_perl/ subversion/bindings/swig/ruby/test/ subversion/include/ subversion/include/privat...

Modified: subversion/branches/ra-git/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/conflict-callbacks.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/ra-git/subversion/svn/conflict-callbacks.c Tue Dec 13 12:36:55 2016
@@ -229,8 +229,8 @@ merge_prop_conflict(svn_stream_t *output
     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);
+  if (their_propval == NULL)
+    their_propval = svn_string_create_empty(pool);
     
   options->ignore_eol_style = TRUE;
   SVN_ERR(svn_diff_mem_string_diff3(&diff, base_propval,
@@ -374,148 +374,140 @@ edit_prop_conflict(const svn_string_t **
 typedef struct resolver_option_t
 {
   const char *code;        /* one or two characters */
-  const char *short_desc;  /* label in prompt (localized) */
-  const char *long_desc;   /* longer description (localized) */
   svn_client_conflict_option_id_t choice;
                            /* or ..._undefined if not from libsvn_client */
   const char *accept_arg;  /* --accept option argument (NOT localized) */
 } resolver_option_t;
 
+typedef struct client_option_t
+{
+  const char *code;        /* one or two characters */
+  const char *label;       /* label in prompt (localized) */
+  const char *long_desc;   /* longer description (localized) */
+  svn_client_conflict_option_id_t choice;
+                           /* or ..._undefined if not from libsvn_client */
+  const char *accept_arg;  /* --accept option argument (NOT localized) */
+} client_option_t;
+
 /* Resolver options for conflict options offered by libsvn_client.  */
 static const resolver_option_t builtin_resolver_options[] =
 {
-  { "r",  NULL, NULL,
-                                  svn_client_conflict_option_merged_text,
-                                  SVN_CL__ACCEPT_WORKING },
-  { "mc", NULL, NULL,
-    svn_client_conflict_option_working_text_where_conflicted,
-                                  SVN_CL__ACCEPT_MINE_CONFLICT },
-  { "tc", NULL, NULL,
-    svn_client_conflict_option_incoming_text_where_conflicted,
-                                  SVN_CL__ACCEPT_THEIRS_CONFLICT },
-  { "mf", NULL, NULL,
-                                  svn_client_conflict_option_working_text,
-                                  SVN_CL__ACCEPT_MINE_FULL},
-  { "tf", NULL, NULL,
-                                  svn_client_conflict_option_incoming_text,
-                                  SVN_CL__ACCEPT_THEIRS_FULL },
-  { "p",  N_("postpone"),         NULL,
-                                  svn_client_conflict_option_postpone,
-                                  SVN_CL__ACCEPT_POSTPONE },
+  { "r",  svn_client_conflict_option_merged_text,
+          SVN_CL__ACCEPT_WORKING },
+  { "mc", svn_client_conflict_option_working_text_where_conflicted,
+          SVN_CL__ACCEPT_MINE_CONFLICT },
+  { "tc", svn_client_conflict_option_incoming_text_where_conflicted,
+          SVN_CL__ACCEPT_THEIRS_CONFLICT },
+  { "mf", svn_client_conflict_option_working_text,
+          SVN_CL__ACCEPT_MINE_FULL},
+  { "tf", svn_client_conflict_option_incoming_text,
+          SVN_CL__ACCEPT_THEIRS_FULL },
+  { "p",  svn_client_conflict_option_postpone,
+          SVN_CL__ACCEPT_POSTPONE },
 
   /* This option resolves a tree conflict to the current working copy state. */
-  { "r", NULL, NULL,
-    svn_client_conflict_option_accept_current_wc_state,
-    SVN_CL__ACCEPT_WORKING },
+  { "r", svn_client_conflict_option_accept_current_wc_state,
+         SVN_CL__ACCEPT_WORKING },
 
   /* These options use the same code since they only occur in
    * distinct conflict scenarios. */
-  { "u", N_("update move destination"),    NULL,
-    svn_client_conflict_option_update_move_destination },
-  { "u", N_("update any moved-away children"), NULL,
-    svn_client_conflict_option_update_any_moved_away_children },
+  { "u", svn_client_conflict_option_update_move_destination },
+  { "u", svn_client_conflict_option_update_any_moved_away_children },
 
   /* Options for incoming add vs local add. */
-  { "i", N_("ignore incoming addition"), NULL,
-    svn_client_conflict_option_incoming_add_ignore },
+  { "i", svn_client_conflict_option_incoming_add_ignore },
 
   /* Options for incoming file add vs local file add upon merge. */
-  { "m", N_("merge the files"), NULL,
-    svn_client_conflict_option_incoming_added_file_text_merge },
-  { "R", N_("delete my file and replace it with incoming file"), NULL,
-    svn_client_conflict_option_incoming_added_file_replace },
-  { "M", N_("replace my file with incoming file and merge the files"), NULL,
-    svn_client_conflict_option_incoming_added_file_replace_and_merge },
+  { "m", svn_client_conflict_option_incoming_added_file_text_merge },
+  { "M", svn_client_conflict_option_incoming_added_file_replace_and_merge },
 
   /* Options for incoming dir add vs local dir add upon merge. */
-  { "m", N_("merge the directories"), NULL,
-    svn_client_conflict_option_incoming_added_dir_merge },
-  { "R", N_("delete my directory and replace it with incoming directory"), NULL,
-    svn_client_conflict_option_incoming_added_dir_replace },
-  { "M", N_("replace my directory with incoming directory and merge"), NULL,
-    svn_client_conflict_option_incoming_added_dir_replace_and_merge },
+  { "m", svn_client_conflict_option_incoming_added_dir_merge },
+  { "R", svn_client_conflict_option_incoming_added_dir_replace },
+  { "M", svn_client_conflict_option_incoming_added_dir_replace_and_merge },
 
   /* Options for incoming delete vs any. */
-  { "i", N_("ignore incoming deletion"), NULL,
-    svn_client_conflict_option_incoming_delete_ignore },
-  { "a", N_("accept incoming deletion"), NULL,
-    svn_client_conflict_option_incoming_delete_accept },
+  { "i", svn_client_conflict_option_incoming_delete_ignore },
+  { "a", svn_client_conflict_option_incoming_delete_accept },
 
   /* Options for incoming move vs local edit. */
-  { "m", NULL, NULL, svn_client_conflict_option_incoming_move_file_text_merge },
-  { "m", NULL, NULL, svn_client_conflict_option_incoming_move_dir_merge },
+  { "m", svn_client_conflict_option_incoming_move_file_text_merge },
+  { "m", svn_client_conflict_option_incoming_move_dir_merge },
+
+  /* Options for local move vs incoming edit. */
+  { "m", svn_client_conflict_option_local_move_file_text_merge },
 
   { NULL }
 };
 
 /* Extra resolver options offered by 'svn' for any conflict. */
-static const resolver_option_t extra_resolver_options[] =
+static const client_option_t extra_resolver_options[] =
 {
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed) */
-  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+  { "q",  N_("Quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_client_conflict_option_postpone },
   { NULL }
 };
 
 
 /* Additional resolver options offered by 'svn' for a text conflict. */
-static const resolver_option_t extra_resolver_options_text[] =
+static const client_option_t extra_resolver_options_text[] =
 {
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed) */
-  { "e",  N_("edit file"),        N_("change merged file in an editor"),
+  { "e",  N_("Edit file"),        N_("change merged file in an editor"),
                                   svn_client_conflict_option_undefined,
                                   SVN_CL__ACCEPT_EDIT },
-  { "df", N_("show diff"),        N_("show all changes made to merged file"),
+  { "df", N_("Show diff"),        N_("show all changes made to merged file"),
                                   svn_client_conflict_option_undefined},
-  { "dc", N_("display conflict"), N_("show all conflicts "
+  { "dc", N_("Display conflict"), N_("show all conflicts "
                                      "(ignoring merged version)"),
                                   svn_client_conflict_option_undefined },
-  { "m",  N_("merge"),            N_("use merge tool to resolve conflict"),
+  { "m",  N_("Merge"),            N_("use merge tool to resolve conflict"),
                                   svn_client_conflict_option_undefined },
-  { "l",  N_("launch tool"),      N_("launch external merge tool to resolve "
+  { "l",  N_("Launch tool"),      N_("launch external merge tool to resolve "
                                      "conflict"),
                                   svn_client_conflict_option_undefined,
                                   SVN_CL__ACCEPT_LAUNCH },
-  { "i",  N_("internal merge tool"), N_("use built-in merge tool to "
+  { "i",  N_("Internal merge tool"), N_("use built-in merge tool to "
                                      "resolve conflict"),
                                   svn_client_conflict_option_undefined },
-  { "s",  N_("show all options"), N_("show this list (also 'h', '?')"),
+  { "s",  N_("Show all options"), N_("show this list (also 'h', '?')"),
                                   svn_client_conflict_option_undefined },
   { NULL }
 };
 
 /* Additional resolver options offered by 'svn' for a property conflict. */
-static const resolver_option_t extra_resolver_options_prop[] =
+static const client_option_t extra_resolver_options_prop[] =
 {
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed) */
-  { "dc", N_("display conflict"), N_("show conflicts in this property"),
+  { "dc", N_("Display conflict"), N_("show conflicts in this property"),
                                   svn_client_conflict_option_undefined },
-  { "e",  N_("edit property"),    N_("change merged property value in an "
+  { "e",  N_("Edit property"),    N_("change merged property value in an "
                                      "editor"),
                                   svn_client_conflict_option_undefined,
                                   SVN_CL__ACCEPT_EDIT },
-  { "h",  N_("help"),             N_("show this help (also '?')"),
+  { "h",  N_("Help"),             N_("show this help (also '?')"),
                                   svn_client_conflict_option_undefined },
   { NULL }
 };
 
 /* Additional resolver options offered by 'svn' for a tree conflict. */
-static const resolver_option_t extra_resolver_options_tree[] =
+static const client_option_t extra_resolver_options_tree[] =
 {
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed) */
-  { "d",  N_("set repository move destination path"),
+  { "d",  N_("Set repository move destination path"),
           N_("pick repository move target from list of possible targets"),
                                   svn_client_conflict_option_undefined },
 
-  { "w",  N_("set working copy move destination path"),
+  { "w",  N_("Set working copy move destination path"),
           N_("pick working copy move target from list of possible targets"),
                                   svn_client_conflict_option_undefined },
 
-  { "h",  N_("help"),             N_("show this help (also '?')"),
+  { "h",  N_("Help"),             N_("show this help (also '?')"),
                                   svn_client_conflict_option_undefined },
 
   { NULL }
@@ -524,14 +516,16 @@ static const resolver_option_t extra_res
 
 /* Return a pointer to the option description in OPTIONS matching the
  * one- or two-character OPTION_CODE.  Return NULL if not found. */
-static const resolver_option_t *
-find_option(const resolver_option_t *options,
+static const client_option_t *
+find_option(const apr_array_header_t *options,
             const char *option_code)
 {
-  const resolver_option_t *opt;
+  int i;
 
-  for (opt = options; opt->code; opt++)
+  for (i = 0; i < options->nelts; i++)
     {
+      const client_option_t *opt = APR_ARRAY_IDX(options, i, client_option_t *);
+
       /* Ignore code "" (blank lines) which is not a valid answer. */
       if (opt->code[0] && strcmp(opt->code, option_code) == 0)
         return opt;
@@ -540,25 +534,52 @@ find_option(const resolver_option_t *opt
 }
 
 /* Return a pointer to the option description in OPTIONS matching the
- * the conflict option ID CHOICE.  Return NULL if not found. */
-static const resolver_option_t *
-find_option_by_id(const resolver_option_t *options,
-                  svn_client_conflict_option_id_t choice)
+ * conflict option ID CHOICE. @a out will be set to NULL if the
+ * option was not found. */
+static svn_error_t *
+find_option_by_builtin(client_option_t **out,
+                       const resolver_option_t *options,
+                       svn_client_conflict_option_t *builtin_option,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   const resolver_option_t *opt;
+  svn_client_conflict_option_id_t id;
+
+  id = svn_client_conflict_option_get_id(builtin_option);
 
   for (opt = options; opt->code; opt++)
     {
-      if (opt->choice == choice)
-        return opt;
+      if (opt->choice == id)
+        {
+          client_option_t *client_opt;
+
+          client_opt = apr_pcalloc(result_pool, sizeof(*client_opt));
+          client_opt->choice = id;
+          client_opt->code = opt->code;
+          client_opt->label = svn_client_conflict_option_get_label(
+              builtin_option,
+              result_pool);
+          client_opt->long_desc = svn_client_conflict_option_get_description(
+                                    builtin_option,
+                                    result_pool);
+          client_opt->accept_arg = opt->accept_arg;
+
+          *out = client_opt;
+
+          return SVN_NO_ERROR;
+        }
     }
-  return NULL;
+
+  *out = NULL;
+
+  return SVN_NO_ERROR;
 }
 
 /* Return a prompt string listing the options OPTIONS. If OPTION_CODES is
  * non-null, select only the options whose codes are mentioned in it. */
 static const char *
-prompt_string(const resolver_option_t *options,
+prompt_string(const apr_array_header_t *options,
               const char *const *option_codes,
               apr_pool_t *pool)
 {
@@ -567,10 +588,11 @@ prompt_string(const resolver_option_t *o
   const char *line_sep = apr_psprintf(pool, "\n%*s", left_margin, "");
   int this_line_len = left_margin;
   svn_boolean_t first = TRUE;
+  int i = 0;
 
   while (1)
     {
-      const resolver_option_t *opt;
+      const client_option_t *opt;
       const char *s;
       int slen;
 
@@ -584,15 +606,16 @@ prompt_string(const resolver_option_t *o
         }
       else
         {
-          opt = options++;
-          if (! opt->code)
+          if (i >= options->nelts)
             break;
+          opt = APR_ARRAY_IDX(options, i, client_option_t *);
+          i++;
         }
 
       if (! first)
         result = apr_pstrcat(pool, result, ",", SVN_VA_NULL);
       s = apr_psprintf(pool, " (%s) %s", opt->code,
-                       opt->short_desc ? _(opt->short_desc) : opt->long_desc);
+                       opt->label ? opt->label : opt->long_desc);
       slen = svn_utf_cstring_utf8_width(s);
       /* Break the line if adding the next option would make it too long */
       if (this_line_len + slen > MAX_PROMPT_WIDTH)
@@ -610,18 +633,22 @@ prompt_string(const resolver_option_t *o
 /* Return a help string listing the OPTIONS. */
 static svn_error_t *
 help_string(const char **result,
-            const resolver_option_t *options,
+            const apr_array_header_t *options,
             apr_pool_t *pool)
 {
-  const resolver_option_t *opt;
   apr_pool_t *iterpool;
+  int i;
 
   *result = "";
   iterpool = svn_pool_create(pool);
-  for (opt = options; opt->code; opt++)
+  for (i = 0; i < options->nelts; i++)
     {
+      const client_option_t *opt;
       svn_pool_clear(iterpool);
 
+      opt = APR_ARRAY_IDX(options, i,
+                          client_option_t *);
+
       /* Append a line describing OPT, or a blank line if its code is "". */
       if (opt->code[0])
         {
@@ -658,8 +685,8 @@ help_string(const char **result,
  * *OPT == NULL.
  */
 static svn_error_t *
-prompt_user(const resolver_option_t **opt,
-            const resolver_option_t *conflict_options,
+prompt_user(const client_option_t **opt,
+            const apr_array_header_t *conflict_options,
             const char *const *options_to_show,
             const char *conflict_description,
             void *prompt_baton,
@@ -695,15 +722,14 @@ prompt_user(const resolver_option_t **op
 
 /* Set *OPTIONS to an array of resolution options for CONFLICT. */
 static svn_error_t *
-build_text_conflict_options(resolver_option_t **options,
+build_text_conflict_options(apr_array_header_t **options,
                             svn_client_conflict_t *conflict,
                             svn_client_ctx_t *ctx,
                             svn_boolean_t is_binary,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  resolver_option_t *opt;
-  const resolver_option_t *o;
+  const client_option_t *o;
   apr_array_header_t *builtin_options;
   apr_size_t nopt;
   int i;
@@ -716,41 +742,34 @@ build_text_conflict_options(resolver_opt
   nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options);
   if (!is_binary)
     nopt += ARRAY_LEN(extra_resolver_options_text);
-  *options = apr_pcalloc(result_pool, sizeof(*opt) * (nopt + 1));
+  *options = apr_array_make(result_pool, nopt, sizeof(client_option_t *));
 
-  opt = *options;
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < builtin_options->nelts; i++)
     {
+      client_option_t *opt;
       svn_client_conflict_option_t *builtin_option;
-      svn_client_conflict_option_id_t id;
-      const resolver_option_t *known_option;
 
       svn_pool_clear(iterpool);
       builtin_option = APR_ARRAY_IDX(builtin_options, i,
                                      svn_client_conflict_option_t *);
-      id = svn_client_conflict_option_get_id(builtin_option);
-      known_option = find_option_by_id(builtin_resolver_options, id);
-      if (known_option == NULL)
+      SVN_ERR(find_option_by_builtin(&opt,
+                                     builtin_resolver_options,
+                                     builtin_option,
+                                     result_pool,
+                                     iterpool));
+      if (opt == NULL)
         continue; /* ### unknown option -- assign a code dynamically? */
 
-      opt->code = known_option->code;
-      opt->short_desc = known_option->short_desc;
-      SVN_ERR(svn_client_conflict_option_describe(&opt->long_desc,
-                                                  builtin_option,
-                                                  result_pool,
-                                                  iterpool));
-      opt->choice = id;
-      opt->accept_arg = known_option->accept_arg;
-      opt++; 
+      APR_ARRAY_PUSH(*options, client_option_t *) = opt;
     }
 
   for (o = extra_resolver_options; o->code; o++)
-    *opt++ = *o;
+    APR_ARRAY_PUSH(*options, const client_option_t *) = o;
   if (!is_binary)
     {
       for (o = extra_resolver_options_text; o->code; o++)
-        *opt++ = *o;
+        APR_ARRAY_PUSH(*options, const client_option_t *) = o;
     }
 
   svn_pool_destroy(iterpool);
@@ -842,7 +861,7 @@ handle_text_conflict(svn_boolean_t *reso
   const char *my_abspath;
   const char *their_abspath;
   const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
-  resolver_option_t *text_conflict_options;
+  apr_array_header_t *text_conflict_options;
   svn_client_conflict_option_id_t option_id; 
 
   option_id = svn_client_conflict_option_unspecified;
@@ -889,8 +908,7 @@ handle_text_conflict(svn_boolean_t *reso
     {
       const char *suggested_options[9]; /* filled statically below */
       const char **next_option = suggested_options;
-      const resolver_option_t *opt;
-
+      const client_option_t *opt;
 
       svn_pool_clear(iterpool);
 
@@ -915,10 +933,9 @@ handle_text_conflict(svn_boolean_t *reso
           if (knows_something || is_binary)
             *next_option++ = "r";
 
-          /* The 'mine-full' option selects the ".mine" file so only offer
-           * it if that file exists. It does not exist for binary files,
-           * for example (questionable historical behaviour since 1.0). */
-          if (my_abspath)
+          /* The 'mine-full' option selects the ".mine" file for texts or
+           * the current working directory file for binary files. */
+          if (my_abspath || is_binary)
             *next_option++ = "mf";
 
           *next_option++ = "tf";
@@ -1167,14 +1184,13 @@ handle_text_conflict(svn_boolean_t *reso
 
 /* Set *OPTIONS to an array of resolution options for CONFLICT. */
 static svn_error_t *
-build_prop_conflict_options(resolver_option_t **options,
+build_prop_conflict_options(apr_array_header_t **options,
                             svn_client_conflict_t *conflict,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  resolver_option_t *opt;
-  const resolver_option_t *o;
+  const client_option_t *o;
   apr_array_header_t *builtin_options;
   apr_size_t nopt;
   int i;
@@ -1186,42 +1202,34 @@ build_prop_conflict_options(resolver_opt
                                                           scratch_pool));
   nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options) +
            ARRAY_LEN(extra_resolver_options_prop);
-  *options = apr_pcalloc(result_pool, sizeof(*opt) * (nopt + 1));
+  *options = apr_array_make(result_pool, nopt, sizeof(client_option_t *));
 
-  opt = *options;
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < builtin_options->nelts; i++)
     {
+      client_option_t *opt;
       svn_client_conflict_option_t *builtin_option;
-      svn_client_conflict_option_id_t id;
-      const resolver_option_t *known_option;
 
       svn_pool_clear(iterpool);
       builtin_option = APR_ARRAY_IDX(builtin_options, i,
                                      svn_client_conflict_option_t *);
-      id = svn_client_conflict_option_get_id(builtin_option);
-      known_option = find_option_by_id(builtin_resolver_options, id);
-      if (known_option == NULL)
+      SVN_ERR(find_option_by_builtin(&opt,
+                                     builtin_resolver_options,
+                                     builtin_option,
+                                     result_pool,
+                                     iterpool));
+      if (opt == NULL)
         continue; /* ### unknown option -- assign a code dynamically? */
 
-      opt->code = known_option->code;
-      opt->short_desc = known_option->short_desc;
-      SVN_ERR(svn_client_conflict_option_describe(&opt->long_desc,
-                                                  builtin_option,
-                                                  result_pool,
-                                                  iterpool));
-      opt->choice = id;
-      opt->accept_arg = known_option->accept_arg;
-
-      opt++; 
+      APR_ARRAY_PUSH(*options, client_option_t *) = opt;
     }
 
   svn_pool_destroy(iterpool);
 
   for (o = extra_resolver_options; o->code; o++)
-    *opt++ = *o;
+    APR_ARRAY_PUSH(*options, const client_option_t *) = o;
   for (o = extra_resolver_options_prop; o->code; o++)
-    *opt++ = *o;
+    APR_ARRAY_PUSH(*options, const client_option_t *) = o;
 
   return SVN_NO_ERROR;
 }
@@ -1250,7 +1258,7 @@ handle_one_prop_conflict(svn_client_conf
   const svn_string_t *my_propval;
   const svn_string_t *their_propval;
   apr_array_header_t *resolution_options;
-  resolver_option_t *prop_conflict_options;
+  apr_array_header_t *prop_conflict_options;
 
   SVN_ERR(svn_client_conflict_prop_get_propvals(NULL, &my_propval,
                                                 &base_propval, &their_propval,
@@ -1278,7 +1286,7 @@ handle_one_prop_conflict(svn_client_conf
   iterpool = svn_pool_create(scratch_pool);
   while (TRUE)
     {
-      const resolver_option_t *opt;
+      const client_option_t *opt;
       const char *suggested_options[9]; /* filled statically below */
       const char **next_option = suggested_options;
 
@@ -1425,57 +1433,62 @@ handle_prop_conflicts(svn_boolean_t *res
 /* Set *OPTIONS to an array of resolution options for CONFLICT. */
 static svn_error_t *
 build_tree_conflict_options(
-  resolver_option_t **options,
+  apr_array_header_t **options,
   apr_array_header_t **possible_moved_to_repos_relpaths,
   apr_array_header_t **possible_moved_to_abspaths,
+  svn_boolean_t *all_options_are_dumb,
   svn_client_conflict_t *conflict,
   svn_client_ctx_t *ctx,
   apr_pool_t *result_pool,
   apr_pool_t *scratch_pool)
 {
-  resolver_option_t *opt;
-  const resolver_option_t *o;
+  const client_option_t *o;
   apr_array_header_t *builtin_options;
   apr_size_t nopt;
   int i;
   apr_pool_t *iterpool;
 
+  if (all_options_are_dumb != NULL)
+    *all_options_are_dumb = TRUE;
+
   SVN_ERR(svn_client_conflict_tree_get_resolution_options(&builtin_options,
                                                           conflict, ctx,
                                                           scratch_pool,
                                                           scratch_pool));
   nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options_tree) +
            ARRAY_LEN(extra_resolver_options);
-  *options = apr_pcalloc(result_pool, sizeof(*opt) * (nopt + 1));
+  *options = apr_array_make(result_pool, nopt, sizeof(client_option_t *));
   *possible_moved_to_abspaths = NULL;
   *possible_moved_to_repos_relpaths = NULL;
 
-  opt = *options;
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < builtin_options->nelts; i++)
     {
+      client_option_t *opt;
       svn_client_conflict_option_t *builtin_option;
       svn_client_conflict_option_id_t id;
-      const resolver_option_t *known_option;
 
       svn_pool_clear(iterpool);
       builtin_option = APR_ARRAY_IDX(builtin_options, i,
                                      svn_client_conflict_option_t *);
-      id = svn_client_conflict_option_get_id(builtin_option);
-      known_option = find_option_by_id(builtin_resolver_options, id);
-      if (known_option == NULL)
+      SVN_ERR(find_option_by_builtin(&opt,
+                                     builtin_resolver_options,
+                                     builtin_option,
+                                     result_pool,
+                                     iterpool));
+      if (opt == NULL)
         continue; /* ### unknown option -- assign a code dynamically? */
 
-      opt->code = known_option->code;
-      opt->short_desc = known_option->short_desc;
-      SVN_ERR(svn_client_conflict_option_describe(&opt->long_desc,
-                                                  builtin_option,
-                                                  result_pool,
-                                                  iterpool));
-      opt->choice = id;
-      opt->accept_arg = known_option->accept_arg;
+      APR_ARRAY_PUSH(*options, client_option_t *) = opt;
 
-      opt++; 
+      id = svn_client_conflict_option_get_id(builtin_option);
+
+      /* Check if we got a "smart" tree conflict option. */
+      if (all_options_are_dumb != NULL &&
+          *all_options_are_dumb &&
+          id != svn_client_conflict_option_postpone &&
+          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)
@@ -1505,10 +1518,10 @@ build_tree_conflict_options(
            (*possible_moved_to_abspaths)->nelts <= 1))
         continue;
 
-      *opt++ = *o;
+      APR_ARRAY_PUSH(*options, const client_option_t *) = o;
     }
   for (o = extra_resolver_options; o->code; o++)
-    *opt++ = *o;
+    APR_ARRAY_PUSH(*options, const client_option_t *) = o;
 
   return SVN_NO_ERROR;
 }
@@ -1633,7 +1646,7 @@ handle_tree_conflict(svn_boolean_t *reso
                      apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool;
-  resolver_option_t *tree_conflict_options;
+  apr_array_header_t *tree_conflict_options;
   svn_client_conflict_option_id_t option_id;
   const char *local_abspath;
   const char *conflict_description;
@@ -1641,6 +1654,7 @@ handle_tree_conflict(svn_boolean_t *reso
   const char *incoming_change_description;
   apr_array_header_t *possible_moved_to_repos_relpaths;
   apr_array_header_t *possible_moved_to_abspaths;
+  svn_boolean_t all_options_are_dumb;
 
   option_id = svn_client_conflict_option_unspecified;
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
@@ -1664,12 +1678,20 @@ handle_tree_conflict(svn_boolean_t *reso
   SVN_ERR(build_tree_conflict_options(&tree_conflict_options,
                                       &possible_moved_to_repos_relpaths,
                                       &possible_moved_to_abspaths,
+                                      &all_options_are_dumb,
                                       conflict, ctx,
                                       scratch_pool, scratch_pool));
+
+  if (all_options_are_dumb)
+    SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+                                _("\nSubversion is not smart enough to resolve "
+                                  "this tree conflict automatically!\nSee 'svn "
+                                  "help resolve' for more information.\n\n")));
+    
   iterpool = svn_pool_create(scratch_pool);
   while (1)
     {
-      const resolver_option_t *opt;
+      const client_option_t *opt;
 
       svn_pool_clear(iterpool);
 
@@ -1723,7 +1745,7 @@ handle_tree_conflict(svn_boolean_t *reso
                         &tree_conflict_options,
                         &possible_moved_to_repos_relpaths,
                         &possible_moved_to_abspaths,
-                        conflict, ctx,
+                        NULL, conflict, ctx,
                         scratch_pool, scratch_pool));
             }
           continue;
@@ -1765,7 +1787,7 @@ handle_tree_conflict(svn_boolean_t *reso
                         &tree_conflict_options,
                         &possible_moved_to_repos_relpaths,
                         &possible_moved_to_abspaths,
-                        conflict, ctx,
+                        NULL, conflict, ctx,
                         scratch_pool, scratch_pool));
             }
           continue;
@@ -1796,163 +1818,6 @@ handle_tree_conflict(svn_boolean_t *reso
 }
 
 static svn_error_t *
-resolve_conflict_by_accept_option(svn_client_conflict_option_id_t *option_id,
-                                  svn_cl__accept_t accept_which, 
-                                  svn_boolean_t *external_failed,
-                                  svn_client_conflict_t *conflict,
-                                  const char *editor_cmd,
-                                  apr_hash_t *config,
-                                  const char *path_prefix,
-                                  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_error_t *err;
-  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);
-  svn_boolean_t text_conflicted;
-  apr_array_header_t *props_conflicted;
-  svn_boolean_t tree_conflicted;
-
-  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
-                                             &props_conflicted,
-                                             &tree_conflicted,
-                                             conflict,
-                                             scratch_pool,
-                                             scratch_pool));
-
-  if (text_conflicted)
-    SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
-                                                  &base_abspath,
-                                                  &their_abspath,
-                                                  conflict, scratch_pool,
-                                                  scratch_pool));
-
-  *option_id = svn_client_conflict_option_unspecified;
-  /* Handle the --accept option. */ 
-  switch (accept_which)
-    {
-    case svn_cl__accept_invalid:
-    case svn_cl__accept_unspecified:
-      /* No (or no valid) --accept option, fall through to prompting. */
-      break;
-    case svn_cl__accept_postpone:
-      *option_id = svn_client_conflict_option_postpone;
-      break;
-    case svn_cl__accept_base:
-      *option_id = svn_client_conflict_option_base_text;
-      break;
-    case svn_cl__accept_working:
-      *option_id = svn_client_conflict_option_merged_text;
-      break;
-    case svn_cl__accept_mine_conflict:
-      *option_id = svn_client_conflict_option_working_text_where_conflicted;
-      break;
-    case svn_cl__accept_theirs_conflict:
-      *option_id = svn_client_conflict_option_incoming_text_where_conflicted;
-      break;
-    case svn_cl__accept_mine_full:
-      *option_id = svn_client_conflict_option_working_text;
-      break;
-    case svn_cl__accept_theirs_full:
-      *option_id = svn_client_conflict_option_incoming_text;
-      break;
-    case svn_cl__accept_edit:
-      if (merged_abspath)
-        {
-          if (*external_failed)
-            {
-              *option_id = svn_client_conflict_option_postpone;
-              break;
-            }
-
-          err = svn_cmdline__edit_file_externally(merged_abspath,
-                                                  editor_cmd, config,
-                                                  scratch_pool);
-          if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
-                      err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
-            {
-              char buf[1024];
-              const char *message;
-
-              message = svn_err_best_message(err, buf, sizeof(buf));
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
-                                          message));
-              svn_error_clear(err);
-              *external_failed = TRUE;
-            }
-          else if (err)
-            return svn_error_trace(err);
-          *option_id = svn_client_conflict_option_merged_text;
-          break;
-        }
-      /* else, fall through to prompting. */
-      break;
-    case svn_cl__accept_launch:
-      if (base_abspath && their_abspath && my_abspath && merged_abspath)
-        {
-          svn_boolean_t remains_in_conflict;
-          const char *local_abspath;
-
-          if (*external_failed)
-            {
-              *option_id = svn_client_conflict_option_postpone;
-              break;
-            }
-
-          local_abspath = svn_client_conflict_get_local_abspath(conflict);
-          err = svn_cl__merge_file_externally(base_abspath,
-                                              their_abspath,
-                                              my_abspath,
-                                              merged_abspath,
-                                              local_abspath,
-                                              config,
-                                              &remains_in_conflict,
-                                              scratch_pool);
-          if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
-                      err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
-            {
-              char buf[1024];
-              const char *message;
-
-              message = svn_err_best_message(err, buf, sizeof(buf));
-              SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
-                                          message));
-              *external_failed = TRUE;
-              return svn_error_trace(err);
-            }
-          else if (err)
-            return svn_error_trace(err);
-
-          if (remains_in_conflict)
-            *option_id = svn_client_conflict_option_postpone;
-          else
-            *option_id = svn_client_conflict_option_merged_text;
-          break;
-        }
-      /* else, fall through to prompting. */
-      break;
-    }
-
-  if (*option_id != svn_client_conflict_option_unspecified &&
-      *option_id != svn_client_conflict_option_postpone)
-    {
-      SVN_ERR(mark_conflict_resolved(conflict, *option_id,
-                                     text_conflicted,
-                                     props_conflicted->nelts >  0 ? "" : NULL,
-                                     tree_conflicted,
-                                     path_prefix, conflict_stats,
-                                     ctx, scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
 resolve_conflict_interactively(svn_boolean_t *resolved,
                                svn_boolean_t *postponed,
                                svn_boolean_t *quit,
@@ -2011,23 +1876,24 @@ resolve_conflict_interactively(svn_boole
 
 svn_error_t *
 svn_cl__resolve_conflict(svn_boolean_t *resolved,
-                         svn_cl__accept_t *accept_which,
                          svn_boolean_t *quit,
                          svn_boolean_t *external_failed,
                          svn_boolean_t *printed_summary,
                          svn_client_conflict_t *conflict,
+                         svn_cl__accept_t accept_which,
                          const char *editor_cmd,
                          apr_hash_t *config,
                          const char *path_prefix,
                          svn_cmdline_prompt_baton_t *pb,
                          svn_cl__conflict_stats_t *conflict_stats,
-                         svn_client_conflict_option_id_t option_id,
                          svn_client_ctx_t *ctx,
                          apr_pool_t *scratch_pool)
 {
   svn_boolean_t text_conflicted;
   apr_array_header_t *props_conflicted;
   svn_boolean_t tree_conflicted;
+  const char *local_abspath;
+  svn_client_conflict_option_id_t option_id;
 
   SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
                                              &props_conflicted,
@@ -2035,59 +1901,225 @@ svn_cl__resolve_conflict(svn_boolean_t *
                                              conflict,
                                              scratch_pool,
                                              scratch_pool));
+  local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
-  /* Resolve the conflict by --accept option or interactively if no
-   * resolution option was passed. */
-  if (option_id == svn_client_conflict_option_unspecified)
+  if (accept_which == svn_cl__accept_unspecified)
+    {
+      option_id = svn_client_conflict_option_unspecified;
+    }
+  else if (accept_which == svn_cl__accept_postpone)
     {
-      SVN_ERR(resolve_conflict_by_accept_option(&option_id, *accept_which,
-                                                external_failed, conflict,
-                                                editor_cmd, config,
-                                                path_prefix, pb,
-                                                conflict_stats, ctx,
-                                                scratch_pool, scratch_pool));
+      option_id = svn_client_conflict_option_postpone;
+    }
+  else if (accept_which == svn_cl__accept_base)
+    {
+      option_id = svn_client_conflict_option_base_text;
+    }
+  else if (accept_which == svn_cl__accept_working)
+    {
+      option_id = svn_client_conflict_option_merged_text;
 
-      if (option_id == svn_client_conflict_option_unspecified)
+      if (text_conflicted)
         {
-          svn_boolean_t postponed = FALSE;
-          svn_boolean_t printed_description = FALSE;
-          svn_error_t *err;
+          const char *mime_type =
+            svn_client_conflict_text_get_mime_type(conflict);
+
+          /* There is no merged text for binary conflicts, behave as
+           * if 'mine-full' was chosen. */
+          if (mime_type && svn_mime_type_is_binary(mime_type))
+            option_id = svn_client_conflict_option_working_text;
+        }
+      else if (tree_conflicted)
+        {
+          /* For tree conflicts, map 'working' to 'accept current working
+           * copy state'. */
+          option_id = svn_client_conflict_option_accept_current_wc_state;
+        }
+    }
+  else if (accept_which == svn_cl__accept_theirs_conflict)
+    {
+      option_id = svn_client_conflict_option_incoming_text_where_conflicted;
+    }
+  else if (accept_which == svn_cl__accept_mine_conflict)
+    {
+      option_id = svn_client_conflict_option_working_text_where_conflicted;
 
-          *quit = FALSE;
+      if (tree_conflicted)
+        {
+          svn_wc_operation_t operation;
 
-          /* We're in interactive mode and either the user gave no --accept
-             option or the option did not apply; let's prompt. */
-          while (!*resolved && !postponed && !*quit)
+          operation = svn_client_conflict_get_operation(conflict);
+          if (operation == svn_wc_operation_update ||
+              operation == svn_wc_operation_switch)
             {
-              err = resolve_conflict_interactively(resolved, &postponed, quit,
-                                                   external_failed,
-                                                   printed_summary,
-                                                   &printed_description,
-                                                   conflict,
-                                                   editor_cmd, config,
-                                                   path_prefix, pb,
-                                                   conflict_stats, ctx,
-                                                   scratch_pool, scratch_pool);
-              if (err && err->apr_err == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE)
+              svn_wc_conflict_reason_t reason;
+
+              reason = svn_client_conflict_get_local_change(conflict);
+              if (reason == svn_wc_conflict_reason_moved_away)
+                {
+                  /* Map 'mine-conflict' to 'update move destination'. */
+                  option_id =
+                    svn_client_conflict_option_update_move_destination;
+                }
+              else if (reason == svn_wc_conflict_reason_deleted ||
+                       reason == svn_wc_conflict_reason_replaced)
+                {
+                  svn_wc_conflict_action_t action;
+                  svn_node_kind_t node_kind;
+
+                  action = svn_client_conflict_get_incoming_change(conflict);
+                  node_kind =
+                    svn_client_conflict_tree_get_victim_node_kind(conflict);
+
+                  if (action == svn_wc_conflict_action_edit &&
+                      node_kind == svn_node_dir)
+                    {
+                      /* Map 'mine-conflict' to 'update any moved away
+                       * children'. */
+                      option_id =
+                        svn_client_conflict_option_update_any_moved_away_children;
+                    }
+                }
+            }
+        }
+    }
+  else if (accept_which == svn_cl__accept_theirs_full)
+    {
+      option_id = svn_client_conflict_option_incoming_text;
+    }
+  else if (accept_which == svn_cl__accept_mine_full)
+    {
+      option_id = svn_client_conflict_option_working_text;
+    }
+  else if (accept_which == svn_cl__accept_edit)
+    {
+      option_id = svn_client_conflict_option_unspecified;
+
+      if (local_abspath)
+        {
+          if (*external_failed)
+            {
+              option_id = svn_client_conflict_option_postpone;
+            }
+          else
+            {
+              svn_error_t *err;
+
+              err = svn_cmdline__edit_file_externally(local_abspath,
+                                                      editor_cmd, config,
+                                                      scratch_pool);
+              if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
+                          err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
                 {
-                  /* Conflict resolution has failed. Let the user try again.
-                   * It is always possible to break out of this loop with
-                   * the 'quit' or 'postpone' options. */
-                  svn_handle_warning2(stderr, err, "svn: ");
+                  char buf[1024];
+                  const char *message;
+
+                  message = svn_err_best_message(err, buf, sizeof(buf));
+                  SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
+                                              message));
                   svn_error_clear(err);
-                  err = SVN_NO_ERROR;
+                  *external_failed = TRUE;
                 }
-              SVN_ERR(err);
+              else if (err)
+                return svn_error_trace(err);
+              option_id = svn_client_conflict_option_merged_text;
             }
         }
+    }
+  else if (accept_which == svn_cl__accept_launch)
+    {
+      const char *base_abspath = NULL;
+      const char *my_abspath = NULL;
+      const char *their_abspath = NULL;
+
+      option_id = svn_client_conflict_option_unspecified;
+
+      if (text_conflicted)
+        SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                      &base_abspath,
+                                                      &their_abspath,
+                                                      conflict, scratch_pool,
+                                                      scratch_pool));
+
+      if (base_abspath && their_abspath && my_abspath && local_abspath)
+        {
+          if (*external_failed)
+            {
+              option_id = svn_client_conflict_option_postpone;
+            }
+          else
+            {
+              svn_boolean_t remains_in_conflict;
+              svn_error_t *err;
+
+              err = svn_cl__merge_file_externally(base_abspath, their_abspath,
+                                                  my_abspath, local_abspath,
+                                                  local_abspath, config,
+                                                  &remains_in_conflict,
+                                                  scratch_pool);
+              if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
+                          err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
+                {
+                  char buf[1024];
+                  const char *message;
+
+                  message = svn_err_best_message(err, buf, sizeof(buf));
+                  SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
+                                              message));
+                  *external_failed = TRUE;
+                  return svn_error_trace(err);
+                }
+              else if (err)
+                return svn_error_trace(err);
 
-      return SVN_NO_ERROR;
+              if (remains_in_conflict)
+                option_id = svn_client_conflict_option_postpone;
+              else
+                option_id = svn_client_conflict_option_merged_text;
+            }
+        }
     }
+  else
+    SVN_ERR_MALFUNCTION();
 
-  /* Non-interactive resolution. */
-  SVN_ERR_ASSERT(option_id != svn_client_conflict_option_unspecified);
+  /* If we are in interactive mode and either the user gave no --accept
+   * option or the option did not apply, then prompt. */
+  if (option_id == svn_client_conflict_option_unspecified)
+    {
+      svn_boolean_t postponed = FALSE;
+      svn_boolean_t printed_description = FALSE;
+      svn_error_t *err;
+
+      *quit = FALSE;
 
-  if (option_id != svn_client_conflict_option_postpone)
+      while (!*resolved && !postponed && !*quit)
+        {
+          err = resolve_conflict_interactively(resolved, &postponed, quit,
+                                               external_failed,
+                                               printed_summary,
+                                               &printed_description,
+                                               conflict,
+                                               editor_cmd, config,
+                                               path_prefix, pb,
+                                               conflict_stats, ctx,
+                                               scratch_pool, scratch_pool);
+          if (err && err->apr_err == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE)
+            {
+              /* Conflict resolution has failed. Let the user try again.
+               * It is always possible to break out of this loop with
+               * the 'quit' or 'postpone' options. */
+              svn_handle_warning2(stderr, err, "svn: ");
+              svn_error_clear(err);
+              err = SVN_NO_ERROR;
+            }
+          SVN_ERR(err);
+        }
+    }
+  else if (option_id == svn_client_conflict_option_postpone)
+    {
+      *resolved = FALSE;
+    }
+  else
     {
       SVN_ERR(mark_conflict_resolved(conflict, option_id,
                                      text_conflicted,
@@ -2097,10 +2129,6 @@ svn_cl__resolve_conflict(svn_boolean_t *
                                      ctx, scratch_pool));
       *resolved = TRUE;
     }
-  else
-    {
-      *resolved = FALSE;
-    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ra-git/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/info-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/info-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svn/info-cmd.c Tue Dec 13 12:36:55 2016
@@ -811,7 +811,7 @@ print_info_item_revision(svn_revnum_t re
       if (target_path)
         SVN_ERR(svn_cmdline_printf(pool, "%-10ld %s", rev, target_path));
       else
-        SVN_ERR(svn_cmdline_printf(pool, "%-10ld", rev));
+        SVN_ERR(svn_cmdline_printf(pool, "%ld", rev));
     }
   else if (target_path)
     SVN_ERR(svn_cmdline_printf(pool, "%-10s %s", "", target_path));

Modified: subversion/branches/ra-git/subversion/svn/list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/list-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/list-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svn/list-cmd.c Tue Dec 13 12:36:55 2016
@@ -351,6 +351,8 @@ svn_cl__list(apr_getopt_t *os,
       const char *target = APR_ARRAY_IDX(targets, i, const char *);
       const char *truepath;
       svn_opt_revision_t peg_revision;
+      apr_array_header_t *patterns = NULL;
+      int k;
 
       /* Initialize the following variables for
          every list target. */
@@ -375,8 +377,27 @@ svn_cl__list(apr_getopt_t *os,
           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
         }
 
-      err = svn_client_list3(truepath, &peg_revision,
-                             &(opt_state->start_revision),
+      if (opt_state->search_patterns)
+        {
+          patterns = apr_array_make(subpool, 4, sizeof(const char *));
+          for (k = 0; k < opt_state->search_patterns->nelts; ++k)
+            {
+              apr_array_header_t *pattern_group
+                = APR_ARRAY_IDX(opt_state->search_patterns, k,
+                                apr_array_header_t *);
+
+              /* Should never fail but ... */
+              if (pattern_group->nelts != 1)
+                return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                  _("'search-and' option is not supported"));
+
+              APR_ARRAY_PUSH(patterns, const char *)
+                = APR_ARRAY_IDX(pattern_group, 0, const char *);
+            }
+        }
+
+      err = svn_client_list4(truepath, &peg_revision,
+                             &(opt_state->start_revision), patterns,
                              opt_state->depth,
                              dirent_fields,
                              (opt_state->xml || opt_state->verbose),

Modified: subversion/branches/ra-git/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/merge-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svn/merge-cmd.c Tue Dec 13 12:36:55 2016
@@ -547,7 +547,7 @@ svn_cl__merge(apr_getopt_t *os,
   SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats,
                                            pool, pool));
   if (conflicted_paths)
-    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, FALSE,
+    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats,
                                    opt_state, ctx, pool));
 
   if (!opt_state->quiet)

Modified: subversion/branches/ra-git/subversion/svn/resolve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/resolve-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/resolve-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svn/resolve-cmd.c Tue Dec 13 12:36:55 2016
@@ -43,12 +43,11 @@
 struct conflict_status_walker_baton
 {
   svn_client_ctx_t *ctx;
-  svn_client_conflict_option_id_t option_id;
   svn_wc_notify_func2_t notify_func;
   void *notify_baton;
   svn_boolean_t resolved_one;
   apr_hash_t *resolve_later;
-  svn_cl__accept_t *accept_which;
+  svn_cl__accept_t accept_which;
   svn_boolean_t *quit;
   svn_boolean_t *external_failed;
   svn_boolean_t *printed_summary;
@@ -141,14 +140,12 @@ conflict_status_walker(void *baton,
                                   iterpool, iterpool));
   SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted,
                                              conflict, iterpool, iterpool));
-  err = svn_cl__resolve_conflict(&resolved, cswb->accept_which,
-                                 cswb->quit, cswb->external_failed,
-                                 cswb->printed_summary,
-                                 conflict, cswb->editor_cmd,
+  err = svn_cl__resolve_conflict(&resolved, cswb->quit, cswb->external_failed,
+                                 cswb->printed_summary, conflict,
+                                 cswb->accept_which, cswb->editor_cmd,
                                  cswb->config, cswb->path_prefix,
                                  cswb->pb, cswb->conflict_stats,
-                                 cswb->option_id, cswb->ctx,
-                                 scratch_pool);
+                                 cswb->ctx, scratch_pool);
   if (err)
     {
       if (tree_conflicted)
@@ -175,8 +172,7 @@ static svn_error_t *
 walk_conflicts(svn_client_ctx_t *ctx,
                const char *local_abspath,
                svn_depth_t depth,
-               svn_client_conflict_option_id_t option_id,
-               svn_cl__accept_t *accept_which,
+               svn_cl__accept_t accept_which,
                svn_boolean_t *quit,
                svn_boolean_t *external_failed,
                svn_boolean_t *printed_summary,
@@ -195,7 +191,6 @@ walk_conflicts(svn_client_ctx_t *ctx,
     depth = svn_depth_infinity;
 
   cswb.ctx = ctx;
-  cswb.option_id = option_id;
 
   cswb.resolved_one = FALSE;
   cswb.resolve_later = (depth != svn_depth_empty)
@@ -257,7 +252,6 @@ walk_conflicts(svn_client_ctx_t *ctx,
 
       for (; hi && !err; hi = apr_hash_next(hi))
         {
-          const char *relpath;
           svn_pool_clear(iterpool);
 
           tc_abspath = apr_hash_this_key(hi);
@@ -265,24 +259,8 @@ walk_conflicts(svn_client_ctx_t *ctx,
           if (ctx->cancel_func)
             SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-          relpath = svn_dirent_skip_ancestor(local_abspath,
-                                             tc_abspath);
-
-          if (!relpath
-              || (depth >= svn_depth_empty
-                  && depth < svn_depth_infinity
-                  && strchr(relpath, '/')))
-            {
-              continue;
-            }
-
           SVN_ERR(svn_wc_status3(&status, ctx->wc_ctx, tc_abspath,
                                  iterpool, iterpool));
-
-          if (depth == svn_depth_files
-              && status->kind == svn_node_dir)
-            continue;
-
           err = svn_error_trace(conflict_status_walker(&cswb, tc_abspath,
                                                        status, scratch_pool));
         }
@@ -356,7 +334,6 @@ walk_conflicts(svn_client_ctx_t *ctx,
 svn_error_t *
 svn_cl__walk_conflicts(apr_array_header_t *targets,
                        svn_cl__conflict_stats_t *conflict_stats,
-                       svn_boolean_t is_resolve_cmd,
                        svn_cl__opt_state_t *opt_state,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *scratch_pool)
@@ -365,7 +342,6 @@ svn_cl__walk_conflicts(apr_array_header_
   svn_boolean_t quit = FALSE;
   svn_boolean_t external_failed = FALSE;
   svn_boolean_t printed_summary = FALSE;
-  svn_client_conflict_option_id_t option_id;
   svn_cmdline_prompt_baton_t *pb = apr_palloc(scratch_pool, sizeof(*pb));
   const char *path_prefix;
   svn_error_t *err;
@@ -377,51 +353,6 @@ svn_cl__walk_conflicts(apr_array_header_
   pb->cancel_func = ctx->cancel_func;
   pb->cancel_baton = ctx->cancel_baton;
 
-  switch (opt_state->accept_which)
-    {
-    case svn_cl__accept_working:
-      option_id = svn_client_conflict_option_merged_text;
-      break;
-    case svn_cl__accept_base:
-      option_id = svn_client_conflict_option_base_text;
-      break;
-    case svn_cl__accept_theirs_conflict:
-      option_id = svn_client_conflict_option_incoming_text_where_conflicted;
-      break;
-    case svn_cl__accept_mine_conflict:
-      option_id = svn_client_conflict_option_working_text_where_conflicted;
-      break;
-    case svn_cl__accept_theirs_full:
-      option_id = svn_client_conflict_option_incoming_text;
-      break;
-    case svn_cl__accept_mine_full:
-      option_id = svn_client_conflict_option_working_text;
-      break;
-    case svn_cl__accept_unspecified:
-      if (is_resolve_cmd && opt_state->non_interactive)
-        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                _("missing --accept option"));
-      option_id = svn_client_conflict_option_unspecified;
-      break;
-    case svn_cl__accept_postpone:
-      if (is_resolve_cmd)
-        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                _("invalid 'accept' ARG"));
-      option_id = svn_client_conflict_option_postpone;
-      break;
-    case svn_cl__accept_edit:
-    case svn_cl__accept_launch:
-      if (is_resolve_cmd)
-        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                _("invalid 'accept' ARG"));
-      option_id = svn_client_conflict_option_unspecified;
-      break;
-    default:
-      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                              _("invalid 'accept' ARG"));
-    }
-
-
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < targets->nelts; i++)
     {
@@ -442,19 +373,18 @@ svn_cl__walk_conflicts(apr_array_header_
           SVN_ERR(svn_client_conflict_get(&conflict, local_abspath, ctx,
                                           iterpool, iterpool));
           err = svn_cl__resolve_conflict(&resolved,
-                                         &opt_state->accept_which,
                                          &quit, &external_failed,
                                          &printed_summary,
-                                         conflict, opt_state->editor_cmd,
+                                         conflict, opt_state->accept_which,
+                                         opt_state->editor_cmd,
                                          ctx->config, path_prefix,
                                          pb, conflict_stats,
-                                         option_id, ctx,
-                                         iterpool);
+                                         ctx, iterpool);
         }
       else
         {
           err = walk_conflicts(ctx, local_abspath, opt_state->depth,
-                               option_id, &opt_state->accept_which,
+                               opt_state->accept_which,
                                &quit, &external_failed, &printed_summary,
                                opt_state->editor_cmd, ctx->config,
                                path_prefix, pb, conflict_stats, iterpool);
@@ -462,6 +392,16 @@ svn_cl__walk_conflicts(apr_array_header_
 
       if (err)
         {
+          svn_error_t *root = svn_error_root_cause(err);
+
+          if (root->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+            {
+              /* ### Ignore. These errors can happen due to the working copy
+               * ### being re-arranged during tree conflict resolution. */
+              svn_error_clear(err);
+              continue;
+            }
+
           svn_handle_warning2(stderr, svn_error_root_cause(err), "svn: ");
           svn_error_clear(err);
           had_error = TRUE;
@@ -507,7 +447,21 @@ svn_cl__resolve(apr_getopt_t *os,
 
   SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
 
-  SVN_ERR(svn_cl__walk_conflicts(targets, conflict_stats, TRUE,
+  if (opt_state->accept_which == svn_cl__accept_unspecified &&
+      opt_state->non_interactive)
+    {
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("missing --accept option"));
+    }
+  else if (opt_state->accept_which == svn_cl__accept_postpone ||
+           opt_state->accept_which == svn_cl__accept_edit ||
+           opt_state->accept_which == svn_cl__accept_launch)
+    {
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("invalid 'accept' ARG"));
+    }
+
+  SVN_ERR(svn_cl__walk_conflicts(targets, conflict_stats,
                                  opt_state, ctx, scratch_pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ra-git/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/svn.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/svn.c (original)
+++ subversion/branches/ra-git/subversion/svn/svn.c Tue Dec 13 12:36:55 2016
@@ -143,7 +143,7 @@ typedef enum svn_cl__longopt_t {
   opt_show_passwords,
   opt_pin_externals,
   opt_show_item,
-  opt_adds_as_modification,
+  opt_adds_as_modification
 } svn_cl__longopt_t;
 
 
@@ -798,7 +798,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "    Size (in bytes)\n"
      "    Date and time of the last commit\n"),
     {'r', 'v', 'R', opt_depth, opt_incremental, opt_xml,
-     opt_include_externals}, },
+     opt_include_externals, opt_search}, },
 
   { "lock", svn_cl__lock, {0}, N_
     ("Lock working copy paths or URLs in the repository, so that\n"
@@ -833,6 +833,17 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "  reverse ranges is allowed.\n"
      "\n"
      "  With -v, also print all affected paths with each log message.\n"
+     "  Each changed path is preceded with a symbol describing the change:\n"
+     "    A: The path was added or copied.\n"
+     "    D: The path was deleted.\n"
+     "    R: The path was replaced (deleted and re-added in the same revision).\n"
+     "    M: The path's file and/or property content was modified.\n"
+     "  If an added or replaced path was copied from somewhere else, the copy\n"
+     "  source path and revision are shown in parentheses.\n"
+     "  If a file or directory was moved from one path to another with 'svn move'\n"
+     "  the old path will be listed as deleted and the new path will be listed\n"
+     "  as copied from the old path at a prior revision.\n"
+     "\n"
      "  With -q, don't print the log message body itself (note that this is\n"
      "  compatible with -v).\n"
      "\n"
@@ -885,7 +896,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "\n"
      "    Show the log message for the revision in which /branches/foo\n"
      "    was created:\n"
-     "      svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\n"),
+     "      svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\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"
+     "       A /trunk/bar.c (from /trunk/foo.c:21)\n"),
     {'r', 'c', 'q', 'v', 'g', opt_targets, opt_stop_on_copy, opt_incremental,
      opt_xml, 'l', opt_with_all_revprops, opt_with_no_revprops,
      opt_with_revprop, opt_depth, opt_diff, opt_diff_cmd,
@@ -1542,7 +1558,47 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "\n"
      "  The --accept=ARG option prevents interactive prompting and forces\n"
      "  conflicts on PATH to be resolved in the manner specified by ARG.\n"
-     "  In this mode, the command is not recursive by default (depth 'empty').\n"),
+     "  In this mode, the command is not recursive by default (depth 'empty').\n"
+     "\n"
+     "  A conflicted path cannot be committed with 'svn commit' until it\n"
+     "  has been marked as resolved with 'svn resolve'.\n"
+     "\n"
+     "  Subversion knows three types of conflicts:\n"
+     "  Text conflicts, Property conflicts, and Tree conflicts.\n"
+     "\n"
+     "  Text conflicts occur when overlapping changes to file contents were\n"
+     "  made. Text conflicts are usually resolved by editing the conflicted\n"
+     "  file or by using a merge tool (which may be an external program).\n"
+     "  'svn resolve' provides options which can be used to automatically\n"
+     "  edit files (such as 'mine-full' or 'theirs-conflict'), but these are\n"
+     "  only useful in situations where it is acceptable to discard local or\n"
+     "  incoming changes altogether.\n"
+     "\n"
+     "  Property conflicts are usually resolved by editing the value of the\n"
+     "  conflicted property (either from the interactive prompt, or with\n"
+     "  'svn propedit'). As with text conflicts, options exist to edit a\n"
+     "  property automatically, discarding some changes in favour of others.\n"
+     "\n"
+     "  Tree conflicts occur when a change to the directory structure was\n"
+     "  made, and when this change cannot be applied to the working copy\n"
+     "  without affecting other changes (text changes, property changes,\n"
+     "  or other changes to the directory structure). Brief information about\n"     "  tree conflicts is shown by the 'svn status' and'svn info' commands.\n"
+     "  In interactive mode, 'svn resolve' will attempt to describe tree conflicts\n"
+     "  in detail, and may offer options to resolve the conflict automatically.\n"
+     "  It is recommended to use these automatic options whenever possible,\n"
+     "  rather than attempting manual tree conflict resolution.\n"
+     "\n"
+     "  If a tree conflict cannot be resolved automatically, it is recommended\n"
+     "  to figure out why the conflict occurred before attempting to resolve it.\n"
+     "  The 'svn log -v' command can be used to inspect structural changes\n"
+     "  made in past revisions, and perhaps even on other branches.\n"
+     "  'svn help log' describes how these structural changes are presented.\n"
+     "  Once the conflicting \"incoming\" change has been identified with 'svn log'\n"
+     "  the current \"local\" working copy state should be examined and adjusted\n"
+     "  in a way such that the conflict is resolved. This may involve editing\n"
+     "  files manually or with 'svn merge'. It may be necessary to discard some\n"
+     "  local changes with 'svn revert'. Files or directories might have to be\n"
+     "  copied, deleted, or moved.\n"),
     {opt_targets, 'R', opt_depth, 'q', opt_accept},
     {{opt_accept, N_("specify automatic conflict resolution source\n"
                      "                             "

Modified: subversion/branches/ra-git/subversion/svn/switch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/switch-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/switch-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svn/switch-cmd.c Tue Dec 13 12:36:55 2016
@@ -195,7 +195,7 @@ svn_cl__switch(apr_getopt_t *os,
   SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats,
                                            scratch_pool, scratch_pool));
   if (conflicted_paths)
-    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, FALSE,
+    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats,
                                    opt_state, ctx, scratch_pool));
 
   if (! opt_state->quiet)

Modified: subversion/branches/ra-git/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/update-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/update-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svn/update-cmd.c Tue Dec 13 12:36:55 2016
@@ -185,7 +185,7 @@ svn_cl__update(apr_getopt_t *os,
   SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats,
                                            scratch_pool, scratch_pool));
   if (conflicted_paths)
-    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, FALSE,
+    SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats,
                                    opt_state, ctx, scratch_pool));
 
   if (! opt_state->quiet)

Modified: subversion/branches/ra-git/subversion/svnbench/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svnbench/cl.h?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svnbench/cl.h (original)
+++ subversion/branches/ra-git/subversion/svnbench/cl.h Tue Dec 13 12:36:55 2016
@@ -95,6 +95,7 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t trust_server_cert_expired;
   svn_boolean_t trust_server_cert_not_yet_valid;
   svn_boolean_t trust_server_cert_other_failure;
+  apr_array_header_t* search_patterns; /* pattern arguments for --search */
 } svn_cl__opt_state_t;
 
 

Modified: subversion/branches/ra-git/subversion/svnbench/null-list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svnbench/null-list-cmd.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svnbench/null-list-cmd.c (original)
+++ subversion/branches/ra-git/subversion/svnbench/null-list-cmd.c Tue Dec 13 12:36:55 2016
@@ -122,6 +122,8 @@ svn_cl__null_list(apr_getopt_t *os,
       const char *target = APR_ARRAY_IDX(targets, i, const char *);
       const char *truepath;
       svn_opt_revision_t peg_revision;
+      apr_array_header_t *patterns = NULL;
+      int k;
 
       svn_pool_clear(subpool);
 
@@ -131,8 +133,27 @@ svn_cl__null_list(apr_getopt_t *os,
       SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
                                  subpool));
 
-      err = svn_client_list3(truepath, &peg_revision,
-                             &(opt_state->start_revision),
+      if (opt_state->search_patterns)
+        {
+          patterns = apr_array_make(subpool, 4, sizeof(const char *));
+          for (k = 0; k < opt_state->search_patterns->nelts; ++k)
+            {
+              apr_array_header_t *pattern_group
+                = APR_ARRAY_IDX(opt_state->search_patterns, k,
+                                apr_array_header_t *);
+
+              /* Should never fail but ... */
+              if (pattern_group->nelts != 1)
+                return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                  _("'search-and' option is not supported"));
+
+              APR_ARRAY_PUSH(patterns, const char *)
+                = APR_ARRAY_IDX(pattern_group, 0, const char *);
+            }
+        }
+
+      err = svn_client_list4(truepath, &peg_revision,
+                             &(opt_state->start_revision), patterns,
                              opt_state->depth,
                              dirent_fields,
                              opt_state->verbose,

Modified: subversion/branches/ra-git/subversion/svnbench/svnbench.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svnbench/svnbench.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svnbench/svnbench.c (original)
+++ subversion/branches/ra-git/subversion/svnbench/svnbench.c Tue Dec 13 12:36:55 2016
@@ -41,6 +41,7 @@
 #include "private/svn_opt_private.h"
 #include "private/svn_cmdline_private.h"
 #include "private/svn_string_private.h"
+#include "private/svn_utf_private.h"
 
 #include "svn_private_config.h"
 
@@ -67,7 +68,8 @@ typedef enum svn_cl__longopt_t {
   opt_with_no_revprops,
   opt_trust_server_cert,
   opt_trust_server_cert_failures,
-  opt_changelist
+  opt_changelist,
+  opt_search
 } svn_cl__longopt_t;
 
 
@@ -164,6 +166,8 @@ const apr_getopt_option_t svn_cl__option
                     N_("use/display additional information from merge\n"
                        "                             "
                        "history")},
+  {"search", opt_search, 1,
+                       N_("use ARG as search pattern (glob syntax)")},
 
   /* Long-opt Aliases
    *
@@ -256,7 +260,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "    If locked, the letter 'O'.  (Use 'svn info URL' to see details)\n"
      "    Size (in bytes)\n"
      "    Date and time of the last commit\n"),
-    {'r', 'v', 'q', 'R', opt_depth} },
+    {'r', 'v', 'q', 'R', opt_depth, opt_search} },
 
   { "null-log", svn_cl__null_log, {0}, N_
     ("Fetch the log messages for a set of revision(s) and/or path(s).\n"
@@ -345,6 +349,24 @@ ra_progress_func(apr_off_t progress,
 /* Our cancellation callback. */
 svn_cancel_func_t svn_cl__check_cancel = NULL;
 
+/* Add a --search argument to OPT_STATE.
+ * These options start a new search pattern group. */
+static void
+add_search_pattern_group(svn_cl__opt_state_t *opt_state,
+                         const char *pattern,
+                         apr_pool_t *result_pool)
+{
+  apr_array_header_t *group = NULL;
+
+  if (opt_state->search_patterns == NULL)
+    opt_state->search_patterns = apr_array_make(result_pool, 1,
+                                                sizeof(apr_array_header_t *));
+
+  group = apr_array_make(result_pool, 1, sizeof(const char *));
+  APR_ARRAY_PUSH(group, const char *) = pattern;
+  APR_ARRAY_PUSH(opt_state->search_patterns, apr_array_header_t *) = group;
+}
+
 
 /*** Main. ***/
 
@@ -371,9 +393,13 @@ sub_main(int *exit_code, int argc, const
   svn_boolean_t use_notifier = TRUE;
   apr_time_t start_time, time_taken;
   ra_progress_baton_t ra_progress_baton = {0};
+  svn_membuf_t buf;
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
+  /* Init the temporary buffer. */
+  svn_membuf__create(&buf, 0, pool);
+
   /* Check library versions */
   SVN_ERR(check_lib_versions());
 
@@ -656,6 +682,14 @@ sub_main(int *exit_code, int argc, const
       case 'g':
         opt_state.use_merge_history = TRUE;
         break;
+      case opt_search:
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf__xfrm(&utf8_opt_arg, utf8_opt_arg,
+                              strlen(utf8_opt_arg), TRUE, TRUE, &buf));
+        add_search_pattern_group(&opt_state,
+                                 apr_pstrdup(pool, utf8_opt_arg),
+                                 pool);
+        break;
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away
            opts that commands like svn diff might need. Hmmm indeed. */

Modified: subversion/branches/ra-git/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svnmucc/svnmucc.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/ra-git/subversion/svnmucc/svnmucc.c Tue Dec 13 12:36:55 2016
@@ -480,7 +480,7 @@ sub_main(int *exit_code, int argc, const
     non_interactive_opt,
     force_interactive_opt,
     trust_server_cert_opt,
-    trust_server_cert_failures_opt,
+    trust_server_cert_failures_opt
   };
   static const apr_getopt_option_t options[] = {
     {"message", 'm', 1, ""},

Modified: subversion/branches/ra-git/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svnserve/serve.c?rev=1773992&r1=1773991&r2=1773992&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svnserve/serve.c (original)
+++ subversion/branches/ra-git/subversion/svnserve/serve.c Tue Dec 13 12:36:55 2016
@@ -1679,11 +1679,11 @@ get_file(svn_ra_svn_conn_t *conn,
   return SVN_NO_ERROR;
 }
 
+/* Translate all the words in DIRENT_FIELDS_LIST into the flags in
+ * DIRENT_FIELDS_P.  If DIRENT_FIELDS_LIST is NULL, set all flags. */
 static svn_error_t *
-get_dir(svn_ra_svn_conn_t *conn,
-        apr_pool_t *pool,
-        svn_ra_svn__list_t *params,
-        void *baton)
+parse_dirent_fields(apr_uint64_t *dirent_fields_p,
+                    svn_ra_svn__list_t *dirent_fields_list)
 {
   static const svn_string_t str_kind
     = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_KIND);
@@ -1698,32 +1698,7 @@ get_dir(svn_ra_svn_conn_t *conn,
   static const svn_string_t str_last_author
     = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_LAST_AUTHOR);
 
-  server_baton_t *b = baton;
-  const char *path, *full_path;
-  svn_revnum_t rev;
-  apr_hash_t *entries, *props = NULL;
-  apr_array_header_t *inherited_props;
-  apr_hash_index_t *hi;
-  svn_fs_root_t *root;
-  apr_pool_t *subpool;
-  svn_boolean_t want_props, want_contents;
-  apr_uint64_t wants_inherited_props;
   apr_uint64_t dirent_fields;
-  svn_ra_svn__list_t *dirent_fields_list = NULL;
-  svn_ra_svn__item_t *elt;
-  int i;
-  authz_baton_t ab;
-
-  ab.server = b;
-  ab.conn = conn;
-
-  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)bb?l?B", &path, &rev,
-                                  &want_props, &want_contents,
-                                  &dirent_fields_list,
-                                  &wants_inherited_props));
-
-  if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
-    wants_inherited_props = FALSE;
 
   if (! dirent_fields_list)
     {
@@ -1731,15 +1706,17 @@ get_dir(svn_ra_svn_conn_t *conn,
     }
   else
     {
+      int i;
       dirent_fields = 0;
 
       for (i = 0; i < dirent_fields_list->nelts; ++i)
         {
-          elt = &SVN_RA_SVN__LIST_ITEM(dirent_fields_list, i);
+          svn_ra_svn__item_t *elt
+            = &SVN_RA_SVN__LIST_ITEM(dirent_fields_list, i);
 
           if (elt->kind != SVN_RA_SVN_WORD)
             return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
-                                    "Dirent field not a string");
+                                    "Dirent field not a word");
 
           if (svn_string_compare(&str_kind, &elt->u.word))
             dirent_fields |= SVN_DIRENT_KIND;
@@ -1756,6 +1733,43 @@ get_dir(svn_ra_svn_conn_t *conn,
         }
     }
 
+  *dirent_fields_p = dirent_fields;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+get_dir(svn_ra_svn_conn_t *conn,
+        apr_pool_t *pool,
+        svn_ra_svn__list_t *params,
+        void *baton)
+{
+  server_baton_t *b = baton;
+  const char *path, *full_path;
+  svn_revnum_t rev;
+  apr_hash_t *entries, *props = NULL;
+  apr_array_header_t *inherited_props;
+  apr_hash_index_t *hi;
+  svn_fs_root_t *root;
+  apr_pool_t *subpool;
+  svn_boolean_t want_props, want_contents;
+  apr_uint64_t wants_inherited_props;
+  apr_uint64_t dirent_fields;
+  svn_ra_svn__list_t *dirent_fields_list = NULL;
+  int i;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
+
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)bb?l?B", &path, &rev,
+                                  &want_props, &want_contents,
+                                  &dirent_fields_list,
+                                  &wants_inherited_props));
+
+  if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
+    wants_inherited_props = FALSE;
+
+  SVN_ERR(parse_dirent_fields(&dirent_fields, dirent_fields_list));
   full_path = svn_fspath__join(b->repository->fs_path->data,
                                svn_relpath_canonicalize(path, pool), pool);
 
@@ -3524,6 +3538,114 @@ get_inherited_props(svn_ra_svn_conn_t *c
   return SVN_NO_ERROR;
 }
 
+/* Baton type to be used with list_receiver. */
+typedef struct list_receiver_baton_t
+{
+  /* Send the data through this connection. */
+  svn_ra_svn_conn_t *conn;
+
+  /* Send the field selected by these flags. */
+  apr_uint64_t dirent_fields;
+} list_receiver_baton_t;
+
+/* Implements svn_repos_dirent_receiver_t, sending DIRENT and PATH to the
+ * client.  BATON must be a list_receiver_baton_t. */
+static svn_error_t *
+list_receiver(const char *path,
+              svn_dirent_t *dirent,
+              void *baton,
+              apr_pool_t *pool)
+{
+  list_receiver_baton_t *b = baton;
+  return svn_error_trace(svn_ra_svn__write_dirent(b->conn, pool, path, dirent,
+                                                  b->dirent_fields));
+}
+
+static svn_error_t *
+list(svn_ra_svn_conn_t *conn,
+     apr_pool_t *pool,
+     svn_ra_svn__list_t *params,
+     void *baton)
+{
+  server_baton_t *b = baton;
+  const char *path, *full_path;
+  svn_revnum_t rev;
+  svn_depth_t depth;
+  apr_array_header_t *patterns = NULL;
+  svn_fs_root_t *root;
+  const char *depth_word;
+  svn_boolean_t path_info_only;
+  svn_ra_svn__list_t *dirent_fields_list = NULL;
+  svn_ra_svn__list_t *patterns_list = NULL;
+  int i;
+  list_receiver_baton_t rb;
+  svn_error_t *err, *write_err;
+
+  authz_baton_t ab;
+  ab.server = b;
+  ab.conn = conn;
+
+  /* Read the command parameters. */
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)w?l?l", &path, &rev,
+                                  &depth_word, &dirent_fields_list,
+                                  &patterns_list));
+
+  rb.conn = conn;
+  SVN_ERR(parse_dirent_fields(&rb.dirent_fields, dirent_fields_list));
+
+  depth = svn_depth_from_word(depth_word);
+  full_path = svn_fspath__join(b->repository->fs_path->data,
+                               svn_relpath_canonicalize(path, pool), pool);
+
+  /* Read the patterns list.  */
+  if (patterns_list)
+    {
+      patterns = apr_array_make(pool, 0, sizeof(const char *));
+      for (i = 0; i < patterns_list->nelts; ++i)
+        {
+          svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(patterns_list, i);
+
+          if (elt->kind != SVN_RA_SVN_STRING)
+            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                                    "Pattern field not a string");
+
+          APR_ARRAY_PUSH(patterns, const char *) = elt->u.string.data;
+        }
+    }
+
+  /* Check authorizations */
+  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
+                           full_path, FALSE));
+
+  if (!SVN_IS_VALID_REVNUM(rev))
+    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));
+
+  SVN_ERR(log_command(b, conn, pool, "%s",
+                      svn_log__list(full_path, rev, patterns, depth,
+                                    rb.dirent_fields, pool)));
+
+  /* Fetch the root of the appropriate revision. */
+  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, pool));
+
+  /* Fetch the directory entries if requested and send them immediately. */
+  path_info_only = (rb.dirent_fields & ~SVN_DIRENT_KIND) == 0;
+  err = svn_repos_list(root, full_path, patterns, depth, path_info_only,
+                       authz_check_access_cb_func(b), &ab, list_receiver,
+                       &rb, NULL, NULL, pool);
+
+
+  /* Finish response. */
+  write_err = svn_ra_svn__write_word(conn, pool, "done");
+  if (write_err)
+    {
+      svn_error_clear(err);
+      return write_err;
+    }
+  SVN_CMD_ERR(err);
+
+  return svn_error_trace(svn_ra_svn__write_cmd_response(conn, pool, ""));
+}
+
 static const svn_ra_svn__cmd_entry_t main_commands[] = {
   { "reparent",        reparent },
   { "get-latest-rev",  get_latest_rev },
@@ -3556,6 +3678,7 @@ static const svn_ra_svn__cmd_entry_t mai
   { "replay-range",    replay_range },
   { "get-deleted-rev", get_deleted_rev },
   { "get-iprops",      get_inherited_props },
+  { "list",            list },
   { NULL }
 };
 
@@ -3747,6 +3870,7 @@ find_repos(const char *url,
   if (hooks_env)
     hooks_env = svn_dirent_internal_style(hooks_env, scratch_pool);
 
+  SVN_ERR(svn_repos_hooks_setenv(repository->repos, hooks_env, scratch_pool));
   repository->hooks_env = apr_pstrdup(result_pool, hooks_env);
 
   return SVN_NO_ERROR;
@@ -3954,7 +4078,7 @@ construct_server_baton(server_baton_t **
    * send an empty mechlist. */
   if (params->compression_level > 0)
     SVN_ERR(svn_ra_svn__write_cmd_response(conn, scratch_pool,
-                                           "nn()(wwwwwwwwwww)",
+                                           "nn()(wwwwwwwwwwww)",
                                            (apr_uint64_t) 2, (apr_uint64_t) 2,
                                            SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                            SVN_RA_SVN_CAP_SVNDIFF1,
@@ -3966,11 +4090,12 @@ construct_server_baton(server_baton_t **
                                            SVN_RA_SVN_CAP_PARTIAL_REPLAY,
                                            SVN_RA_SVN_CAP_INHERITED_PROPS,
                                            SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS,
-                                           SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE
+                                           SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE,
+                                           SVN_RA_SVN_CAP_LIST
                                            ));
   else
     SVN_ERR(svn_ra_svn__write_cmd_response(conn, scratch_pool,
-                                           "nn()(wwwwwwwwww)",
+                                           "nn()(wwwwwwwwwww)",
                                            (apr_uint64_t) 2, (apr_uint64_t) 2,
                                            SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                            SVN_RA_SVN_CAP_ABSENT_ENTRIES,
@@ -3981,7 +4106,8 @@ construct_server_baton(server_baton_t **
                                            SVN_RA_SVN_CAP_PARTIAL_REPLAY,
                                            SVN_RA_SVN_CAP_INHERITED_PROPS,
                                            SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS,
-                                           SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE
+                                           SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE,
+                                           SVN_RA_SVN_CAP_LIST
                                            ));
 
   /* Read client response, which we assume to be in version 2 format: