You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2011/10/24 21:37:01 UTC

svn commit: r1188329 - in /subversion/trunk/subversion: include/ libsvn_client/ libsvn_fs/ libsvn_fs_base/ libsvn_fs_fs/ libsvn_repos/ tests/cmdline/

Author: pburba
Date: Mon Oct 24 19:37:00 2011
New Revision: 1188329

URL: http://svn.apache.org/viewvc?rev=1188329&view=rev
Log:
Fix issue #4022 'svn log -g interprets change in inherited mergeinfo due
to move as a merge'.

* subversion/include/svn_fs.h

  (svn_fs_get_mergeinfo2): New.

  (svn_fs_get_mergeinfo): Deprecated.

* subversion/libsvn_fs/fs-loader.c

  (svn_fs_get_mergeinfo2): New.

  (svn_fs_get_mergeinfo): Deprecated.

* subversion/libsvn_fs/fs-loader.h

  (root_vtable_t.get_mergeinfo): Add new args as per svn_fs_get_mergeinfo2.

* subversion/libsvn_fs_base/tree.c

  (get_mergeinfo_for_path_baton,
   txn_body_get_mergeinfo_for_path,
   get_mergeinfos_for_paths,
   base_get_mergeinfo): Drill down new svn_fs_get_mergeinfo2 arguments.

* subversion/libsvn_fs_fs/tree.c

  (get_mergeinfo_for_path,
   get_mergeinfos_for_paths,
   fs_get_mergeinfo): Drill down new svn_fs_get_mergeinfo2 arguments.

* subversion/libsvn_repos/log.c

  (get_combined_mergeinfo_changes): Use new svn_fs_get_mergeinfo2 to
   differentiate between mergeinfo changes brought about by merges from those
   attributable to copies.

* subversion/tests/cmdline/log_tests.py

  (merge_sensitive_log_copied_path_inherited_mergeinfo): Remove XFail
   decorator and adjust comment re failure status.

Modified:
    subversion/trunk/subversion/include/svn_fs.h
    subversion/trunk/subversion/libsvn_client/mergeinfo.c
    subversion/trunk/subversion/libsvn_client/mergeinfo.h
    subversion/trunk/subversion/libsvn_fs/fs-loader.c
    subversion/trunk/subversion/libsvn_fs/fs-loader.h
    subversion/trunk/subversion/libsvn_fs_base/tree.c
    subversion/trunk/subversion/libsvn_fs_fs/tree.c
    subversion/trunk/subversion/libsvn_repos/log.c
    subversion/trunk/subversion/tests/cmdline/log_tests.py

Modified: subversion/trunk/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_fs.h (original)
+++ subversion/trunk/subversion/include/svn_fs.h Mon Oct 24 19:37:00 2011
@@ -1501,6 +1501,15 @@ svn_fs_closest_copy(svn_fs_root_t **root
  * @a inherit indicates whether to retrieve explicit,
  * explicit-or-inherited, or only inherited mergeinfo.
  *
+ * If @a adjust_inherited_mergeinfo is TRUE, then any inherited
+ * mergeinfo returned in @a *catalog is normalized to represent the
+ * inherited mergeinfo on the path doing the inheriting.  If
+ * @a adjust_inherited_mergeinfo is FALSE, then any inherited
+ * mergeinfo is the raw explicit mergeinfo from the nearest parent
+ * of the path with explicit mergeinfo, unadjusted for the path-wise
+ * difference between the path and its parent.  This may include
+ * non-inheritable mergeinfo.
+ *
  * If @a include_descendants is TRUE, then additionally return the
  * mergeinfo for any descendant of any element of @a paths which has
  * the #SVN_PROP_MERGEINFO property explicitly set on it.  (Note
@@ -1508,11 +1517,29 @@ svn_fs_closest_copy(svn_fs_root_t **root
  * paths; descendants of the elements in @a paths which get their
  * mergeinfo via inheritance are not included in @a *catalog.)
  *
- * Do any necessary temporary allocation in @a pool.
+ * Allocate @a *catalog in result_pool.  Do any necessary temporary
+ * allocations in @a scratch_pool.
  *
- * @since New in 1.5.
+ * @since New in 1.8.
  */
 svn_error_t *
+svn_fs_get_mergeinfo2(svn_mergeinfo_catalog_t *catalog,
+                      svn_fs_root_t *root,
+                      const apr_array_header_t *paths,
+                      svn_mergeinfo_inheritance_t inherit,
+                      svn_boolean_t include_descendants,
+                      svn_boolean_t adjust_inherited_mergeinfo,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool);
+
+/**
+ * Same as svn_fs_get_mergeinfo2(), but with @a adjust_inherited_mergeinfo
+ * set always set to TRUE and only one pool.
+ *
+ * @deprecated Provided for backward compatibility with the 1.5 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_fs_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,
                      svn_fs_root_t *root,
                      const apr_array_header_t *paths,

Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.c?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_client/mergeinfo.c Mon Oct 24 19:37:00 2011
@@ -46,6 +46,125 @@
 #include "mergeinfo.h"
 #include "svn_private_config.h"
 
+svn_error_t *
+print_mergeinfo(svn_mergeinfo_t mergeinfo,
+                const char *msg,
+                apr_pool_t *pool)
+{
+#ifdef SVN_DEBUG
+  svn_string_t *out;
+  if (mergeinfo)
+    {
+      SVN_ERR(svn_mergeinfo_to_string(&out, mergeinfo, pool));
+      printf("\n----- %s --------------------------------------\n", msg);
+      printf("%s", out->data);
+      printf("\n---------------------------------------------\n");
+    }
+  else
+    {
+      printf("----- %s --------------------------------------\n", msg);
+      printf("NULL\n");
+      printf("\n---------------------------------------------\n");
+    }
+#endif
+  return SVN_NO_ERROR;
+}
+svn_error_t *
+print_mergeinfo_cat(svn_mergeinfo_catalog_t mergeinfo_catalog,
+                    const char *msg,
+                    apr_pool_t *pool)
+{
+#ifdef SVN_DEBUG
+  if (mergeinfo_catalog)
+    {
+      apr_hash_index_t *hi;
+
+      printf("===== %s ========================================\n", msg);
+      
+      for (hi = apr_hash_first(pool, mergeinfo_catalog);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          const char *path = svn__apr_hash_index_key(hi);
+          svn_mergeinfo_t mergeinfo = svn__apr_hash_index_val(hi);
+          SVN_ERR(print_mergeinfo(mergeinfo, path, pool));
+        }
+      printf("=================================================\n");
+    }
+  else
+    {
+      printf("----- %s --------------------------------------\n", msg);
+      printf("NULL\n");
+      printf("\n---------------------------------------------\n");
+    }
+#endif
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+print_rangelist(apr_array_header_t *rangelist,
+                const char *msg,
+                apr_pool_t *pool)
+{
+#ifdef SVN_DEBUG
+  svn_string_t *out;
+  if (rangelist)
+    {
+      SVN_ERR(svn_rangelist_to_string(&out, rangelist, pool));
+      printf("----- %s --------------------------------------\n", msg);
+      printf("%s", out->data);
+      printf("\n---------------------------------------------\n");
+    }
+  else
+    {
+      printf("----- %s --------------------------------------\n", msg);
+      printf("NULL\n");
+      printf("\n---------------------------------------------\n");
+    }
+#endif
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+print_cwmi(apr_array_header_t *children_with_mergeinfo,
+           apr_pool_t *scratch_pool)
+{
+  int i;
+  for (i = 1; i < children_with_mergeinfo->nelts; i++)
+    {
+      svn_client__merge_path_t *child =
+        APR_ARRAY_IDX(children_with_mergeinfo, i,
+                      svn_client__merge_path_t *);
+      SVN_ERR(print_mergeinfo(child->pre_merge_mergeinfo, child->abspath, scratch_pool));
+    }
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+cwmi_to_mergeinfo_catlog(svn_mergeinfo_catalog_t *mergeinfo_catalog,
+                         apr_array_header_t *children_with_mergeinfo,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  int i;
+
+  *mergeinfo_catalog = apr_hash_make(result_pool);
+
+  for (i = 0; i < children_with_mergeinfo->nelts; i++)
+    {
+      svn_client__merge_path_t *child =
+        APR_ARRAY_IDX(children_with_mergeinfo, i,
+                      svn_client__merge_path_t *);
+      if (child->pre_merge_mergeinfo)
+        {
+          apr_hash_set(*mergeinfo_catalog,
+                       child->abspath,
+                       APR_HASH_KEY_STRING,
+                       child->pre_merge_mergeinfo);
+        }
+    }
+  return SVN_NO_ERROR;
+}
 
 
 svn_client__merge_path_t *

Modified: subversion/trunk/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mergeinfo.h?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/trunk/subversion/libsvn_client/mergeinfo.h Mon Oct 24 19:37:00 2011
@@ -365,4 +365,27 @@ svn_client__mergeinfo_status(svn_boolean
                              const char *local_abspath,
                              apr_pool_t *scratch_pool);
 
+svn_error_t *
+print_mergeinfo(svn_mergeinfo_t mergeinfo,
+                const char *msg,
+                apr_pool_t *pool);
+
+svn_error_t *
+print_mergeinfo_cat(svn_mergeinfo_catalog_t mergeinfo_catalog,
+                    const char *msg,
+                    apr_pool_t *pool);
+svn_error_t *
+print_rangelist(apr_array_header_t *rangelist,
+                const char *msg,
+                apr_pool_t *pool);
+svn_error_t *
+print_cwmi(apr_array_header_t *children_with_mergeinfo,
+           apr_pool_t *scratch_pool);
+
+svn_error_t *
+cwmi_to_mergeinfo_catlog(svn_mergeinfo_catalog_t *mergeinfo_catalog,
+                         apr_array_header_t *children_with_mergeinfo,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
+
 #endif /* SVN_LIBSVN_CLIENT_MERGEINFO_H */

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.c?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.c Mon Oct 24 19:37:00 2011
@@ -891,6 +891,21 @@ svn_fs_closest_copy(svn_fs_root_t **root
 }
 
 svn_error_t *
+svn_fs_get_mergeinfo2(svn_mergeinfo_catalog_t *catalog,
+                      svn_fs_root_t *root,
+                      const apr_array_header_t *paths,
+                      svn_mergeinfo_inheritance_t inherit,
+                      svn_boolean_t include_descendants,
+                      svn_boolean_t adjust_inherited_mergeinfo,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(root->vtable->get_mergeinfo(
+    catalog, root, paths, inherit, include_descendants,
+    adjust_inherited_mergeinfo, result_pool, scratch_pool));
+}
+
+svn_error_t *
 svn_fs_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,
                      svn_fs_root_t *root,
                      const apr_array_header_t *paths,
@@ -901,7 +916,7 @@ svn_fs_get_mergeinfo(svn_mergeinfo_catal
   return svn_error_trace(root->vtable->get_mergeinfo(catalog, root, paths,
                                                      inherit,
                                                      include_descendants,
-                                                     pool));
+                                                     TRUE, pool, pool));
 }
 
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.h?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.h Mon Oct 24 19:37:00 2011
@@ -333,7 +333,9 @@ typedef struct root_vtable_t
                                 const apr_array_header_t *paths,
                                 svn_mergeinfo_inheritance_t inherit,
                                 svn_boolean_t include_descendants,
-                                apr_pool_t *pool);
+                                svn_boolean_t adjust_inherited_mergeinfo,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
 } root_vtable_t;
 
 

Modified: subversion/trunk/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/tree.c?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/tree.c Mon Oct 24 19:37:00 2011
@@ -5142,6 +5142,7 @@ struct get_mergeinfo_for_path_baton
   svn_fs_root_t *root;
   const char *path;
   svn_mergeinfo_inheritance_t inherit;
+  svn_boolean_t adjust_inherited_mergeinfo;
   apr_pool_t *pool;
 };
 
@@ -5237,7 +5238,7 @@ txn_body_get_mergeinfo_for_path(void *ba
      can return the mergeinfo results directly.  Otherwise, we're
      inheriting the mergeinfo, so we need to a) remove non-inheritable
      ranges and b) telescope the merged-from paths. */
-  if (nearest_ancestor != parent_path)
+  if (args->adjust_inherited_mergeinfo && (nearest_ancestor != parent_path))
     {
       svn_mergeinfo_t tmp_mergeinfo;
 
@@ -5291,10 +5292,12 @@ get_mergeinfos_for_paths(svn_fs_root_t *
                          const apr_array_header_t *paths,
                          svn_mergeinfo_inheritance_t inherit,
                          svn_boolean_t include_descendants,
-                         apr_pool_t *pool)
+                         svn_boolean_t adjust_inherited_mergeinfo,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
-  svn_mergeinfo_catalog_t result_catalog = apr_hash_make(pool);
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  svn_mergeinfo_catalog_t result_catalog = apr_hash_make(result_pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   int i;
 
   for (i = 0; i < paths->nelts; i++)
@@ -5312,12 +5315,13 @@ get_mergeinfos_for_paths(svn_fs_root_t *
       gmfp_args.root = root;
       gmfp_args.path = path;
       gmfp_args.inherit = inherit;
-      gmfp_args.pool = pool;
+      gmfp_args.pool = result_pool;
+      gmfp_args.adjust_inherited_mergeinfo = adjust_inherited_mergeinfo;
       SVN_ERR(svn_fs_base__retry_txn(root->fs,
                                      txn_body_get_mergeinfo_for_path,
                                      &gmfp_args, FALSE, iterpool));
       if (path_mergeinfo)
-        apr_hash_set(result_catalog, apr_pstrdup(pool, path),
+        apr_hash_set(result_catalog, apr_pstrdup(result_pool, path),
                      APR_HASH_KEY_STRING,
                      path_mergeinfo);
 
@@ -5363,7 +5367,9 @@ base_get_mergeinfo(svn_mergeinfo_catalog
                    const apr_array_header_t *paths,
                    svn_mergeinfo_inheritance_t inherit,
                    svn_boolean_t include_descendants,
-                   apr_pool_t *pool)
+                   svn_boolean_t adjust_inherited_mergeinfo,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   /* Verify that our filesystem version supports mergeinfo stuff. */
   SVN_ERR(svn_fs_base__test_required_feature_format
@@ -5376,7 +5382,8 @@ base_get_mergeinfo(svn_mergeinfo_catalog
   /* Retrieve a path -> mergeinfo mapping. */
   return get_mergeinfos_for_paths(root, catalog, paths,
                                   inherit, include_descendants,
-                                  pool);
+                                  adjust_inherited_mergeinfo,
+                                  result_pool, scratch_pool);
 }
 
 

Modified: subversion/trunk/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/tree.c?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/tree.c Mon Oct 24 19:37:00 2011
@@ -3463,6 +3463,7 @@ get_mergeinfo_for_path(svn_mergeinfo_t *
                        svn_fs_root_t *rev_root,
                        const char *path,
                        svn_mergeinfo_inheritance_t inherit,
+                       svn_boolean_t adjust_inherited_mergeinfo,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
 {
@@ -3549,7 +3550,7 @@ get_mergeinfo_for_path(svn_mergeinfo_t *
      can return the mergeinfo results directly.  Otherwise, we're
      inheriting the mergeinfo, so we need to a) remove non-inheritable
      ranges and b) telescope the merged-from paths. */
-  if (nearest_ancestor != parent_path)
+  if (adjust_inherited_mergeinfo && (nearest_ancestor != parent_path))
     {
       svn_mergeinfo_t tmp_mergeinfo;
 
@@ -3604,10 +3605,12 @@ get_mergeinfos_for_paths(svn_fs_root_t *
                          const apr_array_header_t *paths,
                          svn_mergeinfo_inheritance_t inherit,
                          svn_boolean_t include_descendants,
-                         apr_pool_t *pool)
+                         svn_boolean_t adjust_inherited_mergeinfo,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
-  svn_mergeinfo_catalog_t result_catalog = apr_hash_make(pool);
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  svn_mergeinfo_catalog_t result_catalog = apr_hash_make(result_pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   int i;
 
   for (i = 0; i < paths->nelts; i++)
@@ -3619,7 +3622,8 @@ get_mergeinfos_for_paths(svn_fs_root_t *
       svn_pool_clear(iterpool);
 
       err = get_mergeinfo_for_path(&path_mergeinfo, root, path,
-                                   inherit, pool, iterpool);
+                                   inherit, adjust_inherited_mergeinfo,
+                                   result_pool, iterpool);
       if (err)
         {
           if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
@@ -3638,8 +3642,8 @@ get_mergeinfos_for_paths(svn_fs_root_t *
         apr_hash_set(result_catalog, path, APR_HASH_KEY_STRING,
                      path_mergeinfo);
       if (include_descendants)
-        SVN_ERR(add_descendant_mergeinfo(result_catalog, root, path, pool,
-                                         iterpool));
+        SVN_ERR(add_descendant_mergeinfo(result_catalog, root, path,
+                                         result_pool, scratch_pool));
     }
   svn_pool_destroy(iterpool);
 
@@ -3655,7 +3659,9 @@ fs_get_mergeinfo(svn_mergeinfo_catalog_t
                  const apr_array_header_t *paths,
                  svn_mergeinfo_inheritance_t inherit,
                  svn_boolean_t include_descendants,
-                 apr_pool_t *pool)
+                 svn_boolean_t adjust_inherited_mergeinfo,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = root->fs->fsap_data;
 
@@ -3674,7 +3680,9 @@ fs_get_mergeinfo(svn_mergeinfo_catalog_t
   /* Retrieve a path -> mergeinfo hash mapping. */
   return get_mergeinfos_for_paths(root, catalog, paths,
                                   inherit,
-                                  include_descendants, pool);
+                                  include_descendants,
+                                  adjust_inherited_mergeinfo,
+                                  result_pool, scratch_pool);
 }
 
 

Modified: subversion/trunk/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/log.c?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/log.c (original)
+++ subversion/trunk/subversion/libsvn_repos/log.c Mon Oct 24 19:37:00 2011
@@ -794,8 +794,9 @@ get_combined_mergeinfo_changes(svn_merge
       const char *prev_path;
       svn_revnum_t appeared_rev, prev_rev;
       svn_fs_root_t *prev_root;
-      svn_mergeinfo_catalog_t catalog;
-      svn_mergeinfo_t prev_mergeinfo, mergeinfo, deleted, added;
+      svn_mergeinfo_catalog_t catalog, inherited_catalog;
+      svn_mergeinfo_t prev_mergeinfo, mergeinfo, deleted, added,
+        prev_inherited_mergeinfo, inherited_mergeinfo;
       apr_array_header_t *query_paths;
 
       svn_pool_clear(iterpool);
@@ -845,18 +846,57 @@ get_combined_mergeinfo_changes(svn_merge
           continue;
         }
       SVN_ERR(err);
+
+      /* Issue #4022 'svn log -g interprets change in inherited mergeinfo due
+         to move as a merge': A copy where the source and destination inherit
+         mergeinfo from the same parent means the inherited mergeinfo of the
+         source and destination will differ, but this diffrence is not
+         indicative of a merge unless the mergeinfo on the inherited parent
+         has actually changed.
+
+         To check for this we must fetch the "raw" previous inherited
+         mergeinfo and the "raw" mergeinfo @REV then compare these. */
+      SVN_ERR(svn_fs_get_mergeinfo2(&inherited_catalog, prev_root, query_paths,
+                                    svn_mergeinfo_nearest_ancestor, FALSE,
+                                    FALSE, /* adjust_inherited_mergeinfo */
+                                    iterpool, iterpool));
+
       prev_mergeinfo = apr_hash_get(catalog, prev_path, APR_HASH_KEY_STRING);
+      prev_inherited_mergeinfo = apr_hash_get(inherited_catalog, prev_path, APR_HASH_KEY_STRING);
 
       /* Fetch the current mergeinfo (as of REV, and including
          inherited stuff) for this path. */
       APR_ARRAY_IDX(query_paths, 0, const char *) = path;
       SVN_ERR(svn_fs_get_mergeinfo(&catalog, root, query_paths,
                                    svn_mergeinfo_inherited, FALSE, iterpool));
+
+      /* Issue #4022 again, fetch the raw inherited mergeinfo. */
+      SVN_ERR(svn_fs_get_mergeinfo2(&inherited_catalog, root, query_paths,
+                                    svn_mergeinfo_nearest_ancestor, FALSE,
+                                    FALSE, /* adjust_inherited_mergeinfo */
+                                    iterpool, iterpool));
+
       mergeinfo = apr_hash_get(catalog, path, APR_HASH_KEY_STRING);
+      inherited_mergeinfo = apr_hash_get(inherited_catalog, path, APR_HASH_KEY_STRING);
 
       if (!prev_mergeinfo && !mergeinfo)
         continue;
 
+      /* Last bit of issue #4022 checking. */
+      if (prev_inherited_mergeinfo && inherited_mergeinfo)
+        {
+          svn_boolean_t inherits_same_mergeinfo;
+
+          SVN_ERR(svn_mergeinfo__equals(&inherits_same_mergeinfo,
+                                        prev_inherited_mergeinfo,
+                                        inherited_mergeinfo,
+                                        TRUE, iterpool));
+          /* If a copy rather than an actual merge brought about an
+             inherited mergeinfo change then we are finished. */
+          if (inherits_same_mergeinfo)
+            continue;
+        }
+
       /* Compare, constrast, and combine the results. */
       SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, prev_mergeinfo,
                                   mergeinfo, FALSE, result_pool, iterpool));

Modified: subversion/trunk/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/log_tests.py?rev=1188329&r1=1188328&r2=1188329&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/log_tests.py Mon Oct 24 19:37:00 2011
@@ -2032,7 +2032,6 @@ def log_on_nonexistent_path_and_valid_re
 # Test for issue #4022 'svn log -g interprets change in inherited mergeinfo
 # due to move as a merge'.
 @Issue(4022)
-@XFail()
 def merge_sensitive_log_copied_path_inherited_mergeinfo(sbox):
   "log -g on copied path with inherited mergeinfo"
 
@@ -2060,8 +2059,8 @@ def merge_sensitive_log_copied_path_inhe
   svntest.main.run_svn(None, 'ci', '-m', 'Move file', wc_dir)
 
   # 'svn log -g --stop-on-copy ^/A/C/gamma' hould return *only* r5
-  # Currently this test fails because the change in gamma's inherited
-  # mergeinfo between r4 and r5, due to the move, is understood as a merge:
+  # Previously this test failed because the change in gamma's inherited
+  # mergeinfo between r4 and r5, due to the move, was understood as a merge:
   #
   #   >svn log -v -g --stop-on-copy ^^/A/C/gamma
   #   ------------------------------------------------------------------------