subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1199222 - in /subversion/branches/showing-merge-info/subversion: include/private/svn_client_private.h libsvn_client/mergeinfo.c libsvn_client/ra.c svn/mergeinfo-cmd.c
Date Tue, 08 Nov 2011 12:54:43 GMT
Author: julianfoad
Date: Tue Nov  8 12:54:43 2011
New Revision: 1199222

URL: http://svn.apache.org/viewvc?rev=1199222&view=rev
Log:
On the 'showing-merge-info' branch: Account for renaming of the source
branch over its lifetime.

* subversion/include/private/svn_client_private.h
  (svn_client__get_source_target_mergeinfo): Rename to
    'svn_client__get_branch_to_branch_mergeinfo' and take the source branch
    history as an input.
  (svn_client__get_location_segments): New function.

* subversion/libsvn_client/mergeinfo.c
  (filter_mergeinfo): Don't trip up on gaps in source history. Don't emit
    paths with no mergeinfo. Comment out the debugging prints.
  (filter_mergeinfo_catalog):  Don't emit paths with no mergeinfo.
  (svn_client__get_source_target_mergeinfo): Rename to
    'svn_client__get_branch_to_branch_mergeinfo' and take the source branch
    history as an input.

* subversion/libsvn_client/ra.c
  (svn_client__get_location_segments): New function.

* subversion/svn/mergeinfo-cmd.c
  (path_relative_to_branch): Rewrite to take account of the source branch's
    location history.
  (print_recorded_ranges): Get the source branch's location history.

Modified:
    subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
    subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c
    subversion/branches/showing-merge-info/subversion/libsvn_client/ra.c
    subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c

Modified: subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h?rev=1199222&r1=1199221&r2=1199222&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
(original)
+++ subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
Tue Nov  8 12:54:43 2011
@@ -94,15 +94,39 @@ svn_client__check_branch_root_marker(con
                                      svn_client_ctx_t *ctx,
                                      apr_pool_t *pool);
 
-/* Set *MERGEINFO to describe the merges into TARGET from (paths in the
- * history of) SOURCE_BRANCH. */
+/* Set *MERGEINFO to describe the merges into TARGET from paths in
+ * SOURCE_LOCATIONS which is an array of (svn_location_segment_t *)
+ * elements describing the history of the source branch over the
+ * revision range of interest. */
 svn_error_t *
-svn_client__get_source_target_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_cat,
-                                        const svn_client_peg_t *target,
-                                        const svn_client_peg_t *source_branch,
-                                        svn_client_ctx_t *ctx,
-                                        apr_pool_t *result_pool,
-                                        apr_pool_t *scratch_pool);
+svn_client__get_branch_to_branch_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_cat,
+                                           const svn_client_peg_t *target,
+                                           apr_array_header_t *source_locations,
+                                           svn_client_ctx_t *ctx,
+                                           apr_pool_t *result_pool,
+                                           apr_pool_t *scratch_pool);
+
+/* Set *SEGMENTS to an array of svn_location_segment_t * objects, each
+   representing a reposition location segment for the history of TARGET
+   between OLD_REVISION and YOUNG_REVISION, ordered from oldest segment
+   to youngest.  *SEGMENTS may be empty but it will never be NULL.
+
+   YOUNG_REVISION must not be NULL.  If OLD_REVISION is NULL it means the
+   beginning of TARGET's history.  See svn_ra_get_location_segments() for
+   the rules governing START_REVISION and END_REVISION in relation to the
+   target's peg revision.
+
+   This is similar to svn_client__repos_location_segments(), but takes
+   high-level (pegged) target and revision number parameters.
+   */
+svn_error_t *
+svn_client__get_location_segments(apr_array_header_t **segments,
+                                  const svn_client_peg_t *target,
+                                  const svn_opt_revision_t *young_revision,
+                                  const svn_opt_revision_t *old_revision,
+                                  svn_client_ctx_t *ctx,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool);
 
 
 #ifdef __cplusplus

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=1199222&r1=1199221&r2=1199222&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c Tue Nov  8
12:54:43 2011
@@ -733,33 +733,34 @@ filter_mergeinfo(svn_mergeinfo_t mergein
 {
   apr_hash_index_t *hi;
 
-  SVN_DBG(("filter_mergeinfo(in[%d], %8ld-%-8ld %s)\n",
+  /* SVN_DBG(("filter_mergeinfo(in[%d], %8ld-%-8ld %s)\n",
           apr_hash_count(mergeinfo_in),
-          segment->range_start, segment->range_end, segment->path));
+          segment->range_start, segment->range_end, segment->path)); */
   for (hi = apr_hash_first(scratch_pool, mergeinfo_in); hi; hi = apr_hash_next(hi))
     {
       const char *src_path = svn__apr_hash_index_key(hi);
       apr_array_header_t *ranges = svn__apr_hash_index_val(hi);
 
-      /* ### This needs to check the revision ranges. It presently just
-       *     assumes any matching path is OK. */
       SVN_ERR_ASSERT(src_path[0] == '/');
-      if (svn_relpath_skip_ancestor(segment->path, src_path + 1))
+      if (segment->path != NULL
+          && svn_relpath_skip_ancestor(segment->path, src_path + 1))
         {
           apr_array_header_t *rangelist_out;
-          {
+
+          /* {
             svn_string_t *ranges_string;
             SVN_ERR(svn_rangelist_to_string(&ranges_string, ranges, scratch_pool));
             SVN_DBG(("  %s[%d]: %s\n", src_path, ranges->nelts, ranges_string->data));
-          }
+          } */
           SVN_ERR(svn_client__rangelist_intersect_range(&rangelist_out, ranges,
                                                         segment->range_start,
                                                         segment->range_end,
                                                         FALSE /* consider_inheritance */,
                                                         result_pool, scratch_pool));
 
-          apr_hash_set(mergeinfo_out, src_path, APR_HASH_KEY_STRING,
-                       rangelist_out);
+          if (rangelist_out->nelts > 0)
+            apr_hash_set(mergeinfo_out, src_path, APR_HASH_KEY_STRING,
+                         rangelist_out);
         }
     }
 
@@ -795,6 +796,8 @@ filter_mergeinfo_catalog(svn_mergeinfo_c
                                    result_pool, scratch_pool));
         }
 
+      if (apr_hash_count(mergeinfo_out) == 0)
+        mergeinfo_out = NULL;
       apr_hash_set(mergeinfo_cat, path, APR_HASH_KEY_STRING, mergeinfo_out);
     }
 
@@ -802,30 +805,13 @@ filter_mergeinfo_catalog(svn_mergeinfo_c
 }
 
 svn_error_t *
-svn_client__get_source_target_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_cat,
-                                        const svn_client_peg_t *target,
-                                        const svn_client_peg_t *source_branch,
-                                        svn_client_ctx_t *ctx,
-                                        apr_pool_t *result_pool,
-                                        apr_pool_t *scratch_pool)
+svn_client__get_branch_to_branch_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_cat,
+                                           const svn_client_peg_t *target,
+                                           apr_array_header_t *source_locations,
+                                           svn_client_ctx_t *ctx,
+                                           apr_pool_t *result_pool,
+                                           apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *source_locations;
-
-  /* Find the source location-segments. */
-  {
-    svn_ra_session_t *ra_session;
-    svn_revnum_t rev;
-
-    SVN_ERR(svn_client__ra_session_from_peg(&ra_session, &rev, NULL,
-                                               source_branch,
-                                               &source_branch->peg_revision,
-                                               ctx, scratch_pool));
-    SVN_ERR(svn_client__repos_location_segments(&source_locations, ra_session,
-                                                "", rev, rev,
-                                                SVN_INVALID_REVNUM,
-                                                ctx, scratch_pool));
-  }
-
   /* Find the target mergeinfo */
   SVN_ERR(svn_client_get_mergeinfo_catalog(mergeinfo_cat,
                                            target->path_or_url,

Modified: subversion/branches/showing-merge-info/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/ra.c?rev=1199222&r1=1199221&r2=1199222&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/ra.c Tue Nov  8 12:54:43
2011
@@ -40,6 +40,7 @@
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_client_private.h"
 
 
 /* This is the baton that we pass svn_ra_open3(), and is associated with
@@ -592,6 +593,33 @@ svn_client__repos_location_segments(apr_
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_client__get_location_segments(apr_array_header_t **segments,
+                                  const svn_client_peg_t *target,
+                                  const svn_opt_revision_t *young_revision,
+                                  const svn_opt_revision_t *old_revision,
+                                  svn_client_ctx_t *ctx,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_ra_session_t *ra_session;
+  const char *young_url, *old_url = NULL;
+  svn_revnum_t rev, young_rev, old_rev = SVN_INVALID_REVNUM;
+
+  SVN_ERR(svn_client__ra_session_from_peg(&ra_session, &rev, NULL,
+                                          target, &target->peg_revision,
+                                          ctx, scratch_pool));
+  SVN_ERR(svn_client__repos_locations(&young_url, &young_rev,
+                                      &old_url, &old_rev,
+                                      ra_session, "", &target->peg_revision,
+                                      young_revision, old_revision,
+                                      ctx, scratch_pool));
+  SVN_ERR(svn_client__repos_location_segments(segments, ra_session, "", rev,
+                                              young_rev, old_rev,
+                                              ctx, result_pool));
+  return SVN_NO_ERROR;
+}
+
 
 svn_error_t *
 svn_client__repos_locations(const char **start_url,

Modified: subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c?rev=1199222&r1=1199221&r2=1199222&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c Tue Nov  8 12:54:43
2011
@@ -113,24 +113,52 @@ targets_are_same_branch(svn_client_targe
   return (strcmp(source->repos_relpath, target->repos_relpath) == 0);
 }
 
-/* */
+/* Return the path, relative to the source branch root, where SRC_FSPATH
+ * existed (or could have existed) over the revision ranges SRC_RANGES.
+ * SRC_ROOT_SEGMENTS is the location history of the source branch root.
+ *
+ * ### Assume this line of mergeinfo (SRC_PATH:SRC_RANGES) all occurs
+ * within a single history segment, which is almost certain in practice
+ * but not necessarily true.
+ */
 static const char *
-path_relative_to_branch(const char *src_path,
-                        apr_array_header_t *src_ranges,
-                        svn_client_target_t *source,
-                        /*source_segments*/
+path_relative_to_branch(const char *src_fspath,
+                        const apr_array_header_t *src_ranges,
+                        const apr_array_header_t *src_root_segments,
                         apr_pool_t *scratch_pool)
 {
-  const char *src_relpath;
+  const svn_merge_range_t *first_range
+    = APR_ARRAY_IDX(src_ranges, 0, svn_merge_range_t *);
+  const char *src_relpath = NULL;
+  int i;
+
+  SVN_ERR_ASSERT_NO_RETURN(src_fspath[0] == '/');
 
-  /* ### incomplete: should consider source_location_segments and ranges */
-  SVN_ERR_ASSERT_NO_RETURN(src_path[0] == '/');
-  src_relpath = svn_relpath_skip_ancestor(source->repos_relpath, src_path + 1);
+  for (i = 0; i < src_root_segments->nelts; i++)
+    {
+      const svn_location_segment_t *seg
+        = APR_ARRAY_IDX(src_root_segments, i, svn_location_segment_t *);
+      if (first_range->start + 1 >= seg->range_start
+          && first_range->start + 1 <= seg->range_end)
+        {
+          if (seg->path)
+            {
+              src_relpath = svn_relpath_skip_ancestor(seg->path, src_fspath + 1);
+            }
+          else
+            {
+              printf("    warning: mergeinfo '%s:%ld-...' refers to a gap in the source branch's
history\n",
+                     src_fspath, first_range->start + 1);
+              src_relpath = src_fspath;
+            }
+          break;
+        }
+    }
   if (src_relpath == NULL)
     {
-      printf("warning: source path '%s' was not in the source branch\n",
-             src_path);
-      src_relpath = src_path;
+      printf("    warning: mergeinfo '%s:%ld-...' is not in the source branch's history\n",
+             src_fspath, first_range->start + 1);
+      src_relpath = src_fspath;
     }
   return src_relpath;
 }
@@ -143,12 +171,22 @@ print_recorded_ranges(svn_client_target_
                       svn_client_ctx_t *ctx,
                       apr_pool_t *scratch_pool)
 {
+  apr_array_header_t *source_segments;
   svn_mergeinfo_catalog_t mergeinfo_cat;
   apr_array_header_t *mergeinfo_cat_sorted;
   int i;
 
-  SVN_ERR(svn_client__get_source_target_mergeinfo(
-            &mergeinfo_cat, target->peg, source->peg,
+  /* Find the source location-segments. */
+  /* ### This needs to stop where it meets 'target' at their common
+   * ancestor, as we don't want to report mergeinfo that refers to a
+   * period before the branch was branched. Perhaps such mergeinfo
+   * should never exist, but in practice it sometimes does. */
+  SVN_ERR(svn_client__get_location_segments(&source_segments, source->peg,
+                                            &source->peg->peg_revision, NULL,
+                                            ctx, scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_client__get_branch_to_branch_mergeinfo(
+            &mergeinfo_cat, target->peg, source_segments,
             ctx, scratch_pool, scratch_pool));
   mergeinfo_cat_sorted = svn_sort__hash(mergeinfo_cat,
                                         svn_sort_compare_items_as_paths,
@@ -183,8 +221,8 @@ print_recorded_ranges(svn_client_target_
                * maps to more than one src_relpath because of the source
                * branch root having moved during this range and yet the source
                * node continuing to have the same path? */
-              src_relpath = path_relative_to_branch(src_path, ranges, source,
-                                                    /*source_segments*/
+              src_relpath = path_relative_to_branch(src_path, ranges,
+                                                    source_segments,
                                                     scratch_pool);
               printf("    %s", ranges_string);
               if (ranges->nelts >= 4)



Mime
View raw message