You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2011/10/13 17:14:30 UTC

svn commit: r1182898 - in /subversion/branches/showing-merge-info: ./ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_fs/ subversion/libsvn_fs_base/bdb/ subversion/libsvn_fs_fs/ subversion/libsvn_ra_svn/ subv...

Author: julianfoad
Date: Thu Oct 13 15:14:29 2011
New Revision: 1182898

URL: http://svn.apache.org/viewvc?rev=1182898&view=rev
Log:
On the 'showing-merge-info' branch: Catch up to trunk@1182860.

Modified:
    subversion/branches/showing-merge-info/   (props changed)
    subversion/branches/showing-merge-info/CHANGES
    subversion/branches/showing-merge-info/subversion/include/private/svn_mergeinfo_private.h
    subversion/branches/showing-merge-info/subversion/include/private/svn_mutex.h
    subversion/branches/showing-merge-info/subversion/include/svn_types.h
    subversion/branches/showing-merge-info/subversion/libsvn_client/info.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/list.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c
    subversion/branches/showing-merge-info/subversion/libsvn_fs/fs-loader.c
    subversion/branches/showing-merge-info/subversion/libsvn_fs_base/bdb/env.c
    subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs.c
    subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/showing-merge-info/subversion/libsvn_subr/cmdline.c
    subversion/branches/showing-merge-info/subversion/libsvn_subr/dso.c
    subversion/branches/showing-merge-info/subversion/libsvn_subr/mergeinfo.c
    subversion/branches/showing-merge-info/subversion/libsvn_subr/svn_mutex.c
    subversion/branches/showing-merge-info/subversion/libsvn_wc/lock.c
    subversion/branches/showing-merge-info/subversion/libsvn_wc/merge.c
    subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c
    subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/mergeinfo-test.c
    subversion/branches/showing-merge-info/tools/dist/templates/stable-news.ezt

Propchange: subversion/branches/showing-merge-info/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Oct 13 15:14:29 2011
@@ -56,4 +56,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1177607-1182330
+/subversion/trunk:1177607-1182860

Modified: subversion/branches/showing-merge-info/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/CHANGES?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/CHANGES (original)
+++ subversion/branches/showing-merge-info/CHANGES Thu Oct 13 15:14:29 2011
@@ -9,6 +9,26 @@ http://svn.apache.org/repos/asf/subversi
     * fix inconsistent handling of log revs without changed paths (issue #3694)
 
 
+Version 1.7.1
+(?? ??? 2011, from /branches/1.7.x)
+http://svn.apache.org/repos/asf/subversion/tags/1.7.1
+
+  User-visible changes:
+   * improve performance of 'svn info' (r1164386)
+   * improve sorting performance (r1167659)
+   * update base completion for 1.7 (r1177001)
+   * make 'svn ls' continue to work with 1.0-1.3 repos (r1154278, -379, -82)
+   * improve error messages generated by SASL (r1179767)
+
+  Developer-visible changes:
+   * fix object lifetime issues in the JavaHL bindings (r1175888)
+   * fix org.tigris JavaHL wrappers to avoid double finalize (r1179680)
+   * don't write to const memory (r1177492)
+   * improve zlib configuration (r1174761, -98, -806)
+   * improve SQLite runtime init for OS X 10.7 compat (r1181666)
+   * improve test suite correctness (r1174111)
+
+
 Version 1.7.0
 (11 Oct 2011, from /branches/1.7.x)
 http://svn.apache.org/repos/asf/subversion/tags/1.7.0

Modified: subversion/branches/showing-merge-info/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/private/svn_mergeinfo_private.h?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/private/svn_mergeinfo_private.h Thu Oct 13 15:14:29 2011
@@ -252,6 +252,17 @@ svn_mergeinfo__mergeinfo_from_segments(s
                                        const apr_array_header_t *segments,
                                        apr_pool_t *pool);
 
+/* Merge every rangelist in MERGEINFO into the given MERGED_RANGELIST,
+ * ignoring the source paths of MERGEINFO. MERGED_RANGELIST may
+ * initially be empty. New elements added to @a rangelist are allocated in
+ * @a result_pool. See svn_rangelist_merge2() for details of inheritability
+ * etc. */
+svn_error_t *
+svn_rangelist__merge_many(apr_array_header_t *merged_rangelist,
+                          svn_mergeinfo_t mergeinfo,
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/showing-merge-info/subversion/include/private/svn_mutex.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/private/svn_mutex.h?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/private/svn_mutex.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/private/svn_mutex.h Thu Oct 13 15:14:29 2011
@@ -56,10 +56,9 @@ typedef void svn_mutex__t;
 #endif
 
 /** Initialize the @a *mutex. If @a enable_mutex is TRUE, the mutex will
- * actually be created with a lifetime defined by @a pool. Otherwise, the
- * pointer will be set to @c NULL and @ref svn_mutex__lock as well as
- * @ref svn_mutex__unlock will be no-ops. The same happens at the end 
- * of the pool lifetime as part of the pool cleanup.
+ * actually be created with a lifetime defined by @a result_pool. Otherwise,
+ * the pointer will be set to @c NULL and @ref svn_mutex__lock as well as
+ * @ref svn_mutex__unlock will be no-ops.
  * 
  * If @a enable_mutex is set but threading is not supported by APR, this 
  * function returns an @c APR_ENOTIMPL error.
@@ -67,7 +66,7 @@ typedef void svn_mutex__t;
 svn_error_t *
 svn_mutex__init(svn_mutex__t **mutex,
                 svn_boolean_t enable_mutex,
-                apr_pool_t *pool);
+                apr_pool_t *result_pool);
 
 /** Acquire the @a mutex, if that has been enabled in @ref svn_mutex__init.
  * Make sure to call @ref svn_mutex__unlock some time later in the same 

Modified: subversion/branches/showing-merge-info/subversion/include/svn_types.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/svn_types.h?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/svn_types.h (original)
+++ subversion/branches/showing-merge-info/subversion/include/svn_types.h Thu Oct 13 15:14:29 2011
@@ -147,9 +147,13 @@ typedef struct svn_error_t
 
 } svn_error_t;
 
+
+
 /* See svn_version.h.
    Defined here to avoid including svn_version.h from all public headers. */
 typedef struct svn_version_t svn_version_t;
+
+
 
 /** @defgroup APR_ARRAY_compat_macros APR Array Compatibility Helper Macros
  * These macros are provided by APR itself from version 1.3.
@@ -168,6 +172,8 @@ typedef struct svn_version_t svn_version
 #endif
 
 /** @} */
+
+
 
 /** @defgroup apr_hash_utilities APR Hash Table Helpers
  * These functions enable the caller to dereference an APR hash table index
@@ -189,6 +195,10 @@ svn__apr_hash_index_klen(const apr_hash_
 void *
 svn__apr_hash_index_val(const apr_hash_index_t *hi);
 
+/** @} */
+
+
+
 /** On Windows, APR_STATUS_IS_ENOTDIR includes several kinds of
  * invalid-pathname error but not ERROR_INVALID_NAME, so we include it.
  * We also include ERROR_DIRECTORY as that was not included in apr versions
@@ -203,6 +213,8 @@ svn__apr_hash_index_val(const apr_hash_i
 #endif
 
 /** @} */
+
+
 
 /** A node kind.
  *
@@ -283,6 +295,7 @@ svn__kind_from_node_kind(svn_node_kind_t
                          svn_boolean_t is_symlink);
 
 
+
 /** Generic three-state property to represent an unknown value for values
  * that are just like booleans.  The values have been set deliberately to
  * make tristates disjoint from #svn_boolean_t.
@@ -316,6 +329,7 @@ svn_tristate_t
 svn_tristate__from_word(const char * word);
 
 
+
 /** About Special Files in Subversion
  *
  * Subversion denotes files that cannot be portably created or
@@ -353,6 +367,8 @@ svn_tristate__from_word(const char * wor
  *     routines from 1.
  */
 
+
+
 /** A revision number. */
 typedef long int svn_revnum_t;
 
@@ -399,6 +415,7 @@ svn_revnum_parse(svn_revnum_t *rev,
 #define SVN_REVNUM_T_FMT "ld"
 
 
+
 /** The size of a file in the Subversion FS. */
 typedef apr_int64_t svn_filesize_t;
 
@@ -416,6 +433,7 @@ typedef apr_int64_t svn_filesize_t;
 #endif
 
 
+
 /** An enum to indicate whether recursion is needed. */
 enum svn_recurse_kind
 {
@@ -473,7 +491,6 @@ typedef enum svn_depth_t
 
 } svn_depth_t;
 
-
 /** Return a constant string expressing @a depth as an English word,
  * e.g., "infinity", "immediates", etc.  The string is not localized,
  * as it may be used for client<->server communications.
@@ -483,7 +500,6 @@ typedef enum svn_depth_t
 const char *
 svn_depth_to_word(svn_depth_t depth);
 
-
 /** Return the appropriate depth for @a depth_str.  @a word is as
  * returned from svn_depth_to_word().  If @a depth_str does not
  * represent a recognized depth, return #svn_depth_unknown.
@@ -493,7 +509,6 @@ svn_depth_to_word(svn_depth_t depth);
 svn_depth_t
 svn_depth_from_word(const char *word);
 
-
 /* Return #svn_depth_infinity if boolean @a recurse is TRUE, else
  * return #svn_depth_files.
  *
@@ -505,7 +520,6 @@ svn_depth_from_word(const char *word);
 #define SVN_DEPTH_INFINITY_OR_FILES(recurse) \
   ((recurse) ? svn_depth_infinity : svn_depth_files)
 
-
 /* Return #svn_depth_infinity if boolean @a recurse is TRUE, else
  * return #svn_depth_immediates.
  *
@@ -517,7 +531,6 @@ svn_depth_from_word(const char *word);
 #define SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse) \
   ((recurse) ? svn_depth_infinity : svn_depth_immediates)
 
-
 /* Return #svn_depth_infinity if boolean @a recurse is TRUE, else
  * return #svn_depth_empty.
  *
@@ -529,7 +542,6 @@ svn_depth_from_word(const char *word);
 #define SVN_DEPTH_INFINITY_OR_EMPTY(recurse) \
   ((recurse) ? svn_depth_infinity : svn_depth_empty)
 
-
 /* Return a recursion boolean based on @a depth.
  *
  * Although much code has been converted to use depth, some code still
@@ -542,6 +554,7 @@ svn_depth_from_word(const char *word);
    ? TRUE : FALSE)
 
 
+
 /**
  * It is sometimes convenient to indicate which parts of an #svn_dirent_t
  * object you are actually interested in, so that calculating and sending
@@ -599,7 +612,6 @@ typedef struct svn_dirent_t
   /* IMPORTANT: If you extend this struct, check svn_dirent_dup(). */
 } svn_dirent_t;
 
-
 /** Return a deep copy of @a dirent, allocated in @a pool.
  *
  * @since New in 1.4.
@@ -608,8 +620,8 @@ svn_dirent_t *
 svn_dirent_dup(const svn_dirent_t *dirent,
                apr_pool_t *pool);
 
-
 
+
 /** Keyword substitution.
  *
  * All the keywords Subversion recognizes.
@@ -686,6 +698,7 @@ svn_dirent_dup(const svn_dirent_t *diren
 
 /** @} */
 
+
 
 /** All information about a commit.
  *
@@ -714,7 +727,6 @@ typedef struct svn_commit_info_t
 
 } svn_commit_info_t;
 
-
 /**
  * Allocate an object of type #svn_commit_info_t in @a pool and
  * return it.
@@ -732,7 +744,6 @@ typedef struct svn_commit_info_t
 svn_commit_info_t *
 svn_create_commit_info(apr_pool_t *pool);
 
-
 /**
  * Return a deep copy @a src_commit_info allocated in @a pool.
  *
@@ -742,6 +753,7 @@ svn_commit_info_t *
 svn_commit_info_dup(const svn_commit_info_t *src_commit_info,
                     apr_pool_t *pool);
 
+
 
 /**
  * A structure to represent a path that changed for a log entry.
@@ -820,7 +832,6 @@ typedef struct svn_log_changed_path_t
 
 } svn_log_changed_path_t;
 
-
 /**
  * Return a deep copy of @a changed_path, allocated in @a pool.
  *
@@ -970,7 +981,6 @@ svn_log_entry_dup(const svn_log_entry_t 
  *
  * @since New in 1.5.
  */
-
 typedef svn_error_t *(*svn_log_entry_receiver_t)(
   void *baton,
   svn_log_entry_t *log_entry,
@@ -991,6 +1001,7 @@ typedef svn_error_t *(*svn_log_message_r
   const char *message,
   apr_pool_t *pool);
 
+
 
 /** Callback function type for commits.
  *
@@ -1016,6 +1027,7 @@ typedef svn_error_t *(*svn_commit_callba
   const char *author,
   void *baton);
 
+
 
 /** A buffer size that may be used when processing a stream of data.
  *
@@ -1068,7 +1080,6 @@ svn_error_t *
 svn_mime_type_validate(const char *mime_type,
                        apr_pool_t *pool);
 
-
 /** Return FALSE iff @a mime_type is a textual type.
  *
  * All mime types that start with "text/" are textual, plus some special
@@ -1139,6 +1150,8 @@ svn_lock_create(apr_pool_t *pool);
 svn_lock_t *
 svn_lock_dup(const svn_lock_t *lock, apr_pool_t *pool);
 
+
+
 /**
  * Return a formatted Universal Unique IDentifier (UUID) string.
  *
@@ -1147,6 +1160,8 @@ svn_lock_dup(const svn_lock_t *lock, apr
 const char *
 svn_uuid_generate(apr_pool_t *pool);
 
+
+
 /**
  * Mergeinfo representing a merge of a range of revisions.
  *
@@ -1212,7 +1227,6 @@ typedef struct svn_location_segment_t
 
 } svn_location_segment_t;
 
-
 /**
  * A callback invoked by generators of #svn_location_segment_t
  * objects, used to report information about a versioned object's
@@ -1224,7 +1238,6 @@ typedef svn_error_t *(*svn_location_segm
   void *baton,
   apr_pool_t *pool);
 
-
 /**
  * Return a deep copy of @a segment, allocated in @a pool.
  *
@@ -1236,6 +1249,8 @@ svn_location_segment_dup(const svn_locat
 
 /** @} */
 
+
+
 /** A line number, such as in a file or a stream.
  *
  * @since New in 1.7.
@@ -1249,6 +1264,7 @@ typedef unsigned long svn_linenum_t;
 #define SVN_LINENUM_MAX_VALUE ULONG_MAX
 
 
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/info.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/info.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/info.c Thu Oct 13 15:14:29 2011
@@ -256,6 +256,75 @@ wc_info_receiver(void *baton,
                                  abspath_or_url, &client_info, scratch_pool);
 }
 
+/* Like svn_ra_stat() but with a compatibility hack for pre-1.2 svnserve. */
+static svn_error_t *
+ra_stat_compatible(svn_ra_session_t *ra_session,
+                   svn_revnum_t rev,
+                   svn_dirent_t **dirent_p,
+                   apr_uint32_t dirent_fields,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
+{
+  const char *repos_root_URL, *url;
+  svn_error_t *err;
+  svn_dirent_t *the_ent;
+
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_URL, pool));
+  SVN_ERR(svn_ra_get_session_url(ra_session, &url, pool));
+
+  err = svn_ra_stat(ra_session, "", rev, &the_ent, pool);
+
+  /* svn_ra_stat() will work against old versions of mod_dav_svn, but
+     not old versions of svnserve.  In the case of a pre-1.2 svnserve,
+     catch the specific error it throws:*/
+  if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
+    {
+      /* Fall back to pre-1.2 strategy for fetching dirent's URL. */
+      svn_node_kind_t url_kind;
+      svn_ra_session_t *parent_ra_session;
+      apr_hash_t *parent_ents;
+      const char *parent_url, *base_name;
+
+      if (strcmp(url, repos_root_URL) == 0)
+        {
+          /* In this universe, there's simply no way to fetch
+             information about the repository's root directory! */
+          return err;
+        }
+
+      svn_error_clear(err);
+
+      SVN_ERR(svn_ra_check_path(ra_session, "", rev, &url_kind, pool));
+      if (url_kind == svn_node_none)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 _("URL '%s' non-existent in revision %ld"),
+                                 url, rev);
+
+      /* Open a new RA session to the item's parent. */
+      svn_uri_split(&parent_url, &base_name, url, pool);
+      SVN_ERR(svn_client__open_ra_session_internal(&parent_ra_session, NULL,
+                                                   parent_url, NULL,
+                                                   NULL, FALSE, TRUE,
+                                                   ctx, pool));
+
+      /* Get all parent's entries, and find the item's dirent in the hash. */
+      SVN_ERR(svn_ra_get_dir2(parent_ra_session, &parent_ents, NULL, NULL,
+                              "", rev, dirent_fields, pool));
+      the_ent = apr_hash_get(parent_ents, base_name, APR_HASH_KEY_STRING);
+      if (the_ent == NULL)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 _("URL '%s' non-existent in revision %ld"),
+                                 url, rev);
+    }
+  else if (err)
+    {
+      return svn_error_trace(err);
+    }
+
+  *dirent_p = the_ent;
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_info3(const char *abspath_or_url,
                  const svn_opt_revision_t *peg_revision,
@@ -269,15 +338,13 @@ svn_client_info3(const char *abspath_or_
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
 {
-  svn_ra_session_t *ra_session, *parent_ra_session;
+  svn_ra_session_t *ra_session;
   svn_revnum_t rev;
   const char *url;
-  svn_node_kind_t url_kind;
   const char *repos_root_URL, *repos_UUID;
   svn_lock_t *lock;
   svn_boolean_t related;
-  apr_hash_t *parent_ents;
-  const char *parent_url, *base_name;
+  const char *base_name;
   svn_dirent_t *the_ent;
   svn_client_info2_t *info;
   svn_error_t *err;
@@ -312,56 +379,26 @@ svn_client_info3(const char *abspath_or_
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_URL, pool));
   SVN_ERR(svn_ra_get_uuid2(ra_session, &repos_UUID, pool));
 
-  svn_uri_split(&parent_url, &base_name, url, pool);
+  svn_uri_split(NULL, &base_name, url, pool);
 
   /* Get the dirent for the URL itself. */
-  err = svn_ra_stat(ra_session, "", rev, &the_ent, pool);
-
-  /* svn_ra_stat() will work against old versions of mod_dav_svn, but
-     not old versions of svnserve.  In the case of a pre-1.2 svnserve,
-     catch the specific error it throws:*/
+  err = ra_stat_compatible(ra_session, rev, &the_ent, DIRENT_FIELDS,
+                           ctx, pool);
   if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
     {
-      /* Fall back to pre-1.2 strategy for fetching dirent's URL. */
       svn_error_clear(err);
 
-      if (strcmp(url, repos_root_URL) == 0)
-        {
-          /* In this universe, there's simply no way to fetch
-             information about the repository's root directory!
-             If we're recursing, degrade gracefully: rather than
-             throw an error, return no information about the
-             repos root. */
-          if (depth > svn_depth_empty)
-            goto pre_1_2_recurse;
-
-          /* Otherwise, we really are stuck.  Better tell the user
-             what's going on. */
-          return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                   _("Server does not support retrieving "
-                                     "information about the repository root"));
-        }
-
-      SVN_ERR(svn_ra_check_path(ra_session, "", rev, &url_kind, pool));
-      if (url_kind == svn_node_none)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' non-existent in revision %ld"),
-                                 url, rev);
-
-      /* Open a new RA session to the item's parent. */
-      SVN_ERR(svn_client__open_ra_session_internal(&parent_ra_session, NULL,
-                                                   parent_url, NULL,
-                                                   NULL, FALSE, TRUE,
-                                                   ctx, pool));
-
-      /* Get all parent's entries, and find the item's dirent in the hash. */
-      SVN_ERR(svn_ra_get_dir2(parent_ra_session, &parent_ents, NULL, NULL,
-                              "", rev, DIRENT_FIELDS, pool));
-      the_ent = apr_hash_get(parent_ents, base_name, APR_HASH_KEY_STRING);
-      if (the_ent == NULL)
-        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                 _("URL '%s' non-existent in revision %ld"),
-                                 url, rev);
+      /* If we're recursing, degrade gracefully: rather than
+         throw an error, return no information about the
+         repos root. */
+      if (depth > svn_depth_empty)
+        goto pre_1_2_recurse;
+
+      /* Otherwise, we really are stuck.  Better tell the user
+         what's going on. */
+      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                               _("Server does not support retrieving "
+                                 "information about the repository root"));
     }
   else if (err)
     {

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/list.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/list.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/list.c Thu Oct 13 15:14:29 2011
@@ -121,42 +121,21 @@ get_dir_contents(apr_uint32_t dirent_fie
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_client_list2(const char *path_or_url,
-                 const svn_opt_revision_t *peg_revision,
-                 const svn_opt_revision_t *revision,
-                 svn_depth_t depth,
-                 apr_uint32_t dirent_fields,
-                 svn_boolean_t fetch_locks,
-                 svn_client_list_func_t list_func,
-                 void *baton,
-                 svn_client_ctx_t *ctx,
-                 apr_pool_t *pool)
+/* Like svn_ra_stat() but with a compatibility hack for pre-1.2 svnserve. */
+static svn_error_t *
+ra_stat_compatible(svn_ra_session_t *ra_session,
+                   svn_revnum_t rev,
+                   svn_dirent_t **dirent_p,
+                   apr_uint32_t dirent_fields,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
 {
-  svn_ra_session_t *ra_session;
-  svn_revnum_t rev;
-  svn_dirent_t *dirent;
-  const char *url;
-  const char *repos_root;
-  const char *fs_path;
+  const char *repos_root, *url;
   svn_error_t *err;
-  apr_hash_t *locks;
-
-  /* We use the kind field to determine if we should recurse, so we
-     always need it. */
-  dirent_fields |= SVN_DIRENT_KIND;
-
-  /* Get an RA plugin for this filesystem object. */
-  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
-                                           &url, path_or_url, NULL,
-                                           peg_revision,
-                                           revision, ctx, pool));
+  svn_dirent_t *dirent;
 
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
-
-  SVN_ERR(svn_client__path_relative_to_root(&fs_path, ctx->wc_ctx, url,
-                                            repos_root, TRUE, ra_session,
-                                            pool, pool));
+  SVN_ERR(svn_ra_get_session_url(ra_session, &url, pool));
 
   err = svn_ra_stat(ra_session, "", rev, &dirent, pool);
 
@@ -240,6 +219,49 @@ svn_client_list2(const char *path_or_url
   else if (err)
     return svn_error_trace(err);
 
+  *dirent_p = dirent;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_list2(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_client_list_func_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  svn_revnum_t rev;
+  svn_dirent_t *dirent;
+  const char *url;
+  const char *repos_root;
+  const char *fs_path;
+  svn_error_t *err;
+  apr_hash_t *locks;
+
+  /* We use the kind field to determine if we should recurse, so we
+     always need it. */
+  dirent_fields |= SVN_DIRENT_KIND;
+
+  /* Get an RA plugin for this filesystem object. */
+  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
+                                           &url, path_or_url, NULL,
+                                           peg_revision,
+                                           revision, ctx, pool));
+
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
+
+  SVN_ERR(svn_client__path_relative_to_root(&fs_path, ctx->wc_ctx, url,
+                                            repos_root, TRUE, ra_session,
+                                            pool, pool));
+
+  SVN_ERR(ra_stat_compatible(ra_session, rev, &dirent, dirent_fields,
+                             ctx, pool));
   if (! dirent)
     return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                              _("URL '%s' non-existent in revision %ld"),

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c Thu Oct 13 15:14:29 2011
@@ -1060,8 +1060,9 @@ filter_self_referential_mergeinfo(apr_ar
       /* Combine whatever older and younger filtered mergeinfo exists
          into filtered_mergeinfo. */
       if (filtered_mergeinfo && filtered_younger_mergeinfo)
-        SVN_ERR(svn_mergeinfo_merge(filtered_mergeinfo,
-                                    filtered_younger_mergeinfo, iterpool));
+        SVN_ERR(svn_mergeinfo_merge2(filtered_mergeinfo,
+                                     filtered_younger_mergeinfo, iterpool,
+                                     iterpool));
       else if (filtered_younger_mergeinfo)
         filtered_mergeinfo = filtered_younger_mergeinfo;
 
@@ -1463,7 +1464,6 @@ merge_file_changed(svn_wc_notify_state_t
   if (wc_kind != svn_node_file || is_deleted)
     {
       const char *moved_to_abspath;
-      svn_wc_conflict_reason_t reason;
       svn_error_t *err;
 
       /* Maybe the node is excluded via depth filtering? */
@@ -1513,6 +1513,8 @@ merge_file_changed(svn_wc_notify_state_t
         }
       else
         {
+          svn_wc_conflict_reason_t reason;
+
           if (is_deleted)
             reason = svn_wc_conflict_reason_deleted;
           else
@@ -4140,21 +4142,10 @@ find_gaps_in_merge_source_history(svn_re
       apr_array_header_t *implicit_rangelist =
         apr_array_make(scratch_pool, 2, sizeof(svn_merge_range_t *));
       apr_array_header_t *gap_rangelist;
-      apr_hash_index_t *hi;
-      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
-      for (hi = apr_hash_first(scratch_pool, implicit_src_mergeinfo);
-           hi;
-           hi = apr_hash_next(hi))
-        {
-          apr_array_header_t *value = svn__apr_hash_index_val(hi);
 
-          svn_pool_clear(iterpool);
-
-          SVN_ERR(svn_rangelist_merge2(implicit_rangelist, value,
-                                       scratch_pool, iterpool));
-        }
-      svn_pool_destroy(iterpool);
+      SVN_ERR(svn_rangelist__merge_many(implicit_rangelist,
+                                        implicit_src_mergeinfo,
+                                        scratch_pool, scratch_pool));
       SVN_ERR(svn_rangelist_remove(&gap_rangelist, implicit_rangelist,
                                    requested_rangelist, FALSE,
                                    scratch_pool));
@@ -7176,9 +7167,9 @@ process_children_with_new_mergeinfo(merg
              explicit mergeinfo. */
           if (path_inherited_mergeinfo)
             {
-              SVN_ERR(svn_mergeinfo_merge(path_explicit_mergeinfo,
-                                          path_inherited_mergeinfo,
-                                          iterpool));
+              SVN_ERR(svn_mergeinfo_merge2(path_explicit_mergeinfo,
+                                           path_inherited_mergeinfo,
+                                           iterpool, iterpool));
               SVN_ERR(svn_client__record_wc_mergeinfo(
                                           abspath_with_new_mergeinfo,
                                           path_explicit_mergeinfo,
@@ -7946,8 +7937,9 @@ record_mergeinfo_for_added_subtrees(
           /* Combine the explict mergeinfo on the added path (if any)
              with the mergeinfo describing this merge. */
           if (added_path_mergeinfo)
-            SVN_ERR(svn_mergeinfo_merge(merge_mergeinfo, added_path_mergeinfo,
-                                        iterpool));
+            SVN_ERR(svn_mergeinfo_merge2(merge_mergeinfo,
+                                         added_path_mergeinfo,
+                                         iterpool, iterpool));
           SVN_ERR(svn_client__record_wc_mergeinfo(
             added_abspath, merge_mergeinfo,
             !squelch_mergeinfo_notifications, merge_b->ctx, iterpool));
@@ -9966,21 +9958,10 @@ find_unsynced_ranges(const char *source_
            hi_catalog = apr_hash_next(hi_catalog))
         {
           svn_mergeinfo_t mergeinfo = svn__apr_hash_index_val(hi_catalog);
-          apr_hash_index_t *hi_mergeinfo;
-          apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
-          for (hi_mergeinfo = apr_hash_first(scratch_pool, mergeinfo);
-               hi_mergeinfo;
-               hi_mergeinfo = apr_hash_next(hi_mergeinfo))
-            {
-              apr_array_header_t *rangelist =
-                svn__apr_hash_index_val(hi_mergeinfo);
 
-              svn_pool_clear(iterpool);
-              SVN_ERR(svn_rangelist_merge2(potentially_unmerged_ranges,
-                                           rangelist, scratch_pool, iterpool));
-            }
-          svn_pool_destroy(iterpool);
+          SVN_ERR(svn_rangelist__merge_many(potentially_unmerged_ranges,
+                                            mergeinfo,
+                                            scratch_pool, scratch_pool));
         }
     }
 
@@ -10212,8 +10193,9 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
                                                   ctx, iterpool));
       SVN_ERR(svn_mergeinfo__mergeinfo_from_segments(
         &source_history_as_mergeinfo, segments, iterpool));
-      SVN_ERR(svn_mergeinfo_merge(source_mergeinfo,
-                                  source_history_as_mergeinfo, iterpool));
+      SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
+                                   source_history_as_mergeinfo, iterpool,
+                                   iterpool));
 
       /* Now source_mergeinfo represents everything we know about
          source_path's history.  Now we need to know what part, if any, of the
@@ -10329,9 +10311,9 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
                 ctx, iterpool));
               SVN_ERR(svn_mergeinfo__mergeinfo_from_segments(
                 &source_history_as_mergeinfo, segments, iterpool));
-              SVN_ERR(svn_mergeinfo_merge(source_mergeinfo,
-                                          source_history_as_mergeinfo,
-                                          iterpool));
+              SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
+                                           source_history_as_mergeinfo,
+                                           iterpool, iterpool));
               SVN_ERR(svn_mergeinfo_intersect2(&common_mergeinfo,
                                                source_mergeinfo,
                                                target_history_as_mergeinfo,

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c Thu Oct 13 15:14:29 2011
@@ -1937,23 +1937,9 @@ svn_client_mergeinfo_log(svn_boolean_t f
 
       /* Keep track of all ranges partially merged to any and all
          subtrees. */
-      if (apr_hash_count(merged_noninheritable))
-        {
-          apr_pool_t *iterpool2 = svn_pool_create(iterpool);
-
-          for (hi = apr_hash_first(iterpool, merged_noninheritable);
-               hi;
-               hi = apr_hash_next(hi))
-            {
-              apr_array_header_t *list = svn__apr_hash_index_val(hi);
-              svn_pool_clear(iterpool2);
-              SVN_ERR(svn_rangelist_merge2(
-                master_noninheritable_rangelist,
-                svn_rangelist_dup(list, scratch_pool),
-                scratch_pool, iterpool2));
-            }
-          svn_pool_destroy(iterpool2);
-        }
+      SVN_ERR(svn_rangelist__merge_many(master_noninheritable_rangelist,
+                                        merged_noninheritable,
+                                        scratch_pool, iterpool));
 
       /* Find the intersection of the inheritable part of TGT_MERGEINFO
          and SOURCE_HISTORY. */
@@ -1970,25 +1956,11 @@ svn_client_mergeinfo_log(svn_boolean_t f
              to SUBTREE_PATH. */
           apr_array_header_t *subtree_merged_rangelist =
             apr_array_make(scratch_pool, 1, sizeof(svn_merge_range_t *));
-          apr_pool_t *iterpool2 = svn_pool_create(iterpool);
 
-          for (hi = apr_hash_first(iterpool, merged);
-               hi;
-               hi = apr_hash_next(hi))
-            {
-              apr_array_header_t *list = svn__apr_hash_index_val(hi);
-
-              svn_pool_clear(iterpool2);
-              SVN_ERR(svn_rangelist_merge2(master_inheritable_rangelist,
-                                           svn_rangelist_dup(list,
-                                                             scratch_pool),
-                                           scratch_pool, iterpool2));
-              SVN_ERR(svn_rangelist_merge2(subtree_merged_rangelist,
-                                           svn_rangelist_dup(list,
-                                                            scratch_pool),
-                                           scratch_pool, iterpool2));
-            }
-          svn_pool_destroy(iterpool2);
+          SVN_ERR(svn_rangelist__merge_many(master_inheritable_rangelist,
+                                            merged, scratch_pool, iterpool));
+          SVN_ERR(svn_rangelist__merge_many(subtree_merged_rangelist,
+                                            merged, scratch_pool, iterpool));
 
           apr_hash_set(inheritable_subtree_merges,
                        apr_pstrdup(scratch_pool, subtree_path),
@@ -2062,18 +2034,9 @@ svn_client_mergeinfo_log(svn_boolean_t f
       apr_array_header_t *source_master_rangelist =
         apr_array_make(scratch_pool, 1, sizeof(svn_merge_range_t *));
 
-      for (hi = apr_hash_first(scratch_pool, source_history);
-           hi;
-           hi = apr_hash_next(hi))
-        {
-          apr_array_header_t *subtree_merged_rangelist =
-            svn__apr_hash_index_val(hi);
-
-          svn_pool_clear(iterpool);
-          SVN_ERR(svn_rangelist_merge2(source_master_rangelist,
-                                       subtree_merged_rangelist,
-                                       scratch_pool, iterpool));
-        }
+      SVN_ERR(svn_rangelist__merge_many(source_master_rangelist,
+                                        source_history,
+                                        scratch_pool, scratch_pool));
 
       /* From what might be eligible subtract what we know is partially merged
          and then merge that back. */

Modified: subversion/branches/showing-merge-info/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_fs/fs-loader.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_fs/fs-loader.c Thu Oct 13 15:14:29 2011
@@ -265,8 +265,9 @@ svn_fs_initialize(apr_pool_t *pool)
     return SVN_NO_ERROR;
 
   common_pool = svn_pool_create(pool);
+#if APR_HAS_THREADS
   SVN_ERR(svn_mutex__init(&common_pool_lock, TRUE, common_pool));
-
+#endif
   /* ### This won't work if POOL is NULL and libsvn_fs is loaded as a DSO
      ### (via libsvn_ra_local say) since the global common_pool will live
      ### longer than the DSO, which gets unloaded when the pool used to

Modified: subversion/branches/showing-merge-info/subversion/libsvn_fs_base/bdb/env.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_fs_base/bdb/env.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_fs_base/bdb/env.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_fs_base/bdb/env.c Thu Oct 13 15:14:29 2011
@@ -367,6 +367,7 @@ static apr_status_t
 clear_cache(void *data)
 {
   bdb_cache = NULL;
+  bdb_cache_lock = NULL;
   return APR_SUCCESS;
 }
 
@@ -540,6 +541,7 @@ svn_fs_bdb__close(bdb_env_baton_t *bdb_b
 #endif
     }
 
+  /* This may run during final pool cleanup when the lock is NULL. */
   SVN_MUTEX__WITH_LOCK(bdb_cache_lock, svn_fs_bdb__close_internal(bdb));
   
   return SVN_NO_ERROR;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs.c Thu Oct 13 15:14:29 2011
@@ -95,7 +95,8 @@ fs_serialized_init(svn_fs_t *fs, apr_poo
       SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock, 
                               SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
 
-      SVN_ERR(svn_mutex__init(&ffsd->txn_list_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->txn_list_lock,
+                              SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
 
       key = apr_pstrdup(common_pool, key);
       status = apr_pool_userdata_set(ffsd, key, NULL, common_pool);

Modified: subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/cyrus_auth.c Thu Oct 13 15:14:29 2011
@@ -123,10 +123,10 @@ static int check_result(svn_error_t *err
   if (err)
     {
       svn_error_clear(err);
-      return 0;
+      return -1;
     }
     
-  return -1;
+  return 0;
 }
 
 static int sasl_mutex_lock_cb(void *mutex)
@@ -771,7 +771,7 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se
   const char *local_addrport = NULL, *remote_addrport = NULL;
   svn_boolean_t success;
   sasl_callback_t *callbacks;
-  cred_baton_t cred_baton;
+  cred_baton_t cred_baton = { 0 };
   int i;
 
   if (!sess->is_tunneled)
@@ -801,7 +801,6 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se
   realmstring = apr_psprintf(pool, "%s %s", sess->realm_prefix, realm);
 
   /* Initialize the credential baton. */
-  memset(&cred_baton, 0, sizeof(cred_baton));
   cred_baton.auth_baton = sess->callbacks->auth_baton;
   cred_baton.realmstring = realmstring;
   cred_baton.pool = pool;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_subr/cmdline.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_subr/cmdline.c Thu Oct 13 15:14:29 2011
@@ -73,6 +73,7 @@ svn_cmdline_init(const char *progname, F
   apr_status_t status;
   apr_pool_t *pool;
   svn_error_t *err;
+  char prefix_buf[64];  /* 64 is probably bigger than most program names */
 
 #ifndef WIN32
   {
@@ -197,11 +198,17 @@ svn_cmdline_init(const char *progname, F
       return EXIT_FAILURE;
     }
 
-  /* This has to happen before any pools are created. */
+  strncpy(prefix_buf, progname, sizeof(prefix_buf) - 3);
+  prefix_buf[sizeof(prefix_buf) - 3] = '\0';
+  strcat(prefix_buf, ": ");
+
+  /* DSO pool must be created before any other pools used by the
+     application so that pool cleanup doesn't unload DSOs too
+     early. See docstring of svn_dso_initialize2(). */
   if ((err = svn_dso_initialize2()))
     {
-      if (error_stream && err->message)
-        fprintf(error_stream, "%s", err->message);
+      if (error_stream)
+        svn_handle_error2(err, error_stream, TRUE, prefix_buf);
 
       svn_error_clear(err);
       return EXIT_FAILURE;
@@ -223,8 +230,8 @@ svn_cmdline_init(const char *progname, F
 
   if ((err = svn_nls_init()))
     {
-      if (error_stream && err->message)
-        fprintf(error_stream, "%s", err->message);
+      if (error_stream)
+        svn_handle_error2(err, error_stream, TRUE, prefix_buf);
 
       svn_error_clear(err);
       return EXIT_FAILURE;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_subr/dso.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_subr/dso.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_subr/dso.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_subr/dso.c Thu Oct 13 15:14:29 2011
@@ -54,7 +54,7 @@ svn_dso_initialize2(void)
 
   dso_pool = svn_pool_create(NULL);
 
-  SVN_ERR(svn_mutex__init(&dso_mutex, TRUE, dso_pool));
+  SVN_ERR(svn_mutex__init(&dso_mutex, APR_HAS_THREADS, dso_pool));
 
   dso_cache = apr_hash_make(dso_pool);
   return SVN_NO_ERROR;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_subr/mergeinfo.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_subr/mergeinfo.c Thu Oct 13 15:14:29 2011
@@ -78,7 +78,7 @@ combine_ranges(svn_merge_range_t *output
 static svn_error_t *
 parse_pathname(const char **input,
                const char *end,
-               svn_stringbuf_t **pathname,
+               const char **pathname,
                apr_pool_t *pool)
 {
   const char *curr = *input;
@@ -101,17 +101,11 @@ parse_pathname(const char **input,
     return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                             _("No pathname preceding ':'"));
 
-  /* Tolerate relative repository paths, but convert them to absolute. */
-  if (**input == '/')
-    {
-      *pathname = svn_stringbuf_ncreate(*input, last_colon - *input, pool);
-    }
-  else
-    {
-      const char *repos_rel_path = apr_pstrndup(pool, *input,
-                                                last_colon - *input);
-      *pathname = svn_stringbuf_createf(pool, "/%s",  repos_rel_path);
-    }
+  /* Tolerate relative repository paths, but convert them to absolute.
+     ### Efficiency?  1 string duplication here, 2 in canonicalize. */
+  *pathname = svn_fspath__canonicalize(apr_pstrndup(pool, *input,
+                                                    last_colon - *input),
+                                       pool);
 
   *input = last_colon;
 
@@ -614,7 +608,7 @@ static svn_error_t *
 parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
                     apr_pool_t *scratch_pool)
 {
-  svn_stringbuf_t *pathname;
+  const char *pathname;
   apr_array_header_t *existing_rangelist;
   apr_array_header_t *rangelist = apr_array_make(scratch_pool, 1,
                                                  sizeof(svn_merge_range_t *));
@@ -627,7 +621,7 @@ parse_revision_line(const char **input, 
 
   *input = *input + 1;
 
-  SVN_ERR(parse_rangelist(input, end, rangelist, pathname->data, scratch_pool));
+  SVN_ERR(parse_rangelist(input, end, rangelist, pathname, scratch_pool));
 
   if (*input != end && *(*input) != '\n')
     return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
@@ -695,12 +689,12 @@ parse_revision_line(const char **input, 
      leading slash, e.g. "trunk:4033\n/trunk:4039-4995".  In the event
      we encounter this we merge the rangelists together under a single
      absolute path key. */
-  existing_rangelist = apr_hash_get(hash, pathname->data, APR_HASH_KEY_STRING);
+  existing_rangelist = apr_hash_get(hash, pathname, APR_HASH_KEY_STRING);
   if (existing_rangelist)
     SVN_ERR(svn_rangelist_merge2(rangelist, existing_rangelist,
                                  scratch_pool, scratch_pool));
 
-  apr_hash_set(hash, apr_pstrdup(apr_hash_pool_get(hash), pathname->data),
+  apr_hash_set(hash, apr_pstrdup(apr_hash_pool_get(hash), pathname),
                APR_HASH_KEY_STRING,
                svn_rangelist_dup(rangelist, apr_hash_pool_get(hash)));
 
@@ -2614,6 +2608,33 @@ svn_mergeinfo__mergeinfo_from_segments(s
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_rangelist__merge_many(apr_array_header_t *merged_rangelist,
+                          svn_mergeinfo_t merge_history,
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool)
+{
+  if (apr_hash_count(merge_history))
+    {
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+      apr_hash_index_t *hi;
+
+      for (hi = apr_hash_first(scratch_pool, merge_history);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          apr_array_header_t *subtree_rangelist = svn__apr_hash_index_val(hi);
+
+          svn_pool_clear(iterpool);
+          SVN_ERR(svn_rangelist_merge2(merged_rangelist, subtree_rangelist,
+                                       result_pool, iterpool));
+        }
+      svn_pool_destroy(iterpool);
+    }
+  return SVN_NO_ERROR;
+}
+
+
 const char *
 svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit)
 {

Modified: subversion/branches/showing-merge-info/subversion/libsvn_subr/svn_mutex.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_subr/svn_mutex.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_subr/svn_mutex.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_subr/svn_mutex.c Thu Oct 13 15:14:29 2011
@@ -1,5 +1,5 @@
 /*
- * svn_mutex.c: in-memory caching for Subversion
+ * svn_mutex.c: routines for mutual exclusion.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -24,22 +24,10 @@
 #include "svn_private_config.h"
 #include "private/svn_mutex.h"
 
-#if APR_HAS_THREADS
-/* Destructor to be called as part of the pool cleanup procedure. */
-static apr_status_t
-destroy_mutex(void *data)
-{
-  svn_mutex__t **mutex_p = data;
-  *mutex_p = NULL;
-
-  return APR_SUCCESS;
-}
-#endif
-
 svn_error_t *
 svn_mutex__init(svn_mutex__t **mutex_p, 
                 svn_boolean_t enable_mutex, 
-                apr_pool_t *pool)
+                apr_pool_t *result_pool)
 {
 #if APR_HAS_THREADS
   *mutex_p = NULL;
@@ -49,13 +37,11 @@ svn_mutex__init(svn_mutex__t **mutex_p, 
       apr_status_t status =
           apr_thread_mutex_create(&apr_mutex,
                                   APR_THREAD_MUTEX_DEFAULT,
-                                  pool);
+                                  result_pool);
       if (status)
         return svn_error_wrap_apr(status, _("Can't create mutex"));
 
       *mutex_p = apr_mutex;
-      apr_pool_cleanup_register(pool, mutex_p, destroy_mutex,
-                                apr_pool_cleanup_null);
     }
 #else
   if (enable_mutex)

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/lock.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/lock.c Thu Oct 13 15:14:29 2011
@@ -122,64 +122,64 @@ svn_wc__internal_check_wc(int *wc_format
         }
     }
 
-    if (*wc_format >= SVN_WC__WC_NG_VERSION)
-      {
-        svn_wc__db_status_t db_status;
-        svn_kind_t db_kind;
-
-        if (check_path)
-          {
-            /* If a node is not a directory, it is not a working copy
-               directory.  This allows creating new working copies as
-               a path below an existing working copy. */
-            svn_node_kind_t wc_kind;
-
-            SVN_ERR(svn_io_check_path(local_abspath, &wc_kind, scratch_pool));
-            if (wc_kind != svn_node_dir)
-              {
-                *wc_format = 0; /* Not a directory, so not a wc-directory */
-                return SVN_NO_ERROR;
-              }
-          }
-
-        err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL,
-                                   db, local_abspath,
-                                   scratch_pool, scratch_pool);
+  if (*wc_format >= SVN_WC__WC_NG_VERSION)
+    {
+      svn_wc__db_status_t db_status;
+      svn_kind_t db_kind;
 
-        if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-          {
-            svn_error_clear(err);
-            *wc_format = 0;
-            return SVN_NO_ERROR;
-          }
-        else
-          SVN_ERR(err);
-
-        if (db_kind != svn_kind_dir)
-          {
-            /* The WC thinks there must be a file, so this is not
-               a wc-directory */
-            *wc_format = 0;
-            return SVN_NO_ERROR;
-          }
+      if (check_path)
+        {
+          /* If a node is not a directory, it is not a working copy
+             directory.  This allows creating new working copies as
+             a path below an existing working copy. */
+          svn_node_kind_t wc_kind;
 
-        switch (db_status)
-          {
-            case svn_wc__db_status_not_present:
-            case svn_wc__db_status_server_excluded:
-            case svn_wc__db_status_excluded:
-              /* If there is a directory here, it is not related to the parent
-                 working copy: Obstruction */
-              *wc_format = 0;
+          SVN_ERR(svn_io_check_path(local_abspath, &wc_kind, scratch_pool));
+          if (wc_kind != svn_node_dir)
+            {
+              *wc_format = 0; /* Not a directory, so not a wc-directory */
               return SVN_NO_ERROR;
-            default:
-              break;
-          }
-      }
+            }
+        }
+
+      err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL,
+                                 db, local_abspath,
+                                 scratch_pool, scratch_pool);
+
+      if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        {
+          svn_error_clear(err);
+          *wc_format = 0;
+          return SVN_NO_ERROR;
+        }
+      else
+        SVN_ERR(err);
+
+      if (db_kind != svn_kind_dir)
+        {
+          /* The WC thinks there must be a file, so this is not
+             a wc-directory */
+          *wc_format = 0;
+          return SVN_NO_ERROR;
+        }
+
+      switch (db_status)
+        {
+          case svn_wc__db_status_not_present:
+          case svn_wc__db_status_server_excluded:
+          case svn_wc__db_status_excluded:
+            /* If there is a directory here, it is not related to the parent
+               working copy: Obstruction */
+            *wc_format = 0;
+            return SVN_NO_ERROR;
+          default:
+            break;
+        }
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/merge.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/merge.c Thu Oct 13 15:14:29 2011
@@ -928,8 +928,9 @@ maybe_resolve_conflicts(svn_skel_t **wor
 /* Attempt a trivial merge of LEFT_ABSPATH and RIGHT_ABSPATH to TARGET_ABSPATH.
  * The merge is trivial if the file at LEFT_ABSPATH equals TARGET_ABSPATH,
  * because in this case the content of RIGHT_ABSPATH can be copied to the
- * target. On success, set *MERGE_OUTCOME to SVN_WC_MERGE_MERGED,
- * and install work queue items allocated in RESULT_POOL in *WORK_ITEMS.
+ * target. On success, set *MERGE_OUTCOME to SVN_WC_MERGE_MERGED in case the
+ * target was changed, or to SVN_WC_MERGE_UNCHANGED if the target was not
+ * changed. Install work queue items allocated in RESULT_POOL in *WORK_ITEMS.
  * On failure, set *MERGE_OUTCOME to SVN_WC_MERGE_NO_MERGE. */
 static svn_error_t *
 merge_file_trivial(svn_skel_t **work_items,
@@ -944,40 +945,48 @@ merge_file_trivial(svn_skel_t **work_ite
 {
   svn_skel_t *work_item;
   svn_boolean_t same_contents = FALSE;
-  svn_error_t *err;
+  svn_node_kind_t kind;
+  svn_boolean_t is_special;
+
+  /* If the target is not a normal file, do not attempt a trivial merge. */
+  SVN_ERR(svn_io_check_special_path(target_abspath, &kind, &is_special,
+                                    scratch_pool));
+  if (kind != svn_node_file || is_special)
+    {
+      *merge_outcome = svn_wc_merge_no_merge;
+      return SVN_NO_ERROR;
+    }
 
   /* If the LEFT side of the merge is equal to WORKING, then we can
    * copy RIGHT directly. */
-  err = svn_io_files_contents_same_p(&same_contents, left_abspath,
-                                     target_abspath, scratch_pool);
-  if (err)
+  SVN_ERR(svn_io_files_contents_same_p(&same_contents, left_abspath,
+                                       target_abspath, scratch_pool));
+  if (same_contents)
     {
-      if (APR_STATUS_IS_ENOENT(err->apr_err))
+      /* Check whether the left side equals the right side.
+       * If it does, there is no change to merge so we leave the target
+       * unchanged. */
+      SVN_ERR(svn_io_files_contents_same_p(&same_contents, left_abspath,
+                                           right_abspath, scratch_pool));
+      if (same_contents)
         {
-          /* This can happen if TARGET_ABSPATH is a broken symlink.
-           * Let the smart merge code handle this. */
-          svn_error_clear(err);
-          *merge_outcome = svn_wc_merge_no_merge;
-          return SVN_NO_ERROR;
+          *merge_outcome = svn_wc_merge_unchanged;
         }
       else
-        return svn_error_trace(err);
-    }
-
-  if (same_contents)
-    {
-      if (!dry_run)
         {
-          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
-                                                db, target_abspath,
-                                                right_abspath,
-                                                FALSE /* use_commit_times */,
-                                                FALSE /* record_fileinfo */,
-                                                result_pool, scratch_pool));
-          *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+          *merge_outcome = svn_wc_merge_merged;
+          if (!dry_run)
+            {
+              SVN_ERR(svn_wc__wq_build_file_install(
+                        &work_item, db, target_abspath, right_abspath,
+                        FALSE /* use_commit_times */,
+                        FALSE /* record_fileinfo */,
+                        result_pool, scratch_pool));
+              *work_items = svn_wc__wq_merge(*work_items, work_item,
+                                             result_pool);
+            }
         }
 
-      *merge_outcome = svn_wc_merge_merged;
       return SVN_NO_ERROR;
     }
 
@@ -1179,13 +1188,6 @@ merge_binary_file(svn_skel_t **work_item
 
   svn_dirent_split(&merge_dirpath, &merge_filename, mt->local_abspath, pool);
 
-  SVN_ERR(merge_file_trivial(work_items, merge_outcome,
-                             left_abspath, right_abspath,
-                             mt->local_abspath, dry_run, mt->db,
-                             result_pool, scratch_pool));
-  if (*merge_outcome == svn_wc_merge_merged)
-    return SVN_NO_ERROR;
-
   /* If we get here the binary files differ. Because we don't know how
    * to merge binary files in a non-trivial way we always flag a conflict. */
 
@@ -1414,41 +1416,48 @@ svn_wc__internal_merge(svn_skel_t **work
                                    cancel_func, cancel_baton,
                                    scratch_pool, scratch_pool));
 
-  if (is_binary)
-    {
-      SVN_ERR(merge_binary_file(work_items,
-                                merge_outcome,
-                                &mt,
-                                left_abspath,
-                                right_abspath,
-                                left_label,
-                                right_label,
-                                target_label,
-                                dry_run,
-                                left_version,
-                                right_version,
-                                detranslated_target_abspath,
-                                conflict_func,
-                                conflict_baton,
-                                result_pool, scratch_pool));
-    }
-  else
+  SVN_ERR(merge_file_trivial(work_items, merge_outcome,
+                             left_abspath, right_abspath,
+                             target_abspath, dry_run, db,
+                             result_pool, scratch_pool));
+  if (*merge_outcome == svn_wc_merge_no_merge)
     {
-      SVN_ERR(merge_text_file(work_items,
-                              merge_outcome,
-                              &mt,
-                              left_abspath,
-                              right_abspath,
-                              left_label,
-                              right_label,
-                              target_label,
-                              dry_run,
-                              left_version,
-                              right_version,
-                              detranslated_target_abspath,
-                              conflict_func, conflict_baton,
-                              cancel_func, cancel_baton,
-                              result_pool, scratch_pool));
+      if (is_binary)
+        {
+          SVN_ERR(merge_binary_file(work_items,
+                                    merge_outcome,
+                                    &mt,
+                                    left_abspath,
+                                    right_abspath,
+                                    left_label,
+                                    right_label,
+                                    target_label,
+                                    dry_run,
+                                    left_version,
+                                    right_version,
+                                    detranslated_target_abspath,
+                                    conflict_func,
+                                    conflict_baton,
+                                    result_pool, scratch_pool));
+        }
+      else
+        {
+          SVN_ERR(merge_text_file(work_items,
+                                  merge_outcome,
+                                  &mt,
+                                  left_abspath,
+                                  right_abspath,
+                                  left_label,
+                                  right_label,
+                                  target_label,
+                                  dry_run,
+                                  left_version,
+                                  right_version,
+                                  detranslated_target_abspath,
+                                  conflict_func, conflict_baton,
+                                  cancel_func, cancel_baton,
+                                  result_pool, scratch_pool));
+        }
     }
 
   /* Merging is complete.  Regardless of text or binariness, we might

Modified: subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c Thu Oct 13 15:14:29 2011
@@ -135,7 +135,7 @@ test_inprocess_cache_basic(apr_pool_t *p
                                       APR_HASH_KEY_STRING,
                                       1,
                                       1,
-                                      TRUE,
+                                      APR_HAS_THREADS,
                                       "",
                                       pool));
 

Modified: subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/mergeinfo-test.c Thu Oct 13 15:14:29 2011
@@ -117,7 +117,7 @@ verify_mergeinfo_parse(const char *input
    -> merge ranges. */
 static apr_hash_t *info1, *info2;
 
-#define NBR_MERGEINFO_VALS 20
+#define NBR_MERGEINFO_VALS 24
 
 /* Valid mergeinfo values. */
 static const char * const mergeinfo_vals[NBR_MERGEINFO_VALS] =
@@ -146,7 +146,12 @@ static const char * const mergeinfo_vals
     "/gunther_branch:7-12*,1,5-10*",
     /* Adjacent rangelists of differing inheritability. */
     "/b5:5-53,1-4,54-90*",
-    "/c0:1-77,12-44"
+    "/c0:1-77,12-44",
+    /* Non-canonical paths. */
+    "/A/:7-8",
+    "/A///:7-8",
+    "/A/.:7-8",
+    "/A/./B:7-8"
   };
 /* Paths corresponding to mergeinfo_vals. */
 static const char * const mergeinfo_paths[NBR_MERGEINFO_VALS] =
@@ -173,7 +178,13 @@ static const char * const mergeinfo_path
     "/gunther_branch",
     "/gunther_branch",
     "/b5",
-    "/c0"
+    "/c0",
+
+    /* non-canonical paths converted to canonical */
+    "/A",
+    "/A",
+    "/A",
+    "/A/B"
   };
 /* First ranges from the paths identified by mergeinfo_paths. */
 static svn_merge_range_t mergeinfo_ranges[NBR_MERGEINFO_VALS][MAX_NBR_RANGES] =
@@ -200,6 +211,10 @@ static svn_merge_range_t mergeinfo_range
     { {0, 1, TRUE}, {4, 12, FALSE} },
     { {0, 53, TRUE}, {53, 90, FALSE} },
     { {0, 77, TRUE} },
+    { {6, 8, TRUE} },
+    { {6, 8, TRUE} },
+    { {6, 8, TRUE} },
+    { {6, 8, TRUE} },
   };
 
 static svn_error_t *

Modified: subversion/branches/showing-merge-info/tools/dist/templates/stable-news.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/tools/dist/templates/stable-news.ezt?rev=1182898&r1=1182897&r2=1182898&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/tools/dist/templates/stable-news.ezt (original)
+++ subversion/branches/showing-merge-info/tools/dist/templates/stable-news.ezt Thu Oct 13 15:14:29 2011
@@ -4,13 +4,13 @@
     title="Link to this section">&para;</a> 
 </h3> 
  
-<p>We are pleased to announce to release of Apache Subversion [version].  This
-   is the most complete Subversion release to date, and we encourage users
-   of Subversion to upgrade as soon as reasonable.  Please see the
-   <a href="">release
-   announcement</a> for more information about this release, and the
-   <a href="http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES"> 
-   change log</a> for information about this release.</p> 
+<p>We are pleased to announce the release of Apache Subversion [version].
+   This is the most complete Subversion release to date, and we encourage
+   users of Subversion to upgrade as soon as reasonable.  Please see the
+   <a href=""
+   >release announcement</a> and the
+   <a href="http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES"
+   >change log</a> for more information about this release.</p> 
  
 <p>To get this release from the nearest mirror, please visit our
    <a href="/download/#recommended-release">download page</a>.</p>