You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/04/29 20:38:56 UTC

svn commit: r1741682 [3/26] - in /subversion/branches/authzperf: ./ build/ build/ac-macros/ build/generator/ contrib/server-side/svncutter/ notes/ notes/api-errata/1.9/ notes/move-tracking/ subversion/ subversion/bindings/ctypes-python/ subversion/bind...

Modified: subversion/branches/authzperf/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_io.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_io.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_io.h Fri Apr 29 18:38:53 2016
@@ -1147,16 +1147,27 @@ svn_error_t *
 svn_stream_for_stdout(svn_stream_t **out,
                       apr_pool_t *pool);
 
-/** Set @a *str to a string buffer allocated in @a result_pool that contains
- * all data from the current position in @a stream to its end.  @a len_hint
- * specifies the initial capacity of the string buffer and may be 0.  The
- * buffer gets automatically resized to fit the actual amount of data being
- * read from @a stream.
+/** Read the contents of @a stream into memory, from its current position
+ * to its end, returning the data in @a *result. This function does not
+ * close the @a stream upon completion.
+ *
+ * @a len_hint gives a hint about the expected length, in bytes, of the
+ * actual data that will be read from the stream. It may be 0, meaning no
+ * hint is being provided. Efficiency in time and/or in space may be
+ * better (and in general will not be worse) when the actual data length
+ * is equal or approximately equal to the length hint.
+ *
+ * The returned memory is allocated in @a result_pool.
+ *
+ * @note The present implementation is efficient when @a len_hint is big
+ * enough (but not vastly bigger than necessary), and also for actual
+ * lengths up to 64 bytes when @a len_hint is 0. Otherwise it can incur
+ * significant time and space overheads. See source code for details.
  *
  * @since New in 1.9.
  */
 svn_error_t *
-svn_stringbuf_from_stream(svn_stringbuf_t **str,
+svn_stringbuf_from_stream(svn_stringbuf_t **result,
                           svn_stream_t *stream,
                           apr_size_t len_hint,
                           apr_pool_t *result_pool);
@@ -1520,25 +1531,44 @@ svn_stream_contents_same(svn_boolean_t *
                          apr_pool_t *pool);
 
 
-/** Read the contents of @a stream into memory, returning the data in
- * @a result. The stream will be closed when it has been successfully and
- * completely read.
+/** Read the contents of @a stream into memory, from its current position
+ * to its end, returning the data in @a *result. The stream will be closed
+ * when it has been successfully and completely read.
+ *
+ * @a len_hint gives a hint about the expected length, in bytes, of the
+ * actual data that will be read from the stream. It may be 0, meaning no
+ * hint is being provided. Efficiency in time and/or in space may be
+ * better (and in general will not be worse) when the actual data length
+ * is equal or approximately equal to the length hint.
  *
  * The returned memory is allocated in @a result_pool, and any temporary
- * allocations are performed in @a scratch_pool.
+ * allocations may be performed in @a scratch_pool.
  *
- * @note due to memory pseudo-reallocation behavior (due to pools), this
- *   can be a memory-intensive operation for large files.
+ * @note The present implementation is efficient when @a len_hint is big
+ * enough (but not vastly bigger than necessary), and also for actual
+ * lengths up to 64 bytes when @a len_hint is 0. Otherwise it can incur
+ * significant time and space overheads. See source code for details.
  *
- * @since New in 1.6
+ * @since New in 1.10
  */
 svn_error_t *
+svn_string_from_stream2(svn_string_t **result,
+                        svn_stream_t *stream,
+                        apr_size_t len_hint,
+                        apr_pool_t *result_pool);
+
+/** Similar to svn_string_from_stream2(), but always passes 0 for
+ * @a len_hint.
+ *
+ * @deprecated Provided for backwards compatibility with the 1.9 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_string_from_stream(svn_string_t **result,
                        svn_stream_t *stream,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool);
 
-
 /** A function type provided for use as a callback from
  * @c svn_stream_lazyopen_create().
  *
@@ -2205,6 +2235,16 @@ svn_error_t *
 svn_io_file_size_get(svn_filesize_t *filesize_p, apr_file_t *file,
                      apr_pool_t *pool);
 
+/** Fetch the current offset of @a file into @a *offset_p. Use @a pool for
+  * temporary allocations.
+  *
+  * @since New in 1.10
+  */
+svn_error_t *
+svn_io_file_get_offset(apr_off_t *offset_p,
+                       apr_file_t *file,
+                       apr_pool_t *pool);
+
 /** Wrapper for apr_file_read(). */
 svn_error_t *
 svn_io_file_read(apr_file_t *file,

Modified: subversion/branches/authzperf/subversion/include/svn_props.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_props.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_props.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_props.h Fri Apr 29 18:38:53 2016
@@ -475,22 +475,42 @@ svn_prop_name_is_valid(const char *prop_
 /** The files' last modification time.
  * This is stored as string in the form @c "2008-08-07T07:38:51.008782Z", to
  * be converted by the functions @c svn_time_to_cstring() and
- * @c svn_time_from_cstring(). */
+ * @c svn_time_from_cstring().
+ *
+ * @note This property name is reserved for future usage, but currently unused.
+ *
+ * @since New in 1.6.
+ */
 #define SVN_PROP_TEXT_TIME  SVN_PROP_PREFIX "text-time"
 
 /** The files' owner.
  * Stored as numeric ID, optionally followed by whitespace and the string:
  * @c "1000 pmarek". Parsers @b should accept any number of whitespace,
- * and writers @b should put exactly a single space. */
+ * and writers @b should put exactly a single space.
+ *
+ * @note This property name is reserved for future usage, but currently unused.
+ *
+ * @since New in 1.6.
+ */
 #define SVN_PROP_OWNER SVN_PROP_PREFIX "owner"
 
 /** The files' group.
- * The same format as for @c SVN_PROP_OWNER, the owner-property. */
+ * The same format as for @c SVN_PROP_OWNER, the owner-property.
+ *
+ * @note This property name is reserved for future usage, but currently unused.
+ *
+ * @since New in 1.6.
+ */
 #define SVN_PROP_GROUP  SVN_PROP_PREFIX "group"
 
 /** The files' unix-mode.
  * Stored in octal, with a leading @c 0; may have 5 digits if any of @c setuid,
- * @c setgid or @c sticky are set; an example is @c "0644". */
+ * @c setgid or @c sticky are set; an example is @c "0644".
+ *
+ * @note This property name is reserved for future usage, but currently unused.
+ *
+ * @since New in 1.6.
+ */
 #define SVN_PROP_UNIX_MODE  SVN_PROP_PREFIX "unix-mode"
 
 /** @} */ /* Meta-data properties */

Modified: subversion/branches/authzperf/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_ra.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_ra.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_ra.h Fri Apr 29 18:38:53 2016
@@ -1089,7 +1089,7 @@ svn_ra_get_file(svn_ra_session_t *sessio
  * @a path is interpreted relative to the URL in @a session.
  *
  * If @a revision is @c SVN_INVALID_REVNUM (meaning 'head') and
- * @a *fetched_rev is not @c NULL, then this function will set
+ * @a fetched_rev is not @c NULL, then this function will set
  * @a *fetched_rev to the actual revision that was retrieved.  (Some
  * callers want to know, and some don't.)
  *

Modified: subversion/branches/authzperf/subversion/include/svn_ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_ra_svn.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_ra_svn.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_ra_svn.h Fri Apr 29 18:38:53 2016
@@ -189,13 +189,38 @@ typedef svn_error_t *(*svn_ra_svn_edit_c
  * It defines the number of bytes that must have been sent since the last
  * check before the next check will be made.
  *
+ * If @a max_in is not 0, error out and close the connection whenever more
+ * than @a max_in bytes are received for a command (e.g. a client request).
+ * If @a max_out is not 0, error out and close the connection whenever more
+ * than @a max_out bytes have been send as response to some command.
+ *
+ * @note The limits enforced may vary slightly by +/- the I/O buffer size. 
+ *
  * @note If @a out_stream is an wrapped apr_file_t* the backing file will be
  * used for some operations.
  *
  * Allocate the result in @a pool.
  *
+ * @since New in 1.10
+ */
+svn_ra_svn_conn_t *svn_ra_svn_create_conn5(apr_socket_t *sock,
+                                           svn_stream_t *in_stream,
+                                           svn_stream_t *out_stream,
+                                           int compression_level,
+                                           apr_size_t zero_copy_limit,
+                                           apr_size_t error_check_interval,
+                                           apr_uint64_t max_in,
+                                           apr_uint64_t max_out,
+                                           apr_pool_t *result_pool);
+
+
+/** Similar to svn_ra_svn_create_conn5() but with @a max_in and @a max_out
+ * set to 0.
+ *
  * @since New in 1.9
+ * @deprecated Provided for backward compatibility with the 1.9 API.
  */
+SVN_DEPRECATED
 svn_ra_svn_conn_t *svn_ra_svn_create_conn4(apr_socket_t *sock,
                                            svn_stream_t *in_stream,
                                            svn_stream_t *out_stream,

Modified: subversion/branches/authzperf/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_repos.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_repos.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_repos.h Fri Apr 29 18:38:53 2016
@@ -1870,6 +1870,198 @@ svn_repos_node_location_segments(svn_rep
 
 /* Retrieving log messages. */
 
+/** Path change descriptor.
+ *
+ * @note Identical to #svn_fs_path_change3_t but with all information
+ *       known, i.e. @a node_kind is never #svn_node_unknown and
+ *       @a copyfrom_known is always @c TRUE.
+ *
+ * @see svn_fs_path_change3_t
+ *
+ * @since New in 1.10.
+ */
+typedef svn_fs_path_change3_t svn_repos_path_change_t;
+
+/** The callback invoked by log message loopers, such as
+ * svn_repos_get_logs5().
+ *
+ * This function is invoked once on each changed path, in a potentially
+ * random order that may even change between invocations for the same
+ * revisions.
+ *
+ * @a baton is what you think it is, and @a change contains relevant
+ * information for the changed path.  Please note that @a change may be
+ * modified within this callback but it will become invalid as soon as
+ * the callback returns.
+ *
+ * Use @a scratch_pool for temporary allocation.  The caller may clear it
+ * between or after invocations.
+ *
+ * @since New in 1.10.
+ */
+typedef svn_error_t *(*svn_repos_path_change_receiver_t)(
+  void *baton,
+  svn_repos_path_change_t *change,
+  apr_pool_t *scratch_pool);
+
+
+/**
+ * A structure to represent all the information about a particular log entry.
+ *
+ * @since New in 1.10.
+ */
+typedef struct svn_repos_log_entry_t
+{
+  /** The revision of the commit. */
+  svn_revnum_t revision;
+
+  /** The hash of requested revision properties, which may be NULL if it
+   * would contain no revprops.  Maps (const char *) property name to
+   * (svn_string_t *) property value. */
+  apr_hash_t *revprops;
+
+  /**
+   * Whether or not this message has children.
+   *
+   * When a log operation requests additional merge information, extra log
+   * entries may be returned as a result of this entry.  The new entries, are
+   * considered children of the original entry, and will follow it.  When
+   * the HAS_CHILDREN flag is set, the receiver should increment its stack
+   * depth, and wait until an entry is provided with SVN_INVALID_REVNUM which
+   * indicates the end of the children.
+   *
+   * For log operations which do not request additional merge information, the
+   * HAS_CHILDREN flag is always FALSE.
+   *
+   * For more information see:
+   * https://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/design.html#commutative-reporting
+   */
+  svn_boolean_t has_children;
+
+  /**
+   * Whether @a revision should be interpreted as non-inheritable in the
+   * same sense of #svn_merge_range_t.
+   *
+   * Currently always FALSE.
+   */
+  svn_boolean_t non_inheritable;
+
+  /**
+   * Whether @a revision is a merged revision resulting from a reverse merge.
+   */
+  svn_boolean_t subtractive_merge;
+
+  /* NOTE: Add new fields at the end to preserve binary compatibility. */
+} svn_repos_log_entry_t;
+
+
+/** The callback invoked by log message loopers, such as
+ * svn_repos_get_logs5().
+ *
+ * This function is invoked once on each log message, in the order
+ * determined by the caller (see above-mentioned functions).
+ *
+ * @a baton is what you think it is, and @a log_entry contains relevant
+ * information for the log message.
+ *
+ * If @a log_entry->has_children is @c TRUE, the message will be followed
+ * immediately by any number of merged revisions (child messages), which are
+ * terminated by an invocation with SVN_INVALID_REVNUM.  This usage may
+ * be recursive.
+ *
+ * Use @a scratch_pool for temporary allocation.  The caller may clear it
+ * between or after invocations.
+ *
+ * @since New in 1.10.
+ */
+typedef svn_error_t *(*svn_repos_log_entry_receiver_t)(
+  void *baton,
+  svn_repos_log_entry_t *log_entry,
+  apr_pool_t *scratch_pool);
+
+
+/**
+ * Invoke @a revision_receiver with @a revision_receiver_baton on each
+ * revision from @a start to @a end in @a repos's filesystem.  @a start may
+ * be greater or less than @a end; this just controls whether the log is
+ * processed in descending or ascending revision number order.
+ *
+ * If not @c NULL, @a path_change_receiver will be invoked with
+ * @a path_change_receiver_baton for each changed path in the respective
+ * revision.  These changes will be reported before the @a revision_receiver
+ * is invoked for that revision.  So, for each revision in the log, there
+ * is a number of calls to @a path_change_receiver followed by a single
+ * invocation of @a revision_receiver, implicitly marking the end of the
+ * changes list for that revision.  If a revision does not contain any
+ * changes (or if none are visible due to @a authz_read_func),
+ * @a path_change_receiver will not be called for that revision.
+ *
+ * If @a start or @a end is #SVN_INVALID_REVNUM, it defaults to youngest.
+ *
+ * If @a paths is non-NULL and has one or more elements, then only show
+ * revisions in which at least one of @a paths was changed (i.e., if
+ * file, text or props changed; if dir, props or entries changed or any node
+ * changed below it).  Each path is a <tt>const char *</tt> representing
+ * an absolute path in the repository.  If @a paths is NULL or empty,
+ * show all revisions regardless of what paths were changed in those
+ * revisions.
+ *
+ * If @a limit is greater than zero then only invoke @a revision_receiver
+ * on the first @a limit logs.
+ *
+ * If @a strict_node_history is set, copy history (if any exists) will
+ * not be traversed while harvesting revision logs for each path.
+ *
+ * If @a include_merged_revisions is set, log information for revisions
+ * which have been merged to @a paths will also be returned, unless these
+ * revisions are already part of @a start to @a end in @a repos's
+ * filesystem, as limited by @a paths. In the latter case those revisions
+ * are skipped and @a receiver is not invoked.
+ *
+ * If @a revprops is NULL, retrieve all revision properties; else, retrieve
+ * only the revision properties named by the (const char *) array elements
+ * (i.e. retrieve none if the array is empty).
+ *
+ * If any invocation of @a revision_receiver or @a path_change_receiver
+ * returnn an error, return that error immediately and without wrapping it.
+ *
+ * If @a start or @a end is a non-existent revision, return the error
+ * #SVN_ERR_FS_NO_SUCH_REVISION, without ever invoking @a revision_receiver.
+ *
+ * If optional @a authz_read_func is non-NULL, then use this function
+ * (along with optional @a authz_read_baton) to check the readability
+ * of each changed-path in each revision about to be "pushed" at
+ * @a path_change_receiver.  If a revision has some changed-paths readable
+ * and others unreadable, unreadable paths are omitted from the
+ * @a path_change_receiver invocations and only svn:author and svn:date
+ * will be available in the revprops field in the @a revision_receiver
+ * callback.  If a revision has no changed-paths readable at all, then all
+ * paths are omitted and no revprops are available.  If
+ * @a path_change_receiver is @c NULL, the same filtering is performed
+ * just without reporting any path changes.
+ *
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @see svn_repos_path_change_receiver_t, svn_repos_log_entry_receiver_t
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_repos_get_logs5(svn_repos_t *repos,
+                    const apr_array_header_t *paths,
+                    svn_revnum_t start,
+                    svn_revnum_t end,
+                    int limit,
+                    svn_boolean_t strict_node_history,
+                    svn_boolean_t include_merged_revisions,
+                    const apr_array_header_t *revprops,
+                    svn_repos_authz_func_t authz_read_func,
+                    void *authz_read_baton,
+                    svn_repos_path_change_receiver_t path_change_receiver,
+                    void *path_change_receiver_baton,
+                    svn_repos_log_entry_receiver_t revision_receiver,
+                    void *revision_receiver_baton,
+                    apr_pool_t *scratch_pool);
 
 /**
  * Invoke @a receiver with @a receiver_baton on each log message from

Modified: subversion/branches/authzperf/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_wc.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_wc.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_wc.h Fri Apr 29 18:38:53 2016
@@ -998,7 +998,10 @@ typedef enum svn_wc_notify_action_t
   /** A revert operation has failed. */
   svn_wc_notify_failed_revert,
 
-  /** Resolving a conflict. */
+  /** All conflicts on a path were marked as resolved.
+   * @note As of 1.10, separate notifications are sent for individually
+   * resolved text, property, and tree conflicts. This notification is used
+   * only if all conflicts on a path were marked resolved at once. */
   svn_wc_notify_resolved,
 
   /** Skipping a path. */
@@ -1274,7 +1277,21 @@ typedef enum svn_wc_notify_action_t
 
   /** Finalizing commit.
    * @since New in 1.9. */
-  svn_wc_notify_commit_finalizing
+  svn_wc_notify_commit_finalizing,
+
+  /** All text conflicts in a file were marked as resolved.
+   * @since New in 1.10. */
+  svn_wc_notify_resolved_text,
+
+  /** A property conflict on a path was marked as resolved.
+   * The name of the property is specified in #svn_wc_notify_t.prop_name.
+   * @since New in 1.10. */
+  svn_wc_notify_resolved_prop,
+
+  /** A tree conflict on a path was marked as resolved.
+   * @since New in 1.10. */
+  svn_wc_notify_resolved_tree,
+
 } svn_wc_notify_action_t;
 
 
@@ -5054,7 +5071,11 @@ svn_wc_remove_from_revision_control(svn_
  * Temporary allocations will be performed in @a scratch_pool.
  *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.9 API.
+ * Use svn_client_conflict_text_resolve(), svn_client_conflict_prop_resolve(),
+ * and svn_client_conflict_tree_resolve() instead.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
                           const char *local_abspath,

Modified: subversion/branches/authzperf/subversion/include/svn_x509.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/svn_x509.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/svn_x509.h (original)
+++ subversion/branches/authzperf/subversion/include/svn_x509.h Fri Apr 29 18:38:53 2016
@@ -166,7 +166,7 @@ svn_x509_certinfo_get_valid_from(const s
  *
  * @since New in 1.9.
  */
-const apr_time_t
+apr_time_t
 svn_x509_certinfo_get_valid_to(const svn_x509_certinfo_t *certinfo);
 
 /**

Modified: subversion/branches/authzperf/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_client/client.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_client/client.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_client/client.h Fri Apr 29 18:38:53 2016
@@ -1185,6 +1185,88 @@ svn_client__remote_propget(apr_hash_t *p
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);
 
+/* */
+typedef struct merge_source_t
+{
+  /* "left" side URL and revision (inclusive iff youngest) */
+  const svn_client__pathrev_t *loc1;
+
+  /* "right" side URL and revision (inclusive iff youngest) */
+  const svn_client__pathrev_t *loc2;
+
+  /* True iff LOC1 is an ancestor of LOC2 or vice-versa (history-wise). */
+  svn_boolean_t ancestral;
+} merge_source_t;
+
+/* Description of the merge target root node (a WC working node) */
+typedef struct merge_target_t
+{
+  /* Absolute path to the WC node */
+  const char *abspath;
+
+  /* The repository location of the base node of the target WC.  If the node
+   * is locally added, then URL & REV are NULL & SVN_INVALID_REVNUM.
+   * REPOS_ROOT_URL and REPOS_UUID are always valid. */
+  svn_client__pathrev_t loc;
+
+} merge_target_t;
+
+/*
+ * Similar API to svn_client_merge_peg5().
+ */
+svn_error_t *
+svn_client__merge_elements(svn_boolean_t *use_sleep,
+                           apr_array_header_t *merge_sources,
+                           merge_target_t *target,
+                           svn_ra_session_t *ra_session,
+                           svn_boolean_t diff_ignore_ancestry,
+                           svn_boolean_t force_delete,
+                           svn_boolean_t dry_run,
+                           const apr_array_header_t *merge_options,
+                           svn_client_ctx_t *ctx,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
+
+/* Data for reporting when a merge aborted because of raising conflicts.
+ *
+ * ### TODO: More info, including the ranges (or other parameters) the user
+ *     needs to complete the merge.
+ */
+typedef struct svn_client__conflict_report_t
+{
+  const char *target_abspath;
+  /* The revision range during which conflicts were raised */
+  const merge_source_t *conflicted_range;
+  /* Was the conflicted range the last range in the whole requested merge? */
+  svn_boolean_t was_last_range;
+} svn_client__conflict_report_t;
+
+/* Create and return an error structure appropriate for the unmerged
+   revisions range(s). */
+svn_error_t *
+svn_client__make_merge_conflict_error(svn_client__conflict_report_t *report,
+                                      apr_pool_t *scratch_pool);
+
+/* The body of svn_client_merge5(), which see for details. */
+svn_error_t *
+svn_client__merge_locked(svn_client__conflict_report_t **conflict_report,
+                         const char *source1,
+                         const svn_opt_revision_t *revision1,
+                         const char *source2,
+                         const svn_opt_revision_t *revision2,
+                         const char *target_abspath,
+                         svn_depth_t depth,
+                         svn_boolean_t ignore_mergeinfo,
+                         svn_boolean_t diff_ignore_ancestry,
+                         svn_boolean_t force_delete,
+                         svn_boolean_t record_only,
+                         svn_boolean_t dry_run,
+                         svn_boolean_t allow_mixed_rev,
+                         const apr_array_header_t *merge_options,
+                         svn_client_ctx_t *ctx,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/authzperf/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_client/diff.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_client/diff.c Fri Apr 29 18:38:53 2016
@@ -359,6 +359,7 @@ maybe_print_mode_change(svn_stream_t *os
                         svn_boolean_t exec_bit2,
                         svn_boolean_t symlink_bit1,
                         svn_boolean_t symlink_bit2,
+                        const char *git_index_shas,
                         apr_pool_t *scratch_pool)
 {
   int old_mode = (exec_bit1 ? exec_mode : noexec_mode)
@@ -366,7 +367,13 @@ maybe_print_mode_change(svn_stream_t *os
   int new_mode = (exec_bit2 ? exec_mode : noexec_mode)
                  | (symlink_bit2 ? kind_symlink_mode : kind_file_mode);
   if (old_mode == new_mode)
-    return SVN_NO_ERROR;
+    {
+      if (git_index_shas)
+        SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
+                                            "index %s %06o" APR_EOL_STR,
+                                            git_index_shas, old_mode));
+      return SVN_NO_ERROR;
+    }
 
   SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
                                       "old mode %06o" APR_EOL_STR, old_mode));
@@ -394,6 +401,7 @@ print_git_diff_header(svn_stream_t *os,
                       svn_revnum_t copyfrom_rev,
                       apr_hash_t *left_props,
                       apr_hash_t *right_props,
+                      const char *git_index_shas,
                       const char *header_encoding,
                       apr_pool_t *scratch_pool)
 {
@@ -430,6 +438,7 @@ print_git_diff_header(svn_stream_t *os,
       SVN_ERR(maybe_print_mode_change(os, header_encoding,
                                       exec_bit1, exec_bit2,
                                       symlink_bit1, symlink_bit2,
+                                      git_index_shas,
                                       scratch_pool));
     }
   else if (operation == svn_diff_op_added)
@@ -454,6 +463,7 @@ print_git_diff_header(svn_stream_t *os,
       SVN_ERR(maybe_print_mode_change(os, header_encoding,
                                       exec_bit1, exec_bit2,
                                       symlink_bit1, symlink_bit2,
+                                      git_index_shas,
                                       scratch_pool));
     }
   else if (operation == svn_diff_op_moved)
@@ -468,6 +478,7 @@ print_git_diff_header(svn_stream_t *os,
       SVN_ERR(maybe_print_mode_change(os, header_encoding,
                                       exec_bit1, exec_bit2,
                                       symlink_bit1, symlink_bit2,
+                                      git_index_shas,
                                       scratch_pool));
     }
 
@@ -553,6 +564,7 @@ display_prop_diffs(const apr_array_heade
                                       SVN_INVALID_REVNUM,
                                       left_props,
                                       right_props,
+                                      NULL,
                                       encoding, scratch_pool));
 
       /* --- label1
@@ -714,11 +726,13 @@ diff_props_changed(const char *diff_relp
   return SVN_NO_ERROR;
 }
 
-/* Given a file TMPFILE, return a path to a temporary file that lives at least
-   as long as RESULT_POOL, containing the git-like represention of TMPFILE */
+/* Given a file ORIG_TMPFILE, return a path to a temporary file that lives at
+ * least as long as RESULT_POOL, containing the git-like represention of
+ * ORIG_TMPFILE */
 static svn_error_t *
 transform_link_to_git(const char **new_tmpfile,
-                      const char *tmpfile,
+                      const char **git_sha1,
+                      const char *orig_tmpfile,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
 {
@@ -726,7 +740,9 @@ transform_link_to_git(const char **new_t
   apr_file_t *gitlike;
   svn_stringbuf_t *line;
 
-  SVN_ERR(svn_io_file_open(&orig, tmpfile, APR_READ, APR_OS_DEFAULT,
+  *git_sha1 = NULL;
+
+  SVN_ERR(svn_io_file_open(&orig, orig_tmpfile, APR_READ, APR_OS_DEFAULT,
                            scratch_pool));
   SVN_ERR(svn_io_open_unique_file3(&gitlike, new_tmpfile, NULL,
                                    svn_io_file_del_on_pool_cleanup,
@@ -737,13 +753,28 @@ transform_link_to_git(const char **new_t
 
   if (line->len > 5 && !strncmp(line->data, "link ", 5))
     {
-      SVN_ERR(svn_io_file_write_full(gitlike, line->data + 5, line->len - 5,
+      const char *sz_str;
+      svn_checksum_t *checksum;
+
+      svn_stringbuf_remove(line, 0, 5);
+
+      SVN_ERR(svn_io_file_write_full(gitlike, line->data, line->len,
                                      NULL, scratch_pool));
+
+      /* git calculates the sha over "blob X\0" + the actual data,
+         where X is the decimal size of the blob. */
+      sz_str = apr_psprintf(scratch_pool, "blob %u", (unsigned int)line->len);
+      svn_stringbuf_insert(line, 0, sz_str, strlen(sz_str) + 1);
+
+      SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1,
+                           line->data, line->len, scratch_pool));
+
+      *git_sha1 = svn_checksum_to_cstring(checksum, result_pool);
     }
   else
     {
       /* Not a link... so can't convert */
-      *new_tmpfile = apr_pstrdup(result_pool, tmpfile);
+      *new_tmpfile = apr_pstrdup(result_pool, orig_tmpfile);
     }
 
   SVN_ERR(svn_io_file_close(orig, scratch_pool));
@@ -784,6 +815,7 @@ diff_content_changed(svn_boolean_t *wrot
   const char *path2 = dwi->ddi.orig_path_2;
   const char *mimetype1 = svn_prop_get_value(left_props, SVN_PROP_MIME_TYPE);
   const char *mimetype2 = svn_prop_get_value(right_props, SVN_PROP_MIME_TYPE);
+  const char *index_shas = NULL;
 
   /* If only property differences are shown, there's nothing to do. */
   if (dwi->properties_only)
@@ -807,13 +839,29 @@ diff_content_changed(svn_boolean_t *wrot
 
   if (dwi->use_git_diff_format)
     {
+      const char *l_hash = NULL;
+      const char *r_hash = NULL;
+
       /* Change symlinks to their 'git like' plain format */
       if (svn_prop_get_value(left_props, SVN_PROP_SPECIAL))
-        SVN_ERR(transform_link_to_git(&tmpfile1, tmpfile1,
+        SVN_ERR(transform_link_to_git(&tmpfile1, &l_hash, tmpfile1,
                                       scratch_pool, scratch_pool));
       if (svn_prop_get_value(right_props, SVN_PROP_SPECIAL))
-        SVN_ERR(transform_link_to_git(&tmpfile2, tmpfile2,
+        SVN_ERR(transform_link_to_git(&tmpfile2, &r_hash, tmpfile2,
                                       scratch_pool, scratch_pool));
+
+      if (l_hash && r_hash)
+        {
+          /* The symlink has changed. But we can't tell the user of the
+             diff whether we are writing git diffs or svn diffs of the
+             symlink... except when we add a git-like index line */
+
+          l_hash = apr_pstrndup(scratch_pool, l_hash, 8);
+          r_hash = apr_pstrndup(scratch_pool, r_hash, 8);
+
+          index_shas = apr_psprintf(scratch_pool, "%8s..%8s",
+                                    l_hash, r_hash);
+        }
     }
 
   if (! dwi->force_binary && (mt1_binary || mt2_binary))
@@ -856,6 +904,7 @@ diff_content_changed(svn_boolean_t *wrot
                                         copyfrom_rev,
                                         left_props,
                                         right_props,
+                                        index_shas,
                                         dwi->header_encoding,
                                         scratch_pool));
 
@@ -1019,6 +1068,7 @@ diff_content_changed(svn_boolean_t *wrot
                                             copyfrom_rev,
                                             left_props,
                                             right_props,
+                                            index_shas,
                                             dwi->header_encoding,
                                             scratch_pool));
             }
@@ -1039,10 +1089,6 @@ diff_content_changed(svn_boolean_t *wrot
         }
     }
 
-  /* ### todo: someday we'll need to worry about whether we're going
-     to need to write a diff plug-in mechanism that makes use of the
-     two paths, instead of just blindly running SVN_CLIENT_DIFF.  */
-
   return SVN_NO_ERROR;
 }
 
@@ -1152,9 +1198,13 @@ diff_file_added(const char *relpath,
                                  copyfrom_source->revision,
                                  right_source->revision,
                                  left_props, right_props,
-                                 svn_diff_op_copied,
+                                 copyfrom_source->moved_from_relpath
+                                    ? svn_diff_op_moved
+                                    : svn_diff_op_copied,
                                  TRUE /* force diff output */,
-                                 copyfrom_source->repos_relpath,
+                                 copyfrom_source->moved_from_relpath
+                                    ? copyfrom_source->moved_from_relpath
+                                    : copyfrom_source->repos_relpath,
                                  copyfrom_source->revision,
                                  dwi, scratch_pool));
   else if (right_file)
@@ -1968,11 +2018,15 @@ diff_repos_repos(const char **root_relpa
 /* Perform a diff between a repository path and a working-copy path.
 
    PATH_OR_URL1 may be either a URL or a working copy path.  PATH2 is a
-   working copy path.  REVISION1 and REVISION2 are their respective
-   revisions.  If REVERSE is TRUE, the diff will be done in reverse.
-   If PEG_REVISION is specified, then PATH_OR_URL1 is the path in the peg
-   revision, and the actual repository path to be compared is
-   determined by following copy history.
+   working copy path.  REVISION1 is the revision of URL1. If PEG_REVISION1
+   is specified, then PATH_OR_URL1 is the path in the peg revision, and the
+   actual repository path to be compared is determined by following copy
+   history.
+
+   REVISION_KIND2 specifies which revision should be reported from the
+   working copy (BASE or WORKING)
+
+   If REVERSE is TRUE, the diff will be reported in reverse.
 
    All other options are the same as those passed to svn_client_diff6(). */
 static svn_error_t *
@@ -1981,9 +2035,9 @@ diff_repos_wc(const char **root_relpath,
               struct diff_driver_info_t *ddi,
               const char *path_or_url1,
               const svn_opt_revision_t *revision1,
-              const svn_opt_revision_t *peg_revision,
+              const svn_opt_revision_t *peg_revision1,
               const char *path2,
-              const svn_opt_revision_t *revision2,
+              enum svn_opt_revision_kind revision2_kind,
               svn_boolean_t reverse,
               svn_depth_t depth,
               svn_boolean_t ignore_ancestry,
@@ -2000,7 +2054,7 @@ diff_repos_wc(const char **root_relpath,
   void *reporter_baton;
   const svn_delta_editor_t *diff_editor;
   void *diff_edit_baton;
-  svn_boolean_t rev2_is_base = (revision2->kind == svn_opt_revision_base);
+  svn_boolean_t rev2_is_base = (revision2_kind == svn_opt_revision_base);
   svn_boolean_t server_supports_depth;
   const char *abspath_or_url1;
   const char *abspath2;
@@ -2040,10 +2094,10 @@ diff_repos_wc(const char **root_relpath,
 
   SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc1,
                                             path_or_url1, abspath2,
-                                            peg_revision, revision1,
+                                            peg_revision1, revision1,
                                             ctx, scratch_pool));
 
-  if (revision2->kind == svn_opt_revision_base || !is_copy)
+  if (revision2_kind == svn_opt_revision_base || !is_copy)
     {
       /* Convert path_or_url1 to a URL to feed to do_diff. */
       SVN_ERR(svn_wc_get_actual_target2(&anchor, &target, ctx->wc_ctx, path2,
@@ -2185,22 +2239,20 @@ diff_repos_wc(const char **root_relpath,
   else
     diff_depth = svn_depth_unknown;
 
+  /* Tell the RA layer we want a delta to change our txn to URL1 */
+  SVN_ERR(svn_ra_do_diff3(ra_session,
+                          &reporter, &reporter_baton,
+                          loc1->rev,
+                          target,
+                          diff_depth,
+                          ignore_ancestry,
+                          TRUE, /* text_deltas */
+                          loc1->url,
+                          diff_editor, diff_edit_baton,
+                          scratch_pool));
 
-
-  if (is_copy && revision2->kind != svn_opt_revision_base)
+  if (is_copy && revision2_kind != svn_opt_revision_base)
     {
-      /* Tell the RA layer we want a delta to change our txn to URL1 */
-      SVN_ERR(svn_ra_do_diff3(ra_session,
-                              &reporter, &reporter_baton,
-                              loc1->rev,
-                              target,
-                              diff_depth,
-                              ignore_ancestry,
-                              TRUE,  /* text_deltas */
-                              loc1->url,
-                              diff_editor, diff_edit_baton,
-                              scratch_pool));
-
       /* Report the copy source. */
       if (cf_depth == svn_depth_unknown)
         cf_depth = svn_depth_infinity;
@@ -2224,18 +2276,6 @@ diff_repos_wc(const char **root_relpath,
     }
   else
     {
-      /* Tell the RA layer we want a delta to change our txn to URL1 */
-      SVN_ERR(svn_ra_do_diff3(ra_session,
-                              &reporter, &reporter_baton,
-                              loc1->rev,
-                              target,
-                              diff_depth,
-                              ignore_ancestry,
-                              TRUE,  /* text_deltas */
-                              loc1->url,
-                              diff_editor, diff_edit_baton,
-                              scratch_pool));
-
       /* Create a txn mirror of path2;  the diff editor will print
          diffs in reverse.  :-)  */
       SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, abspath2,
@@ -2262,6 +2302,7 @@ do_diff(const char **root_relpath,
         const svn_opt_revision_t *revision1,
         const svn_opt_revision_t *revision2,
         const svn_opt_revision_t *peg_revision,
+        svn_boolean_t no_peg_revision,
         svn_depth_t depth,
         svn_boolean_t ignore_ancestry,
         const apr_array_header_t *changelists,
@@ -2282,7 +2323,7 @@ do_diff(const char **root_relpath,
     {
       if (is_repos2)
         {
-          /* ### Ignores 'show_copies_as_adds'. */
+          /* Ignores changelists. */
           SVN_ERR(diff_repos_repos(root_relpath, root_is_dir,
                                    ddi,
                                    path_or_url1, path_or_url2,
@@ -2295,8 +2336,11 @@ do_diff(const char **root_relpath,
       else /* path_or_url2 is a working copy path */
         {
           SVN_ERR(diff_repos_wc(root_relpath, root_is_dir, ddi,
-                                path_or_url1, revision1, peg_revision,
-                                path_or_url2, revision2, FALSE, depth,
+                                path_or_url1, revision1,
+                                no_peg_revision ? revision1
+                                                : peg_revision,
+                                path_or_url2, revision2->kind,
+                                FALSE, depth,
                                 ignore_ancestry, changelists,
                                 diff_processor, ctx,
                                 result_pool, scratch_pool));
@@ -2307,8 +2351,12 @@ do_diff(const char **root_relpath,
       if (is_repos2)
         {
           SVN_ERR(diff_repos_wc(root_relpath, root_is_dir, ddi,
-                                path_or_url2, revision2, peg_revision,
-                                path_or_url1, revision1, TRUE, depth,
+                                path_or_url2, revision2,
+                                no_peg_revision ? revision2
+                                                : peg_revision,
+                                path_or_url1,
+                                revision1->kind,
+                                TRUE, depth,
                                 ignore_ancestry, changelists,
                                 diff_processor, ctx,
                                 result_pool, scratch_pool));
@@ -2327,7 +2375,7 @@ do_diff(const char **root_relpath,
                                               scratch_pool));
 
               /* ### What about ddi? */
-
+              /* Ignores changelists, ignore_ancestry */
               SVN_ERR(svn_client__arbitrary_nodes_diff(root_relpath, root_is_dir,
                                                        abspath1, abspath2,
                                                        depth,
@@ -2531,7 +2579,8 @@ svn_client_diff6(const apr_array_header_
 
   return svn_error_trace(do_diff(NULL, NULL, &dwi.ddi,
                                  path_or_url1, path_or_url2,
-                                 revision1, revision2, &peg_revision,
+                                 revision1, revision2,
+                                 &peg_revision, TRUE /* no_peg_revision */,
                                  depth, ignore_ancestry, changelists,
                                  TRUE /* text_deltas */,
                                  diff_processor, ctx, pool, pool));
@@ -2614,7 +2663,8 @@ svn_client_diff_peg6(const apr_array_hea
 
   return svn_error_trace(do_diff(NULL, NULL, &dwi.ddi,
                                  path_or_url, path_or_url,
-                                 start_revision, end_revision, peg_revision,
+                                 start_revision, end_revision,
+                                 peg_revision, FALSE /* no_peg_revision */,
                                  depth, ignore_ancestry, changelists,
                                  TRUE /* text_deltas */,
                                  diff_processor, ctx, pool, pool));
@@ -2647,7 +2697,8 @@ svn_client_diff_summarize2(const char *p
 
   return svn_error_trace(do_diff(p_root_relpath, NULL, NULL,
                                  path_or_url1, path_or_url2,
-                                 revision1, revision2, &peg_revision,
+                                 revision1, revision2,
+                                 &peg_revision, TRUE /* no_peg_revision */,
                                  depth, ignore_ancestry, changelists,
                                  FALSE /* text_deltas */,
                                  diff_processor, ctx, pool, pool));
@@ -2676,7 +2727,8 @@ svn_client_diff_summarize_peg2(const cha
 
   return svn_error_trace(do_diff(p_root_relpath, NULL, NULL,
                                  path_or_url, path_or_url,
-                                 start_revision, end_revision, peg_revision,
+                                 start_revision, end_revision,
+                                 peg_revision, FALSE /* no_peg_revision */,
                                  depth, ignore_ancestry, changelists,
                                  FALSE /* text_deltas */,
                                  diff_processor, ctx, pool, pool));

Modified: subversion/branches/authzperf/subversion/libsvn_client/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_client/diff_local.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_client/diff_local.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_client/diff_local.c Fri Apr 29 18:38:53 2016
@@ -179,7 +179,7 @@ inner_dir_diff(const char *left_abspath,
         {
           svn_error_clear(err);
           right_dirents = apr_hash_make(scratch_pool);
-          right_only = TRUE;
+          left_only = TRUE;
         }
       else
         SVN_ERR(err);
@@ -669,9 +669,6 @@ svn_client__arbitrary_nodes_diff(const c
   SVN_ERR(svn_io_check_resolved_path(left_abspath, &left_kind, scratch_pool));
   SVN_ERR(svn_io_check_resolved_path(right_abspath, &right_kind, scratch_pool));
 
-  if (depth == svn_depth_unknown)
-    depth = svn_depth_infinity;
-
   if (left_kind == svn_node_dir && right_kind == svn_node_dir)
     {
       left_root_abspath = left_abspath;

Modified: subversion/branches/authzperf/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_client/externals.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_client/externals.c Fri Apr 29 18:38:53 2016
@@ -252,8 +252,10 @@ switch_dir_external(const char *local_ab
                 svn_error_clear(err);
                 err = NULL;
               }
+            else if (err)
+              return svn_error_trace(err);
 
-            return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, err,
+            return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                                      _("The external '%s' defined in %s at '%s' "
                                        "cannot be checked out because '%s' is "
                                        "already a versioned path."),
@@ -532,7 +534,7 @@ switch_file_external(const char *local_a
 
       SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
-      if (kind == svn_node_file || kind == svn_node_dir)
+      if (disk_kind == svn_node_file || disk_kind == svn_node_dir)
         return svn_error_createf(SVN_ERR_WC_PATH_FOUND, NULL,
                                  _("The file external '%s' can not be "
                                    "created because the node exists."),

Modified: subversion/branches/authzperf/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_client/merge.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_client/merge.c Fri Apr 29 18:38:53 2016
@@ -215,32 +215,6 @@
 
 /*** Repos-Diff Editor Callbacks ***/
 
-/* */
-typedef struct merge_source_t
-{
-  /* "left" side URL and revision (inclusive iff youngest) */
-  const svn_client__pathrev_t *loc1;
-
-  /* "right" side URL and revision (inclusive iff youngest) */
-  const svn_client__pathrev_t *loc2;
-
-  /* True iff LOC1 is an ancestor of LOC2 or vice-versa (history-wise). */
-  svn_boolean_t ancestral;
-} merge_source_t;
-
-/* Description of the merge target root node (a WC working node) */
-typedef struct merge_target_t
-{
-  /* Absolute path to the WC node */
-  const char *abspath;
-
-  /* The repository location of the base node of the target WC.  If the node
-   * is locally added, then URL & REV are NULL & SVN_INVALID_REVNUM.
-   * REPOS_ROOT_URL and REPOS_UUID are always valid. */
-  svn_client__pathrev_t loc;
-
-} merge_target_t;
-
 typedef struct merge_cmd_baton_t {
   svn_boolean_t force_delete;         /* Delete a file/dir even if modified */
   svn_boolean_t dry_run;
@@ -1295,6 +1269,15 @@ record_skip(merge_cmd_baton_t *merge_b,
   return SVN_NO_ERROR;
 }
 
+/* Forward declaration */
+static svn_client__merge_path_t *
+find_nearest_ancestor_with_intersecting_ranges(
+  svn_revnum_t *start,
+  svn_revnum_t *end,
+  const apr_array_header_t *children_with_mergeinfo,
+  svn_boolean_t path_is_own_ancestor,
+  const char *local_abspath);
+
 /* Record a tree conflict in the WC, unless this is a dry run or a record-
  * only merge, or if a tree conflict is already flagged for the VICTIM_PATH.
  * (The latter can happen if a merge-tracking-aware merge is doing multiple
@@ -1366,11 +1349,45 @@ record_tree_conflict(merge_cmd_baton_t *
             reason = svn_wc_conflict_reason_moved_here;
         }
 
-      SVN_ERR(make_conflict_versions(&left, &right, local_abspath,
-                                     merge_left_node_kind,
-                                     merge_right_node_kind,
-                                     &merge_b->merge_source, merge_b->target,
-                                     result_pool, scratch_pool));
+      if (HONOR_MERGEINFO(merge_b) && merge_b->merge_source.ancestral)
+        {
+          struct merge_source_t *source;
+          svn_client__pathrev_t *loc1;
+          svn_client__pathrev_t *loc2;
+          svn_merge_range_t range =
+            {SVN_INVALID_REVNUM, SVN_INVALID_REVNUM, TRUE};
+
+          /* We are honoring mergeinfo so do not blindly record
+           * a conflict describing the merge of
+           * SOURCE->LOC1->URL@SOURCE->LOC1->REV through
+           * SOURCE->LOC2->URL@SOURCE->LOC2->REV
+           * but figure out the actual revision range merged. */
+          (void)find_nearest_ancestor_with_intersecting_ranges(
+            &(range.start), &(range.end),
+            merge_b->notify_begin.nodes_with_mergeinfo,
+            action != svn_wc_conflict_action_delete,
+            local_abspath);
+          loc1 = svn_client__pathrev_dup(merge_b->merge_source.loc1,
+                                         scratch_pool);
+          loc2 = svn_client__pathrev_dup(merge_b->merge_source.loc2,
+                                         scratch_pool);
+          loc1->rev = range.start;
+          loc2->rev = range.end;
+          source = merge_source_create(loc1, loc2,
+                                       merge_b->merge_source.ancestral,
+                                       scratch_pool);
+          SVN_ERR(make_conflict_versions(&left, &right, local_abspath,
+                                         merge_left_node_kind,
+                                         merge_right_node_kind,
+                                         source, merge_b->target,
+                                         result_pool, scratch_pool));
+        }
+      else
+        SVN_ERR(make_conflict_versions(&left, &right, local_abspath,
+                                       merge_left_node_kind,
+                                       merge_right_node_kind,
+                                       &merge_b->merge_source, merge_b->target,
+                                       result_pool, scratch_pool));
 
       /* Fix up delete of file, add of dir replacement (or other way around) */
       if (existing_conflict != NULL && existing_conflict->src_left_version)
@@ -5481,29 +5498,16 @@ single_range_conflict_report_create(cons
   return report;
 }
 
-/* Data for reporting when a merge aborted because of raising conflicts.
- *
- * ### TODO: More info, including the ranges (or other parameters) the user
- *     needs to complete the merge.
- */
-typedef struct conflict_report_t
-{
-  const char *target_abspath;
-  /* The revision range during which conflicts were raised */
-  const merge_source_t *conflicted_range;
-  /* Was the conflicted range the last range in the whole requested merge? */
-  svn_boolean_t was_last_range;
-} conflict_report_t;
-
-/* Return a new conflict_report_t containing deep copies of the parameters,
- * allocated in RESULT_POOL. */
-static conflict_report_t *
+/* Return a new svn_client__conflict_report_t containing deep copies of the
+ * parameters, allocated in RESULT_POOL. */
+static svn_client__conflict_report_t *
 conflict_report_create(const char *target_abspath,
                        const merge_source_t *conflicted_range,
                        svn_boolean_t was_last_range,
                        apr_pool_t *result_pool)
 {
-  conflict_report_t *report = apr_palloc(result_pool, sizeof(*report));
+  svn_client__conflict_report_t *report = apr_palloc(result_pool,
+                                                     sizeof(*report));
 
   report->target_abspath = apr_pstrdup(result_pool, target_abspath);
   report->conflicted_range = merge_source_dup(conflicted_range, result_pool);
@@ -5512,11 +5516,12 @@ conflict_report_create(const char *targe
 }
 
 /* Return a deep copy of REPORT, allocated in RESULT_POOL. */
-static conflict_report_t *
-conflict_report_dup(const conflict_report_t *report,
+static svn_client__conflict_report_t *
+conflict_report_dup(const svn_client__conflict_report_t *report,
                     apr_pool_t *result_pool)
 {
-  conflict_report_t *new = apr_pmemdup(result_pool, report, sizeof(*new));
+  svn_client__conflict_report_t *new = apr_pmemdup(result_pool, report,
+                                                   sizeof(*new));
 
   new->target_abspath = apr_pstrdup(result_pool, report->target_abspath);
   new->conflicted_range = merge_source_dup(report->conflicted_range,
@@ -5524,11 +5529,9 @@ conflict_report_dup(const conflict_repor
   return new;
 }
 
-/* Create and return an error structure appropriate for the unmerged
-   revisions range(s). */
-static APR_INLINE svn_error_t *
-make_merge_conflict_error(conflict_report_t *report,
-                          apr_pool_t *scratch_pool)
+svn_error_t *
+svn_client__make_merge_conflict_error(svn_client__conflict_report_t *report,
+                                      apr_pool_t *scratch_pool)
 {
   assert(!report || svn_dirent_is_absolute(report->target_abspath));
 
@@ -6465,10 +6468,7 @@ get_mergeinfo_paths(apr_array_header_t *
       /* Sort CHILDREN_WITH_MERGEINFO by each child's path (i.e. as per
          compare_merge_path_t_as_paths).  Any subsequent insertions of new
          children with insert_child_to_merge() require this ordering. */
-      qsort(children_with_mergeinfo->elts,
-            children_with_mergeinfo->nelts,
-            children_with_mergeinfo->elt_size,
-            compare_merge_path_t_as_paths);
+      svn_sort__array(children_with_mergeinfo, compare_merge_path_t_as_paths);
     }
 
   /* Case 2: Switched subtrees
@@ -7077,8 +7077,7 @@ combine_range_with_segments(apr_array_he
   /* If this was a subtractive merge, and we created more than one
      merge source, we need to reverse the sort ordering of our sources. */
   if (subtractive && (merge_source_ts->nelts > 1))
-    qsort(merge_source_ts->elts, merge_source_ts->nelts,
-          merge_source_ts->elt_size, compare_merge_source_ts);
+    svn_sort__array(merge_source_ts, compare_merge_source_ts);
 
   *merge_source_ts_p = merge_source_ts;
   return SVN_NO_ERROR;
@@ -9766,7 +9765,7 @@ ensure_ra_session_url(svn_ra_session_t *
 static svn_error_t *
 do_merge(apr_hash_t **modified_subtrees,
          svn_mergeinfo_catalog_t result_catalog,
-         conflict_report_t **conflict_report,
+         svn_client__conflict_report_t **conflict_report,
          svn_boolean_t *use_sleep,
          const apr_array_header_t *merge_sources,
          const merge_target_t *target,
@@ -10089,23 +10088,24 @@ do_merge(apr_hash_t **modified_subtrees,
    SCRATCH_POOL is used for all temporary allocations.
  */
 static svn_error_t *
-merge_cousins_and_supplement_mergeinfo(conflict_report_t **conflict_report,
-                                       svn_boolean_t *use_sleep,
-                                       const merge_target_t *target,
-                                       svn_ra_session_t *URL1_ra_session,
-                                       svn_ra_session_t *URL2_ra_session,
-                                       const merge_source_t *source,
-                                       const svn_client__pathrev_t *yca,
-                                       svn_boolean_t same_repos,
-                                       svn_depth_t depth,
-                                       svn_boolean_t diff_ignore_ancestry,
-                                       svn_boolean_t force_delete,
-                                       svn_boolean_t record_only,
-                                       svn_boolean_t dry_run,
-                                       const apr_array_header_t *merge_options,
-                                       svn_client_ctx_t *ctx,
-                                       apr_pool_t *result_pool,
-                                       apr_pool_t *scratch_pool)
+merge_cousins_and_supplement_mergeinfo(
+  svn_client__conflict_report_t **conflict_report,
+  svn_boolean_t *use_sleep,
+  const merge_target_t *target,
+  svn_ra_session_t *URL1_ra_session,
+  svn_ra_session_t *URL2_ra_session,
+  const merge_source_t *source,
+  const svn_client__pathrev_t *yca,
+  svn_boolean_t same_repos,
+  svn_depth_t depth,
+  svn_boolean_t diff_ignore_ancestry,
+  svn_boolean_t force_delete,
+  svn_boolean_t record_only,
+  svn_boolean_t dry_run,
+  const apr_array_header_t *merge_options,
+  svn_client_ctx_t *ctx,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool)
 {
   apr_array_header_t *remove_sources, *add_sources;
   apr_hash_t *modified_subtrees = NULL;
@@ -10429,24 +10429,24 @@ open_target_wc(merge_target_t **target_p
  *
  * IGNORE_MERGEINFO and DIFF_IGNORE_ANCESTRY are as in do_merge().
  */
-static svn_error_t *
-merge_locked(conflict_report_t **conflict_report,
-             const char *source1,
-             const svn_opt_revision_t *revision1,
-             const char *source2,
-             const svn_opt_revision_t *revision2,
-             const char *target_abspath,
-             svn_depth_t depth,
-             svn_boolean_t ignore_mergeinfo,
-             svn_boolean_t diff_ignore_ancestry,
-             svn_boolean_t force_delete,
-             svn_boolean_t record_only,
-             svn_boolean_t dry_run,
-             svn_boolean_t allow_mixed_rev,
-             const apr_array_header_t *merge_options,
-             svn_client_ctx_t *ctx,
-             apr_pool_t *result_pool,
-             apr_pool_t *scratch_pool)
+svn_error_t *
+svn_client__merge_locked(svn_client__conflict_report_t **conflict_report,
+                         const char *source1,
+                         const svn_opt_revision_t *revision1,
+                         const char *source2,
+                         const svn_opt_revision_t *revision2,
+                         const char *target_abspath,
+                         svn_depth_t depth,
+                         svn_boolean_t ignore_mergeinfo,
+                         svn_boolean_t diff_ignore_ancestry,
+                         svn_boolean_t force_delete,
+                         svn_boolean_t record_only,
+                         svn_boolean_t dry_run,
+                         svn_boolean_t allow_mixed_rev,
+                         const apr_array_header_t *merge_options,
+                         svn_client_ctx_t *ctx,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
   merge_target_t *target;
   svn_client__pathrev_t *source1_loc, *source2_loc;
@@ -10643,7 +10643,7 @@ svn_client_merge5(const char *source1,
                   apr_pool_t *pool)
 {
   const char *target_abspath, *lock_abspath;
-  conflict_report_t *conflict_report;
+  svn_client__conflict_report_t *conflict_report;
 
   /* Sanity check our input -- we require specified revisions,
    * and either 2 paths or 2 URLs. */
@@ -10666,22 +10666,23 @@ svn_client_merge5(const char *source1,
 
   if (!dry_run)
     SVN_WC__CALL_WITH_WRITE_LOCK(
-      merge_locked(&conflict_report,
-                   source1, revision1, source2, revision2,
-                   target_abspath, depth, ignore_mergeinfo,
-                   diff_ignore_ancestry,
-                   force_delete, record_only, dry_run,
-                   allow_mixed_rev, merge_options, ctx, pool, pool),
+      svn_client__merge_locked(&conflict_report,
+                               source1, revision1, source2, revision2,
+                               target_abspath, depth, ignore_mergeinfo,
+                               diff_ignore_ancestry,
+                               force_delete, record_only, dry_run,
+                               allow_mixed_rev, merge_options, ctx, pool, pool),
       ctx->wc_ctx, lock_abspath, FALSE /* lock_anchor */, pool);
   else
-    SVN_ERR(merge_locked(&conflict_report,
-                   source1, revision1, source2, revision2,
-                   target_abspath, depth, ignore_mergeinfo,
-                   diff_ignore_ancestry,
-                   force_delete, record_only, dry_run,
-                   allow_mixed_rev, merge_options, ctx, pool, pool));
+    SVN_ERR(svn_client__merge_locked(&conflict_report,
+                                     source1, revision1, source2, revision2,
+                                     target_abspath, depth, ignore_mergeinfo,
+                                     diff_ignore_ancestry,
+                                     force_delete, record_only, dry_run,
+                                     allow_mixed_rev, merge_options, ctx, pool,
+                                     pool));
 
-  SVN_ERR(make_merge_conflict_error(conflict_report, pool));
+  SVN_ERR(svn_client__make_merge_conflict_error(conflict_report, pool));
   return SVN_NO_ERROR;
 }
 
@@ -11700,7 +11701,7 @@ open_reintegrate_source_and_target(svn_r
 
 /* The body of svn_client_merge_reintegrate(), which see for details. */
 static svn_error_t *
-merge_reintegrate_locked(conflict_report_t **conflict_report,
+merge_reintegrate_locked(svn_client__conflict_report_t **conflict_report,
                          const char *source_path_or_url,
                          const svn_opt_revision_t *source_peg_revision,
                          const char *target_abspath,
@@ -11775,7 +11776,7 @@ svn_client_merge_reintegrate(const char
                              apr_pool_t *pool)
 {
   const char *target_abspath, *lock_abspath;
-  conflict_report_t *conflict_report;
+  svn_client__conflict_report_t *conflict_report;
 
   SVN_ERR(get_target_and_lock_abspath(&target_abspath, &lock_abspath,
                                       target_wcpath, ctx, pool));
@@ -11795,7 +11796,7 @@ svn_client_merge_reintegrate(const char
                                      FALSE /*diff_ignore_ancestry*/,
                                      dry_run, merge_options, ctx, pool, pool));
 
-  SVN_ERR(make_merge_conflict_error(conflict_report, pool));
+  SVN_ERR(svn_client__make_merge_conflict_error(conflict_report, pool));
   return SVN_NO_ERROR;
 }
 
@@ -11805,7 +11806,7 @@ svn_client_merge_reintegrate(const char
  * IGNORE_MERGEINFO and DIFF_IGNORE_ANCESTRY are as in do_merge().
  */
 static svn_error_t *
-merge_peg_locked(conflict_report_t **conflict_report,
+merge_peg_locked(svn_client__conflict_report_t **conflict_report,
                  const char *source_path_or_url,
                  const svn_opt_revision_t *source_peg_revision,
                  const svn_rangelist_t *ranges_to_merge,
@@ -11857,6 +11858,21 @@ merge_peg_locked(conflict_report_t **con
 
   /* Do the real merge!  (We say with confidence that our merge
      sources are both ancestral and related.) */
+  if (getenv("SVN_ELEMENT_MERGE")
+      && same_repos
+      && (depth == svn_depth_infinity || depth == svn_depth_unknown)
+      && ignore_mergeinfo
+      && !record_only)
+    {
+      err = svn_client__merge_elements(&use_sleep,
+                                       merge_sources, target, ra_session,
+                                       diff_ignore_ancestry, force_delete,
+                                       dry_run, merge_options,
+                                       ctx, result_pool, scratch_pool);
+      /* ### Currently this merge just errors out on any conflicts */
+      *conflict_report = NULL;
+    }
+  else
   err = do_merge(NULL, NULL, conflict_report, &use_sleep,
                  merge_sources, target, ra_session,
                  TRUE /*sources_related*/, same_repos, ignore_mergeinfo,
@@ -11895,7 +11911,7 @@ client_find_automatic_merge(automatic_me
                             apr_pool_t *scratch_pool);
 
 static svn_error_t *
-do_automatic_merge_locked(conflict_report_t **conflict_report,
+do_automatic_merge_locked(svn_client__conflict_report_t **conflict_report,
                           const automatic_merge_t *merge,
                           const char *target_abspath,
                           svn_depth_t depth,
@@ -11925,7 +11941,7 @@ svn_client_merge_peg5(const char *source
                       apr_pool_t *pool)
 {
   const char *target_abspath, *lock_abspath;
-  conflict_report_t *conflict_report;
+  svn_client__conflict_report_t *conflict_report;
 
   /* No ranges to merge?  No problem. */
   if (ranges_to_merge != NULL && ranges_to_merge->nelts == 0)
@@ -11990,7 +12006,7 @@ svn_client_merge_peg5(const char *source
                        force_delete, record_only, dry_run,
                        allow_mixed_rev, merge_options, ctx, pool, pool));
 
-  SVN_ERR(make_merge_conflict_error(conflict_report, pool));
+  SVN_ERR(svn_client__make_merge_conflict_error(conflict_report, pool));
   return SVN_NO_ERROR;
 }
 
@@ -12670,7 +12686,7 @@ client_find_automatic_merge(automatic_me
  * eliminate already-cherry-picked revisions from the source.
  */
 static svn_error_t *
-do_automatic_merge_locked(conflict_report_t **conflict_report,
+do_automatic_merge_locked(svn_client__conflict_report_t **conflict_report,
                           const automatic_merge_t *merge,
                           const char *target_abspath,
                           svn_depth_t depth,

Modified: subversion/branches/authzperf/subversion/libsvn_client/mtcc.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_client/mtcc.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_client/mtcc.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_client/mtcc.c Fri Apr 29 18:38:53 2016
@@ -712,6 +712,7 @@ mtcc_prop_getter(const svn_string_t **mi
                 {
                   *mime_type = svn_string_dup(mod->value, pool);
                   mime_type = NULL;
+                  break;
                 }
             }
         }