Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_fs.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_fs.h (original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_fs.h Mon Apr 
16 12:21:02 2018
@@ -1744,7 +1744,7 @@ svn_fs_paths_changed3(svn_fs_path_change
  *
  * Use @a pool for all allocations, including the hash and its values.
  *
- * @note Retrieving the #node_rev_id element of #svn_fs_path_change2_t may
+ * @note Retrieving the #svn_fs_path_change2_t.node_rev_id element may
  *       be expensive in some FS backends.
  *
  * @since New in 1.6.
@@ -2492,7 +2492,7 @@ svn_fs_file_md5_checksum(unsigned char d
  * svn_fs_file_contents().  In that case, the result of reading from
  * @a *contents is undefined.
  *
- * ### @todo kff: I am worried about lifetime issues with this pool vs
+ * @todo kff: I am worried about lifetime issues with this pool vs
  * the trail created farther down the call stack.  Trace this function
  * to investigate...
  */

Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_opt.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_opt.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_opt.h 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_opt.h Mon Apr 
16 12:21:02 2018
@@ -69,6 +69,10 @@ typedef svn_error_t *(svn_opt_subcommand
 /** The maximum number of options that can be accepted by a subcommand. */
 #define SVN_OPT_MAX_OPTIONS 50
 
+/** The maximum number of paragraphs of help text a subcommand can have.
+ * @since New in 1.11. */
+#define SVN_OPT_MAX_PARAGRAPHS 100
+
 /** Options that have no short option char should use an identifying
  * integer equal to or greater than this.
  */
@@ -77,7 +81,39 @@ typedef svn_error_t *(svn_opt_subcommand
 
 /** One element of a subcommand dispatch table.
  *
+ * @since New in 1.11.
+ */
+typedef struct svn_opt_subcommand_desc3_t
+{
+  /** The full name of this command. */
+  const char *name;
+
+  /** The function this command invokes. */
+  svn_opt_subcommand_t *cmd_func;
+
+  /** A list of alias names for this command (e.g., 'up' for 'update'). */
+  const char *aliases[SVN_OPT_MAX_ALIASES];
+
+  /** A multi-paragraph string describing this command. */
+  const char *help[SVN_OPT_MAX_PARAGRAPHS];
+
+  /** A list of options accepted by this command.  Each value in the
+   * array is a unique enum (the 2nd field in apr_getopt_option_t)
+   */
+  int valid_options[SVN_OPT_MAX_OPTIONS];
+
+  /** A list of option help descriptions, keyed by the option unique enum
+   * (the 2nd field in apr_getopt_option_t), which override the generic
+   * descriptions given in an apr_getopt_option_t on a per-subcommand basis.
+   */
+  struct { int optch; const char *desc; } desc_overrides[SVN_OPT_MAX_OPTIONS];
+} svn_opt_subcommand_desc3_t;
+
+
+/** One element of a subcommand dispatch table.
+ *
  * @since New in 1.4.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
  */
 typedef struct svn_opt_subcommand_desc2_t
 {
@@ -139,8 +175,21 @@ typedef struct svn_opt_subcommand_desc_t
  * Return the entry in @a table whose name matches @a cmd_name, or @c NULL if
  * none.  @a cmd_name may be an alias.
  *
+ * @since New in 1.11.
+ */
+const svn_opt_subcommand_desc3_t *
+svn_opt_get_canonical_subcommand3(const svn_opt_subcommand_desc3_t *table,
+                                  const char *cmd_name);
+
+
+/**
+ * Same as svn_opt_get_canonical_subcommand3(), but with a different
+ * version of the subcommand description table.
+ *
  * @since New in 1.4.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
  */
+SVN_DEPRECATED
 const svn_opt_subcommand_desc2_t *
 svn_opt_get_canonical_subcommand2(const svn_opt_subcommand_desc2_t *table,
                                   const char *cmd_name);
@@ -170,8 +219,22 @@ svn_opt_get_canonical_subcommand(const s
  *
  * The returned value may be statically allocated, or allocated in @a pool.
  *
+ * @since New in 1.11.
+ */
+const apr_getopt_option_t *
+svn_opt_get_option_from_code3(int code,
+                              const apr_getopt_option_t *option_table,
+                              const svn_opt_subcommand_desc3_t *command,
+                              apr_pool_t *pool);
+
+/**
+ * Same as svn_opt_get_option_from_code3(), but with a different
+ * version of the subcommand description table.
+ *
  * @since New in 1.4.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
  */
+SVN_DEPRECATED
 const apr_getopt_option_t *
 svn_opt_get_option_from_code2(int code,
                               const apr_getopt_option_t *option_table,
@@ -198,8 +261,21 @@ svn_opt_get_option_from_code(int code,
  * non-NULL, it is a zero-terminated array, and all subcommands take
  * the options listed in it.
  *
+ * @since New in 1.11.
+ */
+svn_boolean_t
+svn_opt_subcommand_takes_option4(const svn_opt_subcommand_desc3_t *command,
+                                 int option_code,
+                                 const int *global_options);
+
+/**
+ * Same as svn_opt_subcommand_takes_option4(), but with a different
+ * version of the subcommand description table.
+ *
  * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
  */
+SVN_DEPRECATED
 svn_boolean_t
 svn_opt_subcommand_takes_option3(const svn_opt_subcommand_desc2_t *command,
                                  int option_code,
@@ -235,7 +311,7 @@ svn_opt_subcommand_takes_option(const sv
 /**
  * Print a generic (not command-specific) usage message to @a stream.
  *
- * ### @todo Why is @a stream a stdio file instead of an svn stream?
+ * @todo Why is @a stream a stdio file instead of an svn stream?
  *
  * If @a header is non-NULL, print @a header followed by a newline.  Then
  * loop over @a cmd_table printing the usage for each command (getting
@@ -244,8 +320,24 @@ svn_opt_subcommand_takes_option(const sv
  *
  * Use @a pool for temporary allocation.
  *
+ * @since New in 1.11.
+ */
+void
+svn_opt_print_generic_help3(const char *header,
+                            const svn_opt_subcommand_desc3_t *cmd_table,
+                            const apr_getopt_option_t *opt_table,
+                            const char *footer,
+                            apr_pool_t *pool,
+                            FILE *stream);
+
+/**
+ * Same as svn_opt_print_generic_help3(), but with a different
+ * version of the subcommand description table.
+ *
  * @since New in 1.4.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
  */
+SVN_DEPRECATED
 void
 svn_opt_print_generic_help2(const char *header,
                             const svn_opt_subcommand_desc2_t *cmd_table,
@@ -297,8 +389,23 @@ svn_opt_format_option(const char **strin
  * use that second name as an alias for the first name.  This additional
  * behaviour is new in 1.7.
  *
+ * @since New in 1.11.
+ */
+void
+svn_opt_subcommand_help4(const char *subcommand,
+                         const svn_opt_subcommand_desc3_t *table,
+                         const apr_getopt_option_t *options_table,
+                         const int *global_options,
+                         apr_pool_t *pool);
+
+/**
+ * Same as svn_opt_subcommand_help4(), but with a different
+ * version of the subcommand description table.
+ *
  * @since New in 1.5.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
  */
+SVN_DEPRECATED
 void
 svn_opt_subcommand_help3(const char *subcommand,
                          const svn_opt_subcommand_desc2_t *table,
@@ -709,9 +816,30 @@ svn_opt_parse_path(svn_opt_revision_t *r
  * --version flag *and* subcommand arguments on a help command line.
  * The logic for handling such a situation should be in one place.
  *
- * @since New in 1.8.
+ * @since New in 1.11.
  */
+svn_error_t *
+svn_opt_print_help5(apr_getopt_t *os,
+                    const char *pgm_name,
+                    svn_boolean_t print_version,
+                    svn_boolean_t quiet,
+                    svn_boolean_t verbose,
+                    const char *version_footer,
+                    const char *header,
+                    const svn_opt_subcommand_desc3_t *cmd_table,
+                    const apr_getopt_option_t *option_table,
+                    const int *global_options,
+                    const char *footer,
+                    apr_pool_t *pool);
 
+/**
+ * Same as svn_opt_print_help5(), but with a different
+ * version of the subcommand description table.
+ *
+ * @since New in 1.8.
+ * @deprecated Provided for backward compatibility with the 1.10 API.
+ */
+SVN_DEPRECATED
 svn_error_t *
 svn_opt_print_help4(apr_getopt_t *os,
                     const char *pgm_name,

Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_props.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_props.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_props.h 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_props.h Mon 
Apr 16 12:21:02 2018
@@ -415,19 +415,26 @@ svn_prop_name_is_valid(const char *prop_
 /** Describes external items to check out into this directory.
  *
  * The format is a series of lines, each in the following format:
- *   [-r REV] URL[@PEG] LOCALPATH
+ *
+ *     [-r REV] URL[@PEG] LOCALPATH
+ *
  * LOCALPATH is relative to the directory having this property.
  * REV pins the external to revision REV.
  * URL may be a full URL or a relative URL starting with one of:
- *   ../  to the parent directory of the extracted external
- *   ^/   to the repository root
- *   /    to the server root
- *   //   to the URL scheme
+ *
+ *     ../  to the parent directory of the extracted external
+ *     ^/   to the repository root
+ *     /    to the server root
+ *     //   to the URL scheme
+ *
  * The following format is supported for interoperability with
  * Subversion 1.4 and earlier clients:
- *   LOCALPATH [-r PEG] URL
+ *
+ *     LOCALPATH [-r PEG] URL
+ *
  * The ambiguous format 'relative_path relative_path' is taken as
  * 'relative_url relative_path' with peg revision support.
+ *
  * Lines starting with a '#' character are ignored.
  */
 #define SVN_PROP_EXTERNALS  SVN_PROP_PREFIX "externals"

Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_ra.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_ra.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_ra.h (original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_ra.h Mon Apr 
16 12:21:02 2018
@@ -555,9 +555,9 @@ typedef struct svn_ra_callbacks2_t
 
   /** Fetch working copy properties.
    *
-   *<pre> ### we might have a problem if the RA layer ever wants a property
-   * ### that corresponds to a different revision of the file than
-   * ### what is in the WC. we'll cross that bridge one day...</pre>
+   * @note we might have a problem if the RA layer ever wants a property
+   *       that corresponds to a different revision of the file than
+   *       what is in the WC. we'll cross that bridge one day...
    */
   svn_ra_get_wc_prop_func_t get_wc_prop;
 
@@ -1857,7 +1857,7 @@ svn_ra_get_location_segments(svn_ra_sess
  * @note Prior to Subversion 1.9, this function may request delta handlers
  * from @a handler even for empty text deltas.  Starting with 1.9, the
  * delta handler / baton return arguments passed to @a handler will be
- * #NULL unless there is an actual difference in the file contents between
+ * NULL unless there is an actual difference in the file contents between
  * the current and the previous call.
  *
  * @since New in 1.5.

Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_ra_svn.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_ra_svn.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_ra_svn.h 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_ra_svn.h Mon 
Apr 16 12:21:02 2018
@@ -179,7 +179,9 @@ typedef svn_error_t *(*svn_ra_svn_edit_c
  *
  * Either @a sock or @a in_stream/@a out_stream must be set, not both.
  * @a compression_level specifies the desired network data compression
- * level (zlib) from 0 (no compression) to 9 (best but slowest).
+ * level from 0 (no compression) to 9 (best but slowest). The effect
+ * of the parameter depends on the compression algorithm; for example,
+ * it is used verbatim by zlib/deflate but ignored by LZ4.
  *
  * If @a zero_copy_limit is not 0, cached file contents smaller than the
  * given limit may be sent directly to the network socket.  Otherwise,

Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_repos.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_repos.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_repos.h 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_repos.h Mon 
Apr 16 12:21:02 2018
@@ -861,7 +861,7 @@ typedef svn_error_t *(*svn_repos_freeze_
  * @since New in 1.8.
  */
 svn_error_t *
-svn_repos_freeze(apr_array_header_t *paths,
+svn_repos_freeze(const apr_array_header_t *paths,
                  svn_repos_freeze_func_t freeze_func,
                  void *freeze_baton,
                  apr_pool_t *pool);
@@ -2404,7 +2404,7 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
  * @note Prior to Subversion 1.9, this function may request delta handlers
  * from @a handler even for empty text deltas.  Starting with 1.9, the
  * delta handler / baton return arguments passed to @a handler will be
- * #NULL unless there is an actual difference in the file contents between
+ * NULL unless there is an actual difference in the file contents between
  * the current and the previous call.
  *
  * @since New in 1.5.
@@ -3803,7 +3803,7 @@ typedef struct svn_repos_parse_fns3_t
  *
  * @since New in 1.8.
 
- * @since Starting in 1.10, @a parse_fns may contain #NULL pointers for
+ * @since Starting in 1.10, @a parse_fns may contain NULL pointers for
  * those callbacks that the caller is not interested in.
  */
 svn_error_t *

Modified: 
subversion/branches/shelve-checkpoint/subversion/libsvn_client/client.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/client.h?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/client.h 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/client.h Mon 
Apr 16 12:21:02 2018
@@ -754,40 +754,23 @@ typedef struct svn_client__copy_pair_t
 
 /*** Commit Stuff ***/
 
-/* WARNING: This is all new, untested, un-peer-reviewed conceptual
-   stuff.
+/* The "Harvest Committables" System
 
-   The day that 'svn switch' came into existence, our old commit
-   crawler (svn_wc_crawl_local_mods) became obsolete.  It relied far
-   too heavily on the on-disk hierarchy of files and directories, and
-   simply had no way to support disjoint working copy trees or nest
-   working copies.  The primary reason for this is that commit
-   process, in order to guarantee atomicity, is a single drive of a
+   The commit process requires, per repository, a single drive of a
    commit editor which is based not on working copy paths, but on
-   URLs.  With the completion of 'svn switch', it became all too
-   likely that the on-disk working copy hierarchy would no longer be
-   guaranteed to map to a similar in-repository hierarchy.
-
-   Aside from this new brokenness of the old system, an unrelated
-   feature request had cropped up -- the ability to know in advance of
-   your commit, exactly what would be committed (so that log messages
-   could be initially populated with this information).  Since the old
-   crawler discovered commit candidates while in the process of
-   committing, it was impossible to harvest this information upfront.
-   As a workaround, svn_wc_statuses() was used to stat the whole
-   working copy for changes before the commit started...and then the
-   commit would again stat the whole tree for changes.
-
-   Enter the new system.
+   URLs.  The on-disk working copy hierarchy does not, in general,
+   map to a similar in-repository hierarchy, due to switched subtrees
+   and disjoint working copies.
+
+   Also we wish to know exactly what would be committed, in advance of
+   the commit, so that a log message editor can be initially populated
+   with this information.
 
    The primary goal of this system is very straightforward: harvest
    all commit candidate information up front, and cache enough info in
    the process to use this to drive a URL-sorted commit.
 
-   *** END-OF-KNOWLEDGE ***
-
-   The prototypes below are still in development.  In general, the
-   idea is that commit-y processes ('svn mkdir URL', 'svn delete URL',
+   The idea is that commit-y processes ('svn mkdir URL', 'svn delete URL',
    'svn commit', 'svn copy WC_PATH URL', 'svn copy URL1 URL2', 'svn
    move URL1 URL2', others?) generate the cached commit candidate
    information, and hand this information off to a consumer which is
@@ -844,7 +827,7 @@ typedef svn_error_t *(*svn_client__check
      - if the candidate has a lock token, add it to the LOCK_TOKENS hash.
 
      - if the candidate is a directory scheduled for deletion, crawl
-       the directories children recursively for any lock tokens and
+       the directory's children recursively for any lock tokens and
        add them to the LOCK_TOKENS array.
 
    At the successful return of this function, COMMITTABLES will point
@@ -1129,14 +1112,34 @@ svn_client__resolve_conflicts(svn_boolea
                               svn_client_ctx_t *ctx,
                               apr_pool_t *scratch_pool);
 
-/* Produce a diff with depth DEPTH between two files or two directories at
- * LEFT_ABSPATH1 and RIGHT_ABSPATH, using the provided diff callbacks to
- * show changes in files. The files and directories involved may be part of
- * a working copy or they may be unversioned. For versioned files, show
- * property changes, too.
- *
- * If ANCHOR_ABSPATH is not null, set it to the anchor of the diff before
- * the first processor call. (The anchor is LEFT_ABSPATH or an ancestor of it)
+/* Produce a diff with depth DEPTH between the file or directory at
+ * LEFT_ABSPATH and the file or directory at RIGHT_ABSPATH, reporting
+ * differences to DIFF_PROCESSOR.
+ *
+ * The files and directories involved may be part of a working copy or
+ * they may be unversioned. For versioned files, show property changes,
+ * too.
+ *
+ * No copy or move information is reported to the diff processor.
+ *
+ * If both LEFT_ABSPATH and RIGHT_ABSPATH are directories on disk:
+ *   set *ROOT_RELPATH to "" and
+ *   set *ROOT_IS_DIR to TRUE and
+ *   send diff processor relpaths relative to LEFT_ABSPATH
+ *   (which is the same as relative to RIGHT_ABSPATH);
+ * else:
+ *   set *ROOT_RELPATH to the basename of LEFT_ABSPATH and
+ *   set *ROOT_IS_DIR to FALSE and
+ *   send diff processor relpaths relative to the parent of LEFT_ABSPATH
+ *   (so they all start with a basename(LEFT_ABSPATH) component).
+ *
+ * As any children reached by recursion are matched by name, a diff
+ * processor relpath applies equally to both sides of the diff, except
+ * for its first component in the latter case above.
+ *
+ * Assignments to *ROOT_RELPATH and *ROOT_IS_DIR are made before the first
+ * call to DIFF_PROCESSOR. Each of ROOT_RELPATH and ROOT_IS_DIR may be NULL
+ * if not wanted.
  */
 svn_error_t *
 svn_client__arbitrary_nodes_diff(const char **root_relpath,
@@ -1267,39 +1270,6 @@ svn_client__merge_locked(svn_client__con
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
-/** Set @a shelf's revprop @a prop_name to @a prop_val.
- *
- * If @a prop_val is NULL, delete the property (if present).
- */
-svn_error_t *
-svn_client__shelf_revprop_set(svn_client_shelf_t *shelf,
-                               const char *prop_name,
-                               const svn_string_t *prop_val,
-                               apr_pool_t *scratch_pool);
-
-/** Get @a shelf's revprop @a prop_name into @a *prop_val.
- *
- * If the property is not present, set @a *prop_val to NULL.
- *
- * The lifetime of the result is limited to that of @a shelf and/or
- * of @a result_pool.
- */
-svn_error_t *
-svn_client__shelf_revprop_get(svn_string_t **prop_val,
-                               svn_client_shelf_t *shelf,
-                               const char *prop_name,
-                               apr_pool_t *result_pool);
-
-/** Get @a shelf's revprops into @a props.
- *
- * The lifetime of the result is limited to that of @a shelf and/or
- * of @a result_pool.
- */
-svn_error_t *
-svn_client__shelf_revprop_list(apr_hash_t **props,
-                               svn_client_shelf_t *shelf,
-                               apr_pool_t *result_pool);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: 
subversion/branches/shelve-checkpoint/subversion/libsvn_client/conflicts.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/conflicts.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/conflicts.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/conflicts.c 
Mon Apr 16 12:21:02 2018
@@ -255,7 +255,7 @@ struct repos_move_info {
   /* The revision in which this move was committed. */
   svn_revnum_t rev;
 
-  /* The author who commited the revision in which this move was committed. */
+  /* The author who committed the revision in which this move was committed. */
   const char *rev_author;
 
   /* The repository relpath the node was moved from in this revision. */
@@ -5944,8 +5944,11 @@ describe_incoming_edit_list_modified_rev
             {
               if (i == edits->nelts - (max_revs_to_display / 2))
                   s = apr_psprintf(result_pool,
-                                   _("%s\n [%d revisions omitted for "
-                                     "brevity],\n"),
+                                   Q_("%s\n [%d revision omitted for "
+                                      "brevity],\n",
+                                      "%s\n [%d revisions omitted for "
+                                      "brevity],\n",
+                                      num_revs_to_skip),
                                    s, num_revs_to_skip);
 
               s = apr_psprintf(result_pool, _("%s r%ld by %s%s"), s,
@@ -6704,8 +6707,9 @@ resolve_merge_incoming_added_file_text_u
   /* Revert the path in order to restore the repository's line of
    * history, which is part of the BASE tree. This revert operation
    * is why are being careful about not losing the temporary copy. */
-  err = svn_wc_revert5(ctx->wc_ctx, local_abspath, svn_depth_empty,
+  err = svn_wc_revert6(ctx->wc_ctx, local_abspath, svn_depth_empty,
                        FALSE, NULL, TRUE, FALSE,
+                       TRUE /*added_keep_local*/,
                        NULL, NULL, /* no cancellation */
                        ctx->notify_func2, ctx->notify_baton2,
                        scratch_pool);
@@ -8708,8 +8712,9 @@ resolve_incoming_move_dir_merge(svn_clie
       svn_opt_revision_t incoming_new_opt_rev;
 
       /* Revert the incoming move target directory. */
-      SVN_ERR(svn_wc_revert5(ctx->wc_ctx, moved_to_abspath, svn_depth_infinity,
+      SVN_ERR(svn_wc_revert6(ctx->wc_ctx, moved_to_abspath, svn_depth_infinity,
                              FALSE, NULL, TRUE, FALSE,
+                             TRUE /*added_keep_local*/,
                              NULL, NULL, /* no cancellation */
                              ctx->notify_func2, ctx->notify_baton2,
                              scratch_pool));
@@ -9672,11 +9677,13 @@ configure_option_incoming_delete_ignore(
       incoming_details = conflict->tree_conflict_incoming_details;
       is_incoming_move = (incoming_details != NULL &&
                           incoming_details->moves != NULL);
-      if (local_change == svn_wc_conflict_reason_edited && is_incoming_move)
+      if (local_change == svn_wc_conflict_reason_moved_away ||
+          local_change == svn_wc_conflict_reason_edited)
         {
           /* An option which ignores the incoming deletion makes no sense
-           * if we know it is actually a move. */
-          return SVN_NO_ERROR;
+           * if we know there was a local move and/or an incoming move. */
+          if (is_incoming_move)
+            return SVN_NO_ERROR;
         }
       else if (local_change == svn_wc_conflict_reason_deleted)
         {
@@ -9737,14 +9744,17 @@ configure_option_incoming_delete_accept(
   if (incoming_change == svn_wc_conflict_action_delete)
     {
       struct conflict_tree_incoming_delete_details *incoming_details;
+      svn_boolean_t is_incoming_move;
 
       incoming_details = conflict->tree_conflict_incoming_details;
-
-      if (local_change == svn_wc_conflict_reason_edited &&
-          incoming_details != NULL && incoming_details->moves != NULL)
+      is_incoming_move = (incoming_details != NULL &&
+                          incoming_details->moves != NULL);
+      if (is_incoming_move &&
+          (local_change == svn_wc_conflict_reason_edited ||
+          local_change == svn_wc_conflict_reason_moved_away))
         {
           /* An option which accepts the incoming deletion makes no sense
-           * if we know it is actually a move. */
+           * if we know there was a local move and/or an incoming move. */
           return SVN_NO_ERROR;
         }
       else
@@ -9892,6 +9902,7 @@ configure_option_incoming_dir_merge(svn_
 {
   svn_node_kind_t victim_node_kind;
   svn_wc_conflict_action_t incoming_change;
+  svn_wc_conflict_reason_t local_change;
   const char *incoming_old_repos_relpath;
   svn_revnum_t incoming_old_pegrev;
   svn_node_kind_t incoming_old_kind;
@@ -9900,6 +9911,7 @@ configure_option_incoming_dir_merge(svn_
   svn_node_kind_t incoming_new_kind;
 
   incoming_change = svn_client_conflict_get_incoming_change(conflict);
+  local_change = svn_client_conflict_get_local_change(conflict);
   victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
   SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
             &incoming_old_repos_relpath, &incoming_old_pegrev,
@@ -9913,7 +9925,8 @@ configure_option_incoming_dir_merge(svn_
   if (victim_node_kind == svn_node_dir &&
       incoming_old_kind == svn_node_dir &&
       incoming_new_kind == svn_node_none &&
-      incoming_change == svn_wc_conflict_action_delete)
+      incoming_change == svn_wc_conflict_action_delete &&
+      local_change == svn_wc_conflict_reason_edited)
     {
       struct conflict_tree_incoming_delete_details *details;
       const char *description;

Modified: subversion/branches/shelve-checkpoint/subversion/libsvn_client/diff.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/diff.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/diff.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/diff.c Mon 
Apr 16 12:21:02 2018
@@ -66,6 +66,26 @@
                           _("Path '%s' must be an immediate child of " \
                             "the directory '%s'"), path, relative_to_dir)
 
+/* State provided by the diff drivers; used by the diff writer */
+typedef struct diff_driver_info_t
+{
+  /* The anchor to prefix before wc paths */
+  const char *anchor;
+
+   /* Relative path of ra session from repos_root_url */
+  const char *session_relpath;
+
+  svn_wc_context_t *wc_ctx;
+
+  /* The original targets passed to the diff command.  We may need
+     these to construct distinctive diff labels when comparing the
+     same relative path in the same revision, under different anchors
+     (for example, when comparing a trunk against a branch). */
+  const char *orig_path_1;
+  const char *orig_path_2;
+} diff_driver_info_t;
+
+
 /* Calculate the repository relative path of DIFF_RELPATH, using
  * SESSION_RELPATH and WC_CTX, and return the result in *REPOS_RELPATH.
  * ORIG_TARGET is the related original target passed to the diff command,
@@ -383,28 +403,33 @@ maybe_print_mode_change(svn_stream_t *os
 }
 
 /* Print a git diff header showing the OPERATION to the stream OS using
- * HEADER_ENCODING. Return suitable diff labels for the git diff in *LABEL1
- * and *LABEL2. REPOS_RELPATH1 and REPOS_RELPATH2 are relative to reposroot.
- * are the paths passed to the original diff command. REV1 and REV2 are
- * revisions being diffed. COPYFROM_PATH and COPYFROM_REV indicate where the
+ * HEADER_ENCODING.
+ *
+ * Return suitable diff labels for the git diff in *LABEL1 and *LABEL2.
+ *
+ * REV1 and REV2 are the revisions being diffed.
+ * COPYFROM_PATH and COPYFROM_REV indicate where the
  * diffed item was copied from.
  * Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
 print_git_diff_header(svn_stream_t *os,
                       const char **label1, const char **label2,
                       svn_diff_operation_kind_t operation,
-                      const char *repos_relpath1,
-                      const char *repos_relpath2,
                       svn_revnum_t rev1,
                       svn_revnum_t rev2,
+                      const char *diff_relpath,
                       const char *copyfrom_path,
                       svn_revnum_t copyfrom_rev,
                       apr_hash_t *left_props,
                       apr_hash_t *right_props,
                       const char *git_index_shas,
                       const char *header_encoding,
+                      const diff_driver_info_t *ddi,
                       apr_pool_t *scratch_pool)
 {
+  const char *repos_relpath1;
+  const char *repos_relpath2;
+  const char *copyfrom_repos_relpath = NULL;
   svn_boolean_t exec_bit1 = (svn_prop_get_value(left_props,
                                                 SVN_PROP_EXECUTABLE) != NULL);
   svn_boolean_t exec_bit2 = (svn_prop_get_value(right_props,
@@ -414,6 +439,26 @@ print_git_diff_header(svn_stream_t *os,
   svn_boolean_t symlink_bit2 = (svn_prop_get_value(right_props,
                                                    SVN_PROP_SPECIAL) != NULL);
 
+  SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath,
+                             ddi->orig_path_1,
+                             ddi->session_relpath,
+                             ddi->wc_ctx,
+                             ddi->anchor,
+                             scratch_pool, scratch_pool));
+  SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath,
+                             ddi->orig_path_2,
+                             ddi->session_relpath,
+                             ddi->wc_ctx,
+                             ddi->anchor,
+                             scratch_pool, scratch_pool));
+  if (copyfrom_path)
+    SVN_ERR(make_repos_relpath(&copyfrom_repos_relpath, copyfrom_path,
+                               ddi->orig_path_2,
+                               ddi->session_relpath,
+                               ddi->wc_ctx,
+                               ddi->anchor,
+                               scratch_pool, scratch_pool));
+
   if (operation == svn_diff_op_deleted)
     {
       SVN_ERR(print_git_diff_header_deleted(os, header_encoding,
@@ -494,24 +539,20 @@ print_git_diff_header(svn_stream_t *os,
    ### FIXME needs proper docstring
 
    If USE_GIT_DIFF_FORMAT is TRUE, pring git diff headers, which always
-   show paths relative to the repository root. RA_SESSION and WC_CTX are
-   needed to normalize paths relative the repository root, and are ignored
-   if USE_GIT_DIFF_FORMAT is FALSE.
+   show paths relative to the repository root. DDI->session_relpath and
+   DDI->wc_ctx are needed to normalize paths relative the repository root,
+   and are ignored if USE_GIT_DIFF_FORMAT is FALSE.
 
    If @a pretty_print_mergeinfo is true, then describe 'svn:mergeinfo'
    property changes in a human-readable form that says what changes were
    merged or reverse merged; otherwise (or if the mergeinfo property values
    don't parse correctly) display them just like any other property.
-
-   ANCHOR is the local path where the diff editor is anchored. */
+ */
 static svn_error_t *
 display_prop_diffs(const apr_array_header_t *propchanges,
                    apr_hash_t *left_props,
                    apr_hash_t *right_props,
                    const char *diff_relpath,
-                   const char *anchor,
-                   const char *orig_path1,
-                   const char *orig_path2,
                    svn_revnum_t rev1,
                    svn_revnum_t rev2,
                    const char *encoding,
@@ -520,32 +561,27 @@ display_prop_diffs(const apr_array_heade
                    svn_boolean_t show_diff_header,
                    svn_boolean_t use_git_diff_format,
                    svn_boolean_t pretty_print_mergeinfo,
-                   const char *ra_session_relpath,
+                   const diff_driver_info_t *ddi,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
-                   svn_wc_context_t *wc_ctx,
                    apr_pool_t *scratch_pool)
 {
   const char *repos_relpath1 = NULL;
-  const char *repos_relpath2 = NULL;
   const char *index_path = diff_relpath;
-  const char *adjusted_path1 = orig_path1;
-  const char *adjusted_path2 = orig_path2;
+  const char *adjusted_path1 = ddi->orig_path_1;
+  const char *adjusted_path2 = ddi->orig_path_2;
 
   if (use_git_diff_format)
     {
-      SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath, orig_path1,
-                                 ra_session_relpath, wc_ctx, anchor,
-                                 scratch_pool, scratch_pool));
-      SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath, orig_path2,
-                                 ra_session_relpath, wc_ctx, anchor,
+      SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath, 
ddi->orig_path_1,
+                                 ddi->session_relpath, ddi->wc_ctx, 
ddi->anchor,
                                  scratch_pool, scratch_pool));
     }
 
   /* If we're creating a diff on the wc root, path would be empty. */
   SVN_ERR(adjust_paths_for_diff_labels(&index_path, &adjusted_path1,
                                        &adjusted_path2,
-                                       relative_to_dir, anchor,
+                                       relative_to_dir, ddi->anchor,
                                        scratch_pool, scratch_pool));
 
   if (show_diff_header)
@@ -567,13 +603,12 @@ display_prop_diffs(const apr_array_heade
       if (use_git_diff_format)
         SVN_ERR(print_git_diff_header(outstream, &label1, &label2,
                                       svn_diff_op_modified,
-                                      repos_relpath1, repos_relpath2,
-                                      rev1, rev2, NULL,
-                                      SVN_INVALID_REVNUM,
-                                      left_props,
-                                      right_props,
+                                      rev1, rev2,
+                                      diff_relpath,
+                                      NULL, SVN_INVALID_REVNUM,
+                                      left_props, right_props,
                                       NULL,
-                                      encoding, scratch_pool));
+                                      encoding, ddi, scratch_pool));
 
       /* --- label1
        * +++ label2 */
@@ -605,24 +640,6 @@ display_prop_diffs(const apr_array_heade
 
 /*** Callbacks for 'svn diff', invoked by the repos-diff editor. ***/
 
-/* State provided by the diff drivers; used by the diff writer */
-typedef struct diff_driver_info_t
-{
-  /* The anchor to prefix before wc paths */
-  const char *anchor;
-
-   /* Relative path of ra session from repos_root_url */
-  const char *session_relpath;
-
-  /* The original targets passed to the diff command.  We may need
-     these to construct distinctive diff labels when comparing the
-     same relative path in the same revision, under different anchors
-     (for example, when comparing a trunk against a branch). */
-  const char *orig_path_1;
-  const char *orig_path_2;
-} diff_driver_info_t;
-
-
 /* Diff writer state */
 typedef struct diff_writer_info_t
 {
@@ -680,8 +697,6 @@ typedef struct diff_writer_info_t
   /* Empty files for creating diffs or NULL if not used yet */
   const char *empty_file;
 
-  svn_wc_context_t *wc_ctx;
-
   svn_cancel_func_t cancel_func;
   void *cancel_baton;
 
@@ -717,9 +732,6 @@ diff_props_changed(const char *diff_relp
        * dir_props_changed(). */
       SVN_ERR(display_prop_diffs(props, left_props, right_props,
                                  diff_relpath,
-                                 dwi->ddi.anchor,
-                                 dwi->ddi.orig_path_1,
-                                 dwi->ddi.orig_path_2,
                                  rev1,
                                  rev2,
                                  dwi->header_encoding,
@@ -728,10 +740,9 @@ diff_props_changed(const char *diff_relp
                                  show_diff_header,
                                  dwi->use_git_diff_format,
                                  dwi->pretty_print_mergeinfo,
-                                 dwi->ddi.session_relpath,
+                                 &dwi->ddi,
                                  dwi->cancel_func,
                                  dwi->cancel_baton,
-                                 dwi->wc_ctx,
                                  scratch_pool));
     }
 
@@ -795,9 +806,12 @@ transform_link_to_git(const char **new_t
 }
 
 /* Show differences between TMPFILE1 and TMPFILE2. DIFF_RELPATH, REV1, and
-   REV2 are used in the headers to indicate the file and revisions.  If either
-   MIMETYPE1 or MIMETYPE2 indicate binary content, don't show a diff,
-   but instead print a warning message.
+   REV2 are used in the headers to indicate the file and revisions.
+
+   If either side has an svn:mime-type property that indicates 'binary'
+   content, then if DWI->force_binary is set, attempt to produce the
+   diff in the usual way, otherwise produce a 'GIT binary diff' in git mode
+   or print a warning message in non-git mode.
 
    If FORCE_DIFF is TRUE, always write a diff, even for empty diffs.
 
@@ -893,40 +907,17 @@ diff_content_changed(svn_boolean_t *wrot
         {
           svn_stream_t *left_stream;
           svn_stream_t *right_stream;
-          const char *repos_relpath1;
-          const char *repos_relpath2;
-          const char *copyfrom_repos_relpath = NULL;
-
-          SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath,
-                                      dwi->ddi.orig_path_1,
-                                      dwi->ddi.session_relpath,
-                                      dwi->wc_ctx,
-                                      dwi->ddi.anchor,
-                                      scratch_pool, scratch_pool));
-          SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath,
-                                      dwi->ddi.orig_path_2,
-                                      dwi->ddi.session_relpath,
-                                      dwi->wc_ctx,
-                                      dwi->ddi.anchor,
-                                      scratch_pool, scratch_pool));
-          if (copyfrom_path)
-            SVN_ERR(make_repos_relpath(&copyfrom_repos_relpath, copyfrom_path,
-                                        dwi->ddi.orig_path_2,
-                                        dwi->ddi.session_relpath,
-                                        dwi->wc_ctx,
-                                        dwi->ddi.anchor,
-                                        scratch_pool, scratch_pool));
-          SVN_ERR(print_git_diff_header(outstream, &label1, &label2,
+
+          SVN_ERR(print_git_diff_header(outstream,
+                                        &label1, &label2,
                                         operation,
-                                        repos_relpath1, repos_relpath2,
                                         rev1, rev2,
-                                        copyfrom_repos_relpath,
-                                        copyfrom_rev,
-                                        left_props,
-                                        right_props,
+                                        diff_relpath,
+                                        copyfrom_path, copyfrom_rev,
+                                        left_props, right_props,
                                         index_shas,
                                         dwi->header_encoding,
-                                        scratch_pool));
+                                        &dwi->ddi, scratch_pool));
 
           SVN_ERR(svn_stream_open_readonly(&left_stream, tmpfile1,
                                            scratch_pool, scratch_pool));
@@ -1066,41 +1057,16 @@ diff_content_changed(svn_boolean_t *wrot
 
           if (dwi->use_git_diff_format)
             {
-              const char *repos_relpath1;
-              const char *repos_relpath2;
-              const char *copyfrom_repos_relpath = NULL;
-
-              SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath,
-                                         dwi->ddi.orig_path_1,
-                                         dwi->ddi.session_relpath,
-                                         dwi->wc_ctx,
-                                         dwi->ddi.anchor,
-                                         scratch_pool, scratch_pool));
-              SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath,
-                                         dwi->ddi.orig_path_2,
-                                         dwi->ddi.session_relpath,
-                                         dwi->wc_ctx,
-                                         dwi->ddi.anchor,
-                                         scratch_pool, scratch_pool));
-              if (copyfrom_path)
-                SVN_ERR(make_repos_relpath(&copyfrom_repos_relpath,
-                                           copyfrom_path,
-                                           dwi->ddi.orig_path_2,
-                                           dwi->ddi.session_relpath,
-                                           dwi->wc_ctx,
-                                           dwi->ddi.anchor,
-                                           scratch_pool, scratch_pool));
-              SVN_ERR(print_git_diff_header(outstream, &label1, &label2,
+              SVN_ERR(print_git_diff_header(outstream,
+                                            &label1, &label2,
                                             operation,
-                                            repos_relpath1, repos_relpath2,
                                             rev1, rev2,
-                                            copyfrom_repos_relpath,
-                                            copyfrom_rev,
-                                            left_props,
-                                            right_props,
+                                            diff_relpath,
+                                            copyfrom_path, copyfrom_rev,
+                                            left_props, right_props,
                                             index_shas,
                                             dwi->header_encoding,
-                                            scratch_pool));
+                                            &dwi->ddi, scratch_pool));
             }
 
           /* Output the actual diff */
@@ -1547,11 +1513,22 @@ check_diff_target_exists(const char *url
 
 /** Prepare a repos repos diff between PATH_OR_URL1 and
  * PATH_OR_URL2@PEG_REVISION, in the revision range REVISION1:REVISION2.
- * Return URLs and peg revisions in *URL1, *REV1 and in *URL2, *REV2.
- * Return suitable anchors in *ANCHOR1 and *ANCHOR2, and targets in
- * *TARGET1 and *TARGET2, based on *URL1 and *URL2.
- * Indicate the corresponding node kinds in *KIND1 and *KIND2, and verify
+ *
+ * Return the resolved URL and peg revision pairs in *URL1, *REV1 and in
+ * *URL2, *REV2.
+ *
+ * Return suitable anchor URL and target pairs in *ANCHOR1, *TARGET1 and
+ * in *ANCHOR2, *TARGET2, corresponding to *URL1 and *URL2.
+ *
+ * (The choice of anchor URLs here appears to be: start with *URL1, *URL2;
+ * then take the parent dir on both sides, unless either of *URL1 or *URL2
+ * is the repository root or the parent dir of *URL1 is unreadable.)
+ *
+ * Set *KIND1 and *KIND2 to the node kinds of *URL1 and *URL2, and verify
  * that at least one of the diff targets exists.
+ *
+ * Set *RA_SESSION to an RA session parented at the URL *ANCHOR1.
+ *
  * Use client context CTX. Do all allocations in POOL. */
 static svn_error_t *
 diff_prepare_repos_repos(const char **url1,
@@ -1823,6 +1800,16 @@ unsupported_diff_error(svn_error_t *chil
    PATH1 and PATH2 are both working copy paths.  REVISION1 and
    REVISION2 are their respective revisions.
 
+   For now, require PATH1=PATH2, REVISION1='base', REVISION2='working',
+   otherwise return an error.
+
+   Set *ROOT_RELPATH to "" if PATH1 is a WC root, else to basename(PATH1).
+   Set *ROOT_IS_DIR to TRUE if the working version of PATH1 is
+   a directory, else to FALSE.
+
+   If DDI is non-null: Set DDI->anchor to the parent of PATH1 if the working
+   version of PATH1 is a dir, else to PATH1; set DDI->orig_path* to PATH*.
+
    All other options are the same as those passed to svn_client_diff7(). */
 static svn_error_t *
 diff_wc_wc(const char **root_relpath,
@@ -1870,6 +1857,9 @@ diff_wc_wc(const char **root_relpath,
         ddi->anchor = svn_dirent_dirname(path1, scratch_pool);
       else
         ddi->anchor = path1;
+
+      ddi->orig_path_1 = path1;
+      ddi->orig_path_2 = path2;
     }
 
   SVN_ERR(svn_wc__diff7(root_relpath, root_is_dir,
@@ -1889,6 +1879,20 @@ diff_wc_wc(const char **root_relpath,
    and the actual two paths compared are determined by following copy
    history from PATH_OR_URL2.
 
+   If DDI is non-null: Set DDI->orig_path_* to the two diff target URLs as
+   resolved at the given revisions; set DDI->anchor to an anchor WC path
+   if either of PATH_OR_URL* is given as a WC path, else to null; set
+   DDI->session_relpath to the repository-relpath of the anchor URL for
+   DDI->orig_path_1.
+
+   (The choice of WC anchor implementated here for DDI->anchor appears to
+   be: choose PATH_OR_URL2 (if it's a WC path) or else PATH_OR_URL1 (if
+   it's a WC path); then take its parent dir unless both resolved URLs
+   refer to directories.)
+
+   (For the choice of URL anchor for DDI->session_relpath, see
+   diff_prepare_repos_repos().)
+
    All other options are the same as those passed to svn_client_diff7(). */
 static svn_error_t *
 diff_repos_repos(const char **root_relpath,
@@ -2059,6 +2063,11 @@ diff_repos_repos(const char **root_relpa
 
    If REVERSE is TRUE, the diff will be reported in reverse.
 
+   If DDI is non-null: Set DDI->orig_path_* to the URLs of the two diff
+   targets as resolved at the given revisions; set DDI->anchor to a WC path
+   anchor for PATH2; set DDI->session_relpath to the repository-relpath of
+   the URL of that same anchor WC path.
+
    All other options are the same as those passed to svn_client_diff7(). */
 static svn_error_t *
 diff_repos_wc(const char **root_relpath,
@@ -2405,7 +2414,12 @@ do_diff(const char **root_relpath,
               SVN_ERR(svn_dirent_get_absolute(&abspath2, path_or_url2,
                                               scratch_pool));
 
-              /* ### What about ddi? */
+              if (ddi)
+                {
+                  ddi->orig_path_1 = path_or_url1;
+                  ddi->orig_path_2 = path_or_url2;
+                }
+
               /* Ignores changelists, ignore_ancestry */
               SVN_ERR(svn_client__arbitrary_nodes_diff(root_relpath, 
root_is_dir,
                                                        abspath1, abspath2,
@@ -2493,6 +2507,72 @@ create_diff_writer_info(diff_writer_info
   return SVN_NO_ERROR;
 }
 
+/* Set up *DIFF_PROCESSOR and *DDI for normal and git-style diffs (but not
+ * summary diffs).
+ */
+static svn_error_t *
+get_diff_processor(svn_diff_tree_processor_t **diff_processor,
+                   struct diff_driver_info_t **ddi,
+                   const apr_array_header_t *options,
+                   const char *relative_to_dir,
+                   svn_boolean_t no_diff_added,
+                   svn_boolean_t no_diff_deleted,
+                   svn_boolean_t show_copies_as_adds,
+                   svn_boolean_t ignore_content_type,
+                   svn_boolean_t ignore_properties,
+                   svn_boolean_t properties_only,
+                   svn_boolean_t use_git_diff_format,
+                   svn_boolean_t pretty_print_mergeinfo,
+                   const char *header_encoding,
+                   svn_stream_t *outstream,
+                   svn_stream_t *errstream,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
+{
+  diff_writer_info_t *dwi = apr_pcalloc(pool, sizeof(*dwi));
+  svn_diff_tree_processor_t *processor;
+
+  /* setup callback and baton */
+
+  SVN_ERR(create_diff_writer_info(dwi, options,
+                                  ctx->config, pool));
+  dwi->pool = pool;
+  dwi->outstream = outstream;
+  dwi->errstream = errstream;
+  dwi->header_encoding = header_encoding;
+
+  dwi->force_binary = ignore_content_type;
+  dwi->ignore_properties = ignore_properties;
+  dwi->properties_only = properties_only;
+  dwi->relative_to_dir = relative_to_dir;
+  dwi->use_git_diff_format = use_git_diff_format;
+  dwi->no_diff_added = no_diff_added;
+  dwi->no_diff_deleted = no_diff_deleted;
+  dwi->show_copies_as_adds = show_copies_as_adds;
+  dwi->pretty_print_mergeinfo = pretty_print_mergeinfo;
+
+  dwi->cancel_func = ctx->cancel_func;
+  dwi->cancel_baton = ctx->cancel_baton;
+
+  dwi->ddi.wc_ctx = ctx->wc_ctx;
+  dwi->ddi.session_relpath = NULL;
+  dwi->ddi.anchor = NULL;
+
+  processor = svn_diff__tree_processor_create(dwi, pool);
+
+  processor->dir_added = diff_dir_added;
+  processor->dir_changed = diff_dir_changed;
+  processor->dir_deleted = diff_dir_deleted;
+
+  processor->file_added = diff_file_added;
+  processor->file_changed = diff_file_changed;
+  processor->file_deleted = diff_file_deleted;
+
+  *diff_processor = processor;
+  *ddi = &dwi->ddi;
+  return SVN_NO_ERROR;
+}
+
 /*----------------------------------------------------------------------- */
 
 /*** Public Interfaces. ***/
@@ -2553,10 +2633,9 @@ svn_client_diff7(const apr_array_header_
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
 {
-  diff_writer_info_t dwi = { 0 };
   svn_opt_revision_t peg_revision;
-  const svn_diff_tree_processor_t *diff_processor;
-  svn_diff_tree_processor_t *processor;
+  svn_diff_tree_processor_t *diff_processor;
+  struct diff_driver_info_t *ddi;
 
   if (ignore_properties && properties_only)
     return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
@@ -2566,51 +2645,26 @@ svn_client_diff7(const apr_array_header_
   /* We will never do a pegged diff from here. */
   peg_revision.kind = svn_opt_revision_unspecified;
 
-  /* setup callback and baton */
-  dwi.ddi.orig_path_1 = path_or_url1;
-  dwi.ddi.orig_path_2 = path_or_url2;
-
-  SVN_ERR(create_diff_writer_info(&dwi, options,
-                                  ctx->config, pool));
-  dwi.pool = pool;
-  dwi.outstream = outstream;
-  dwi.errstream = errstream;
-  dwi.header_encoding = header_encoding;
-
-  dwi.force_binary = ignore_content_type;
-  dwi.ignore_properties = ignore_properties;
-  dwi.properties_only = properties_only;
-  dwi.relative_to_dir = relative_to_dir;
-  dwi.use_git_diff_format = use_git_diff_format;
-  dwi.no_diff_added = no_diff_added;
-  dwi.no_diff_deleted = no_diff_deleted;
-  dwi.show_copies_as_adds = show_copies_as_adds;
-  dwi.pretty_print_mergeinfo = pretty_print_mergeinfo;
-
-  dwi.cancel_func = ctx->cancel_func;
-  dwi.cancel_baton = ctx->cancel_baton;
-
-  dwi.wc_ctx = ctx->wc_ctx;
-  dwi.ddi.session_relpath = NULL;
-  dwi.ddi.anchor = NULL;
-
-  processor = svn_diff__tree_processor_create(&dwi, pool);
-
-  processor->dir_added = diff_dir_added;
-  processor->dir_changed = diff_dir_changed;
-  processor->dir_deleted = diff_dir_deleted;
-
-  processor->file_added = diff_file_added;
-  processor->file_changed = diff_file_changed;
-  processor->file_deleted = diff_file_deleted;
-
-  diff_processor = processor;
-
   /* --show-copies-as-adds and --git imply --notice-ancestry */
   if (show_copies_as_adds || use_git_diff_format)
     ignore_ancestry = FALSE;
 
-  return svn_error_trace(do_diff(NULL, NULL, &dwi.ddi,
+  SVN_ERR(get_diff_processor(&diff_processor, &ddi,
+                             options,
+                             relative_to_dir,
+                             no_diff_added,
+                             no_diff_deleted,
+                             show_copies_as_adds,
+                             ignore_content_type,
+                             ignore_properties,
+                             properties_only,
+                             use_git_diff_format,
+                             pretty_print_mergeinfo,
+                             header_encoding,
+                             outstream, errstream,
+                             ctx, pool));
+
+  return svn_error_trace(do_diff(NULL, NULL, ddi,
                                  path_or_url1, path_or_url2,
                                  revision1, revision2,
                                  &peg_revision, TRUE /* no_peg_revision */,
@@ -2643,60 +2697,34 @@ svn_client_diff_peg7(const apr_array_hea
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
 {
-  diff_writer_info_t dwi = { 0 };
-  const svn_diff_tree_processor_t *diff_processor;
-  svn_diff_tree_processor_t *processor;
+  svn_diff_tree_processor_t *diff_processor;
+  struct diff_driver_info_t *ddi;
 
   if (ignore_properties && properties_only)
     return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                             _("Cannot ignore properties and show only "
                               "properties at the same time"));
 
-  /* setup callback and baton */
-  dwi.ddi.orig_path_1 = path_or_url;
-  dwi.ddi.orig_path_2 = path_or_url;
-
-  SVN_ERR(create_diff_writer_info(&dwi, options,
-                                  ctx->config, pool));
-  dwi.pool = pool;
-  dwi.outstream = outstream;
-  dwi.errstream = errstream;
-  dwi.header_encoding = header_encoding;
-
-  dwi.force_binary = ignore_content_type;
-  dwi.ignore_properties = ignore_properties;
-  dwi.properties_only = properties_only;
-  dwi.relative_to_dir = relative_to_dir;
-  dwi.use_git_diff_format = use_git_diff_format;
-  dwi.no_diff_added = no_diff_added;
-  dwi.no_diff_deleted = no_diff_deleted;
-  dwi.show_copies_as_adds = show_copies_as_adds;
-  dwi.pretty_print_mergeinfo = pretty_print_mergeinfo;
-
-  dwi.cancel_func = ctx->cancel_func;
-  dwi.cancel_baton = ctx->cancel_baton;
-
-  dwi.wc_ctx = ctx->wc_ctx;
-  dwi.ddi.session_relpath = NULL;
-  dwi.ddi.anchor = NULL;
-
-  processor = svn_diff__tree_processor_create(&dwi, pool);
-
-  processor->dir_added = diff_dir_added;
-  processor->dir_changed = diff_dir_changed;
-  processor->dir_deleted = diff_dir_deleted;
-
-  processor->file_added = diff_file_added;
-  processor->file_changed = diff_file_changed;
-  processor->file_deleted = diff_file_deleted;
-
-  diff_processor = processor;
-
   /* --show-copies-as-adds and --git imply --notice-ancestry */
   if (show_copies_as_adds || use_git_diff_format)
     ignore_ancestry = FALSE;
 
-  return svn_error_trace(do_diff(NULL, NULL, &dwi.ddi,
+  SVN_ERR(get_diff_processor(&diff_processor, &ddi,
+                             options,
+                             relative_to_dir,
+                             no_diff_added,
+                             no_diff_deleted,
+                             show_copies_as_adds,
+                             ignore_content_type,
+                             ignore_properties,
+                             properties_only,
+                             use_git_diff_format,
+                             pretty_print_mergeinfo,
+                             header_encoding,
+                             outstream, errstream,
+                             ctx, pool));
+
+  return svn_error_trace(do_diff(NULL, NULL, ddi,
                                  path_or_url, path_or_url,
                                  start_revision, end_revision,
                                  peg_revision, FALSE /* no_peg_revision */,

Modified: 
subversion/branches/shelve-checkpoint/subversion/libsvn_client/export.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/export.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/export.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/export.c Mon 
Apr 16 12:21:02 2018
@@ -453,12 +453,12 @@ export_node(void *baton,
  * If PATH exists but is a file, then error with SVN_ERR_WC_NOT_WORKING_COPY.
  *
  * If PATH is a already a directory, then error with
- * SVN_ERR_WC_OBSTRUCTED_UPDATE, unless FORCE, in which case just
+ * SVN_ERR_WC_OBSTRUCTED_UPDATE, unless OVERWRITE, in which case just
  * export into PATH with no error.
  */
 static svn_error_t *
 open_root_internal(const char *path,
-                   svn_boolean_t force,
+                   svn_boolean_t overwrite,
                    svn_wc_notify_func2_t notify_func,
                    void *notify_baton,
                    apr_pool_t *pool)
@@ -472,7 +472,7 @@ open_root_internal(const char *path,
     return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
                              _("'%s' exists and is not a directory"),
                              svn_dirent_local_style(path, pool));
-  else if ((kind != svn_node_dir) || (! force))
+  else if ((kind != svn_node_dir) || (! overwrite))
     return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
                              _("'%s' already exists"),
                              svn_dirent_local_style(path, pool));
@@ -501,7 +501,7 @@ struct edit_baton
   const char *repos_root_url;
   const char *root_path;
   const char *root_url;
-  svn_boolean_t force;
+  svn_boolean_t overwrite;
   svn_revnum_t *target_revision;
   apr_hash_t *externals;
   const char *native_eol;
@@ -587,7 +587,7 @@ open_root(void *edit_baton,
   struct edit_baton *eb = edit_baton;
   struct dir_baton *db = apr_pcalloc(pool, sizeof(*db));
 
-  SVN_ERR(open_root_internal(eb->root_path, eb->force,
+  SVN_ERR(open_root_internal(eb->root_path, eb->overwrite,
                              eb->notify_func, eb->notify_baton, pool));
 
   /* Build our dir baton. */
@@ -621,7 +621,7 @@ add_directory(const char *path,
     return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
                              _("'%s' exists and is not a directory"),
                              svn_dirent_local_style(full_path, pool));
-  else if (! (kind == svn_node_dir && eb->force))
+  else if (! (kind == svn_node_dir && eb->overwrite))
     return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
                              _("'%s' already exists"),
                              svn_dirent_local_style(full_path, pool));
@@ -1077,7 +1077,7 @@ add_directory_ev2(void *baton,
     return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
                              _("'%s' exists and is not a directory"),
                              svn_dirent_local_style(full_path, scratch_pool));
-  else if (! (kind == svn_node_dir && eb->force))
+  else if (! (kind == svn_node_dir && eb->overwrite))
     return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
                              _("'%s' already exists"),
                              svn_dirent_local_style(full_path, scratch_pool));
@@ -1141,7 +1141,7 @@ get_editor_ev2(const svn_delta_editor_t
                                        exb, result_pool));
 
   /* Create the root of the export. */
-  SVN_ERR(open_root_internal(eb->root_path, eb->force, eb->notify_func,
+  SVN_ERR(open_root_internal(eb->root_path, eb->overwrite, eb->notify_func,
                              eb->notify_baton, scratch_pool));
 
   return SVN_NO_ERROR;
@@ -1153,7 +1153,6 @@ export_file_ev2(const char *from_url,
                 struct edit_baton *eb,
                 svn_client__pathrev_t *loc,
                 svn_ra_session_t *ra_session,
-                svn_boolean_t overwrite,
                 apr_pool_t *scratch_pool)
 {
   apr_hash_t *props;
@@ -1177,7 +1176,7 @@ export_file_ev2(const char *from_url,
   SVN_ERR(svn_io_check_path(to_path, &to_kind, scratch_pool));
 
   if ((to_kind == svn_node_file || to_kind == svn_node_unknown) &&
-      ! overwrite)
+      ! eb->overwrite)
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                              _("Destination file '%s' exists, and "
                                "will not be overwritten unless forced"),
@@ -1207,7 +1206,6 @@ export_file(const char *from_url,
             struct edit_baton *eb,
             svn_client__pathrev_t *loc,
             svn_ra_session_t *ra_session,
-            svn_boolean_t overwrite,
             apr_pool_t *scratch_pool)
 {
   apr_hash_t *props;
@@ -1232,7 +1230,7 @@ export_file(const char *from_url,
   SVN_ERR(svn_io_check_path(to_path, &to_kind, scratch_pool));
 
   if ((to_kind == svn_node_file || to_kind == svn_node_unknown) &&
-      ! overwrite)
+      ! eb->overwrite)
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                              _("Destination file '%s' exists, and "
                                "will not be overwritten unless forced"),
@@ -1289,7 +1287,6 @@ export_directory(const char *from_url,
                  struct edit_baton *eb,
                  svn_client__pathrev_t *loc,
                  svn_ra_session_t *ra_session,
-                 svn_boolean_t overwrite,
                  svn_boolean_t ignore_externals,
                  svn_boolean_t ignore_keywords,
                  svn_depth_t depth,
@@ -1344,7 +1341,7 @@ export_directory(const char *from_url,
   SVN_ERR(svn_io_check_path(to_path, &kind, scratch_pool));
   if (kind == svn_node_none)
     SVN_ERR(open_root_internal
-            (to_path, overwrite, ctx->notify_func2,
+            (to_path, eb->overwrite, ctx->notify_func2,
              ctx->notify_baton2, scratch_pool));
 
   if (! ignore_externals && depth == svn_depth_infinity)
@@ -1415,7 +1412,7 @@ svn_client_export5(svn_revnum_t *result_
       SVN_ERR(svn_ra_get_repos_root2(ra_session, &eb->repos_root_url, pool));
       eb->root_path = to_path;
       eb->root_url = loc->url;
-      eb->force = overwrite;
+      eb->overwrite = overwrite;
       eb->target_revision = &edit_revision;
       eb->externals = apr_hash_make(pool);
       eb->native_eol = native_eol;
@@ -1431,15 +1428,15 @@ svn_client_export5(svn_revnum_t *result_
         {
           if (!ENABLE_EV2_IMPL)
             SVN_ERR(export_file(from_url, to_path, eb, loc, ra_session,
-                                overwrite, pool));
+                                pool));
           else
             SVN_ERR(export_file_ev2(from_url, to_path, eb, loc,
-                                    ra_session, overwrite, pool));
+                                    ra_session, pool));
         }
       else if (kind == svn_node_dir)
         {
           SVN_ERR(export_directory(from_url, to_path,
-                                   eb, loc, ra_session, overwrite,
+                                   eb, loc, ra_session,
                                    ignore_externals, ignore_keywords, depth,
                                    native_eol, ctx, pool));
         }

Modified: subversion/branches/shelve-checkpoint/subversion/libsvn_client/info.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/info.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/info.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/info.c Mon 
Apr 16 12:21:02 2018
@@ -253,17 +253,17 @@ same_resource_in_head(svn_boolean_t *sam
                       apr_pool_t *pool)
 {
   svn_error_t *err;
-  svn_opt_revision_t start_rev, peg_rev;
+  svn_opt_revision_t operative_rev, peg_rev;
   const char *head_url;
 
-  start_rev.kind = svn_opt_revision_head;
-  peg_rev.kind = svn_opt_revision_number;
-  peg_rev.value.number = rev;
+  peg_rev.kind = svn_opt_revision_head;
+  operative_rev.kind = svn_opt_revision_number;
+  operative_rev.value.number = rev;
 
   err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
                                     ra_session,
                                     url, &peg_rev,
-                                    &start_rev, NULL,
+                                    &operative_rev, NULL,
                                     ctx, pool);
   if (err &&
       ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||

Modified: subversion/branches/shelve-checkpoint/subversion/libsvn_client/patch.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/patch.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/patch.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/patch.c Mon 
Apr 16 12:21:02 2018
@@ -343,7 +343,9 @@ strip_path(const char **result, const ch
   components = svn_path_decompose(path, scratch_pool);
   if (strip_count > components->nelts)
     return svn_error_createf(SVN_ERR_CLIENT_PATCH_BAD_STRIP_COUNT, NULL,
-                             _("Cannot strip %u components from '%s'"),
+                             Q_("Cannot strip %u component from '%s'",
+                                "Cannot strip %u components from '%s'",
+                                strip_count),
                              strip_count,
                              svn_dirent_local_style(path, scratch_pool));
 

Modified: subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelf.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelf.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelf.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelf.c Mon 
Apr 16 12:21:02 2018
@@ -59,7 +59,7 @@ shelf_name_encode(char **encoded_name_p,
 
   while (*name)
     {
-      apr_snprintf(out_pos, 3, "%02x", *name++);
+      apr_snprintf(out_pos, 3, "%02x", (unsigned char)(*name++));
       out_pos += 2;
     }
   *encoded_name_p = encoded_name;
@@ -187,7 +187,9 @@ get_log_abspath(char **log_abspath,
   return SVN_NO_ERROR;
 }
 
-/* Set SHELF->revprops by reading from its file storage.
+/* Set SHELF->revprops by reading from its storage (the '.log' file).
+ * Set SHELF->revprops to empty if the storage file does not exist; this
+ * is not an error.
  */
 static svn_error_t *
 shelf_read_revprops(svn_client_shelf_t *shelf,
@@ -237,10 +239,10 @@ shelf_write_revprops(svn_client_shelf_t
 }
 
 svn_error_t *
-svn_client__shelf_revprop_set(svn_client_shelf_t *shelf,
-                              const char *prop_name,
-                              const svn_string_t *prop_val,
-                              apr_pool_t *scratch_pool)
+svn_client_shelf_revprop_set(svn_client_shelf_t *shelf,
+                             const char *prop_name,
+                             const svn_string_t *prop_val,
+                             apr_pool_t *scratch_pool)
 {
   svn_hash_sets(shelf->revprops, apr_pstrdup(shelf->pool, prop_name),
                 svn_string_dup(prop_val, shelf->pool));
@@ -249,19 +251,32 @@ svn_client__shelf_revprop_set(svn_client
 }
 
 svn_error_t *
-svn_client__shelf_revprop_get(svn_string_t **prop_val,
-                              svn_client_shelf_t *shelf,
-                              const char *prop_name,
-                              apr_pool_t *result_pool)
+svn_client_shelf_revprop_set_all(svn_client_shelf_t *shelf,
+                                 apr_hash_t *revprop_table,
+                                 apr_pool_t *scratch_pool)
+{
+  if (revprop_table)
+    shelf->revprops = svn_prop_hash_dup(revprop_table, shelf->pool);
+  else
+    shelf->revprops = apr_hash_make(shelf->pool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_shelf_revprop_get(svn_string_t **prop_val,
+                             svn_client_shelf_t *shelf,
+                             const char *prop_name,
+                             apr_pool_t *result_pool)
 {
   *prop_val = svn_hash_gets(shelf->revprops, prop_name);
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_client__shelf_revprop_list(apr_hash_t **props,
-                               svn_client_shelf_t *shelf,
-                               apr_pool_t *result_pool)
+svn_client_shelf_revprop_list(apr_hash_t **props,
+                              svn_client_shelf_t *shelf,
+                              apr_pool_t *result_pool)
 {
   *props = shelf->revprops;
   return SVN_NO_ERROR;
@@ -282,7 +297,9 @@ get_current_abspath(char **current_abspa
   return SVN_NO_ERROR;
 }
 
-/*  */
+/* Read SHELF->max_version from its storage (the '.current' file).
+ * Set SHELF->max_version to -1 if that file does not exist.
+ */
 static svn_error_t *
 shelf_read_current(svn_client_shelf_t *shelf,
                    apr_pool_t *scratch_pool)
@@ -294,7 +311,7 @@ shelf_read_current(svn_client_shelf_t *s
   fp = fopen(current_abspath, "r");
   if (! fp)
     {
-      shelf->max_version = 0;
+      shelf->max_version = -1;
       return SVN_NO_ERROR;
     }
   fscanf(fp, "%d", &shelf->max_version);
@@ -436,7 +453,7 @@ svn_client_shelf_open_existing(svn_clien
                           local_abspath, ctx, result_pool));
   SVN_ERR(shelf_read_revprops(*shelf_p, result_pool));
   SVN_ERR(shelf_read_current(*shelf_p, result_pool));
-  if ((*shelf_p)->max_version <= 0)
+  if ((*shelf_p)->max_version < 0)
     {
       return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                                _("Shelf '%s' not found"),
@@ -446,16 +463,24 @@ svn_client_shelf_open_existing(svn_clien
 }
 
 svn_error_t *
-svn_client_shelf_open(svn_client_shelf_t **shelf_p,
-                      const char *name,
-                      const char *local_abspath,
-                      svn_client_ctx_t *ctx,
-                      apr_pool_t *result_pool)
+svn_client_shelf_open_or_create(svn_client_shelf_t **shelf_p,
+                                const char *name,
+                                const char *local_abspath,
+                                svn_client_ctx_t *ctx,
+                                apr_pool_t *result_pool)
 {
-  SVN_ERR(shelf_construct(shelf_p, name,
+  svn_client_shelf_t *shelf;
+
+  SVN_ERR(shelf_construct(&shelf, name,
                           local_abspath, ctx, result_pool));
-  SVN_ERR(shelf_read_revprops(*shelf_p, result_pool));
-  SVN_ERR(shelf_read_current(*shelf_p, result_pool));
+  SVN_ERR(shelf_read_revprops(shelf, result_pool));
+  SVN_ERR(shelf_read_current(shelf, result_pool));
+  if (shelf->max_version < 0)
+    {
+      shelf->max_version = 0;
+      SVN_ERR(shelf_write_current(shelf, result_pool));
+    }
+  *shelf_p = shelf;
   return SVN_NO_ERROR;
 }
 
@@ -567,6 +592,82 @@ svn_client_shelf_paths_changed(apr_hash_
   return SVN_NO_ERROR;
 }
 
+/* A filter to only apply the patch to a particular file. */
+struct patch_filter_baton_t
+{
+  /* The single path to be selected for patching */
+  const char *path;
+};
+
+static svn_error_t *
+patch_filter(void *baton,
+             svn_boolean_t *filtered,
+             const char *canon_path_from_patchfile,
+             const char *patch_abspath,
+             const char *reject_abspath,
+             apr_pool_t *scratch_pool)
+{
+  struct patch_filter_baton_t *fb = baton;
+
+  *filtered = (strcmp(canon_path_from_patchfile, fb->path) != 0);
+  return SVN_NO_ERROR;
+}
+
+/* Intercept patch notifications to detect when there is a conflict */
+struct patch_notify_baton_t
+{
+  svn_boolean_t conflict;
+};
+
+/* 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 *nb = baton;
+
+  if (notify->action == svn_wc_notify_patch_rejected_hunk
+      || notify->action == svn_wc_notify_skip)
+    nb->conflict = TRUE;
+}
+
+svn_error_t *
+svn_client_shelf_test_apply_file(svn_boolean_t *conflict_p,
+                                 svn_client_shelf_version_t *shelf_version,
+                                 const char *file_relpath,
+                                 apr_pool_t *scratch_pool)
+{
+  svn_client_ctx_t *ctx = shelf_version->shelf->ctx;
+  svn_wc_notify_func2_t ctx_notify_func;
+  void *ctx_notify_baton;
+  struct patch_filter_baton_t fb;
+  struct patch_notify_baton_t nb;
+
+  fb.path = file_relpath;
+
+  nb.conflict = FALSE;
+  ctx_notify_func = ctx->notify_func2;
+  ctx_notify_baton = ctx->notify_baton2;
+  ctx->notify_func2 = patch_notify;
+  ctx->notify_baton2 = &nb;
+
+  SVN_ERR(svn_client_patch(shelf_version->patch_abspath,
+                           shelf_version->shelf->wc_root_abspath,
+                           TRUE /*dry_run*/, 0 /*strip*/,
+                           FALSE /*reverse*/,
+                           FALSE /*ignore_whitespace*/,
+                           TRUE /*remove_tempfiles*/,
+                           patch_filter, &fb,
+                           shelf_version->shelf->ctx, scratch_pool));
+
+  ctx->notify_func2 = ctx_notify_func;
+  ctx->notify_baton2 = ctx_notify_baton;
+
+  *conflict_p = nb.conflict;
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_shelf_apply(svn_client_shelf_version_t *shelf_version,
                        svn_boolean_t dry_run,
@@ -607,32 +708,38 @@ svn_client_shelf_unapply(svn_client_shel
 
 svn_error_t *
 svn_client_shelf_set_current_version(svn_client_shelf_t *shelf,
-                                     int version,
+                                     int version_number,
                                      apr_pool_t *scratch_pool)
 {
+  svn_client_shelf_version_t *shelf_version;
+
+  SVN_ERR(svn_client_shelf_version_open(&shelf_version, shelf, version_number,
+                                        scratch_pool, scratch_pool));
+  SVN_ERR(svn_client_shelf_delete_newer_versions(shelf, shelf_version,
+                                                 scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_shelf_delete_newer_versions(svn_client_shelf_t *shelf,
+                                       svn_client_shelf_version_t 
*shelf_version,
+                                       apr_pool_t *scratch_pool)
+{
+  int previous_version = shelf_version ? shelf_version->version_number : 0;
   int i;
 
   /* Delete any newer checkpoints */
-  for (i = shelf->max_version; i > version; i--)
+  for (i = shelf->max_version; i > previous_version; i--)
     {
       SVN_ERR(shelf_delete_patch_file(shelf, i, scratch_pool));
     }
 
-  shelf->max_version = version;
+  shelf->max_version = previous_version;
   SVN_ERR(shelf_write_current(shelf, scratch_pool));
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_client_shelf_get_patch_abspath(const char **patch_abspath,
-                                   svn_client_shelf_version_t *shelf_version,
-                                   apr_pool_t *scratch_pool)
-{
-  *patch_abspath = shelf_version->patch_abspath;
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_client_shelf_export_patch(svn_client_shelf_version_t *shelf_version,
                               svn_stream_t *outstream,
                               apr_pool_t *scratch_pool)
@@ -648,11 +755,12 @@ svn_client_shelf_export_patch(svn_client
 }
 
 svn_error_t *
-svn_client_shelf_save_new_version(svn_client_shelf_t *shelf,
-                                  const apr_array_header_t *paths,
-                                  svn_depth_t depth,
-                                  const apr_array_header_t *changelists,
-                                  apr_pool_t *scratch_pool)
+svn_client_shelf_save_new_version2(svn_client_shelf_version_t **new_version_p,
+                                   svn_client_shelf_t *shelf,
+                                   const apr_array_header_t *paths,
+                                   svn_depth_t depth,
+                                   const apr_array_header_t *changelists,
+                                   apr_pool_t *scratch_pool)
 {
   int next_version = shelf->max_version + 1;
   const char *patch_abspath;
@@ -668,18 +776,40 @@ svn_client_shelf_save_new_version(svn_cl
   SVN_ERR(svn_io_stat(&file_info, patch_abspath, APR_FINFO_MTIME, 
scratch_pool));
   if (file_info.size > 0)
     {
-      SVN_ERR(svn_client_shelf_set_current_version(shelf, next_version,
-                                                   scratch_pool));
+      shelf->max_version = next_version;
+      SVN_ERR(shelf_write_current(shelf, scratch_pool));
+
+      if (new_version_p)
+        SVN_ERR(svn_client_shelf_version_open(new_version_p, shelf, 
next_version,
+                                              scratch_pool, scratch_pool));
+    }
+  else
+    {
+      if (new_version_p)
+        *new_version_p = NULL;
     }
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
+svn_client_shelf_save_new_version(svn_client_shelf_t *shelf,
+                                  const apr_array_header_t *paths,
+                                  svn_depth_t depth,
+                                  const apr_array_header_t *changelists,
+                                  apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_client_shelf_save_new_version2(NULL, shelf,
+                                             paths, depth, changelists,
+                                             scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_client_shelf_get_log_message(char **log_message,
                                  svn_client_shelf_t *shelf,
                                  apr_pool_t *result_pool)
 {
-  svn_string_t *propval = svn_hash_gets(shelf->revprops, "svn:log");
+  svn_string_t *propval = svn_hash_gets(shelf->revprops, 
SVN_PROP_REVISION_LOG);
 
   if (propval)
     *log_message = apr_pstrdup(result_pool, propval->data);
@@ -690,39 +820,14 @@ svn_client_shelf_get_log_message(char **
 
 svn_error_t *
 svn_client_shelf_set_log_message(svn_client_shelf_t *shelf,
-                                 apr_hash_t *revprop_table,
-                                 svn_boolean_t dry_run,
+                                 const char *message,
                                  apr_pool_t *scratch_pool)
 {
-  svn_client_ctx_t *ctx = shelf->ctx;
-  const char *message = "";
-
-  /* Fetch the log message and any other revprops */
-  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
-    {
-      const char *tmp_file;
-      apr_array_header_t *commit_items
-        = apr_array_make(scratch_pool, 1, sizeof(void *));
-
-      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,
-                                      ctx, scratch_pool));
-      if (! message)
-        return SVN_NO_ERROR;
-    }
-
-  if (revprop_table)
-    shelf->revprops = svn_prop_hash_dup(revprop_table, shelf->pool);
-  else
-    shelf->revprops = apr_hash_make(shelf->pool);
-
-  if (message && !dry_run)
-    {
-      svn_string_t *propval = svn_string_create(message, shelf->pool);
-
-      SVN_ERR(svn_client__shelf_revprop_set(shelf, "svn:log", propval,
-                                            scratch_pool));
-    }
+  svn_string_t *propval
+    = message ? svn_string_create(message, shelf->pool) : NULL;
 
+  SVN_ERR(svn_client_shelf_revprop_set(shelf, SVN_PROP_REVISION_LOG, propval,
+                                       scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -771,7 +876,7 @@ svn_client_shelf_list(apr_hash_t **shelf
 svn_error_t *
 svn_client_shelf_version_open(svn_client_shelf_version_t **shelf_version_p,
                               svn_client_shelf_t *shelf,
-                              int version,
+                              int version_number,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
 {
@@ -781,7 +886,7 @@ svn_client_shelf_version_open(svn_client
 
   shelf_version->shelf = shelf;
   SVN_ERR(get_existing_patch_abspath(&shelf_version->patch_abspath,
-                                     shelf, version,
+                                     shelf, version_number,
                                      result_pool, scratch_pool));
   SVN_ERR(svn_io_stat_dirent2(&dirent,
                               shelf_version->patch_abspath,
@@ -789,6 +894,48 @@ svn_client_shelf_version_open(svn_client
                               TRUE /*ignore_enoent*/,
                               result_pool, scratch_pool));
   shelf_version->mtime = dirent->mtime;
+  shelf_version->version_number = version_number;
   *shelf_version_p = shelf_version;
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_client_shelf_get_newest_version(svn_client_shelf_version_t 
**shelf_version_p,
+                                    svn_client_shelf_t *shelf,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool)
+{
+  if (shelf->max_version == 0)
+    {
+      *shelf_version_p = NULL;
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(svn_client_shelf_version_open(shelf_version_p,
+                                        shelf, shelf->max_version,
+                                        result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_shelf_get_all_versions(apr_array_header_t **versions_p,
+                                  svn_client_shelf_t *shelf,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  int i;
+
+  *versions_p = apr_array_make(result_pool, shelf->max_version - 1,
+                               sizeof(svn_client_shelf_version_t *));
+
+  for (i = 1; i <= shelf->max_version; i++)
+    {
+      svn_client_shelf_version_t *shelf_version;
+
+      SVN_ERR(svn_client_shelf_version_open(&shelf_version,
+                                            shelf, i,
+                                            result_pool, scratch_pool));
+      APR_ARRAY_PUSH(*versions_p, svn_client_shelf_version_t *) = 
shelf_version;
+    }
+  return SVN_NO_ERROR;
+}

Modified: 
subversion/branches/shelve-checkpoint/subversion/libsvn_client/update.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/update.c?rev=1829257&r1=1829256&r2=1829257&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/update.c 
(original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/update.c Mon 
Apr 16 12:21:02 2018
@@ -567,7 +567,7 @@ svn_client__update_internal(svn_revnum_t
 {
   const char *anchor_abspath, *lockroot_abspath;
   svn_error_t *err;
-  svn_opt_revision_t peg_revision = *revision;
+  svn_opt_revision_t opt_rev = *revision;  /* operative revision */
   apr_hash_t *conflicted_paths
     = ctx->conflict_func2 ? apr_hash_make(pool) : NULL;
 
@@ -620,7 +620,7 @@ svn_client__update_internal(svn_revnum_t
 
           err = update_internal(result_rev, timestamp_sleep, conflicted_paths,
                                 &ra_session, missing_parent,
-                                anchor_abspath, &peg_revision, svn_depth_empty,
+                                anchor_abspath, &opt_rev, svn_depth_empty,
                                 FALSE, ignore_externals,
                                 allow_unver_obstructions, adds_as_modification,
                                 FALSE, ctx, pool, iterpool);
@@ -631,8 +631,8 @@ svn_client__update_internal(svn_revnum_t
           /* If we successfully updated a missing parent, let's re-use
              the returned revision number for future updates for the
              sake of consistency. */
-          peg_revision.kind = svn_opt_revision_number;
-          peg_revision.value.number = *result_rev;
+          opt_rev.kind = svn_opt_revision_number;
+          opt_rev.value.number = *result_rev;
         }
 
       svn_pool_destroy(iterpool);
@@ -648,7 +648,7 @@ svn_client__update_internal(svn_revnum_t
   err = update_internal(result_rev, timestamp_sleep, conflicted_paths,
                         &ra_session,
                         local_abspath, anchor_abspath,
-                        &peg_revision, depth, depth_is_sticky,
+                        &opt_rev, depth, depth_is_sticky,
                         ignore_externals, allow_unver_obstructions,
                         adds_as_modification,
                         TRUE, ctx, pool, pool);


Reply via email to