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/08/29 22:13:32 UTC

svn commit: r1162974 - in /subversion/trunk/subversion: libsvn_client/merge.c tests/cmdline/merge_reintegrate_tests.py

Author: pburba
Date: Mon Aug 29 20:13:32 2011
New Revision: 1162974

URL: http://svn.apache.org/viewvc?rev=1162974&view=rev
Log:
Fix issue #3867 'reintegrate merges create mergeinfo for non-existent paths'.

* subversion/libsvn_client/merge.c

  (record_mergeinfo_for_dir_merge): Filter non-existent path-revs and/or
   unrelated lines of history from the mergeinfo set on the reintegrate
   target, not just subtrees of the target.  Expand and correct the comment
   for this block of code.

* subversion/tests/cmdline/merge_reintegrate_tests.py

  (reintegrate_creates_bogus_mergeinfo): Remove XFail decorator and comment.

  (no_source_subtree_mergeinfo): Adjust expected mergeinfo so as not to
   expect non-existent path-revs.

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1162974&r1=1162973&r2=1162974&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Mon Aug 29 20:13:32 2011
@@ -7850,19 +7850,38 @@ record_mergeinfo_for_dir_merge(svn_merge
 
           child_merges = apr_hash_make(iterpool);
 
-          /* If CHILD is the merge target we then know that the mergeinfo
-             described by MERGE_SOURCE_PATH:MERGED_RANGE->START-
-             MERGED_RANGE->END describes existent path-revs in the repository,
-             see normalize_merge_sources() and the global comment
+          /* The short story:
+
+             If we are describing a forward merge, then the naive mergeinfo
+             defined by MERGE_SOURCE_PATH:MERGED_RANGE->START:
+             MERGE_SOURCE_PATH:MERGED_RANGE->END may contain non-existent
+             path-revs or may describe other lines of history.  We must
+             remove these invalid portion(s) before recording mergeinfo
+             describing the merge.
+
+             The long story:
+
+             If CHILD is the merge target we know that
+             MERGE_SOURCE_PATH:MERGED_RANGE->END exists.  Further, if there
+             were no copies in MERGE_SOURCE_PATH's history going back to
+             RANGE->START then we know that
+             MERGE_SOURCE_PATH:MERGED_RANGE->START exists too and the two
+             describe and unbroken line of history and thus
+             MERGE_SOURCE_PATH:MERGED_RANGE->START:
+             MERGE_SOURCE_PATH:MERGED_RANGE->END is a valid description of
+             the merge -- see normalize_merge_sources() and the global comment
              'MERGEINFO MERGE SOURCE NORMALIZATION'.
 
-             If CHILD is a subtree of the merge target however, then no such
-             guarantee holds.  The mergeinfo described by
-             (MERGE_SOURCE_PATH + CHILD_REPOS_PATH):MERGED_RANGE->START-
-             MERGED_RANGE->END might contain merge sources which don't
-             exist or refer to unrelated lines of history. */
-          if (i > 0
-              && (!merge_b->record_only || merge_b->reintegrate_merge)
+             However, if there *was* a copy, then
+             MERGE_SOURCE_PATH:MERGED_RANGE->START doesn't exist or is
+             unrelated to MERGE_SOURCE_PATH:MERGED_RANGE->END.  Also, we
+             don't know if (MERGE_SOURCE_PATH:MERGED_RANGE->START)+1 through
+             (MERGE_SOURCE_PATH:MERGED_RANGE->END)-1 actually exist.
+
+             If CHILD is a subtree of the merge target, then nothing is
+             guaranteed beyond the fact that MERGE_SOURCE_PATH exists at
+             MERGED_RANGE->END. */
+          if ((!merge_b->record_only || merge_b->reintegrate_merge)
               && (!is_rollback))
             {
               svn_opt_revision_t peg_revision;

Modified: subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1162974&r1=1162973&r2=1162974&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_reintegrate_tests.py Mon Aug 29 20:13:32 2011
@@ -2201,7 +2201,6 @@ def two_URL_merge_removes_valid_mergeinf
 # Test for issue #3867 'reintegrate merges create mergeinfo for
 # non-existent paths'.
 @Issue(3867)
-@XFail()
 def reintegrate_creates_bogus_mergeinfo(sbox):
   "reintegrate creates bogus mergeinfo"
 
@@ -2230,11 +2229,11 @@ def reintegrate_creates_bogus_mergeinfo(
   svntest.main.run_svn(None, "cp", A_path_1, A_COPY_path)
   svntest.main.run_svn(None, "ci", "-m", "create a branch", wc_dir)
 
-  # Make a text edit on the branch pushing the repo to rev6
+  # Make a text edit on the branch pushing the repo to r5
   svntest.main.file_write(A_COPY_psi_path, "Branch edit.\n")
   svntest.main.run_svn(None, "ci", "-m", "branch edit", wc_dir)
 
-  # Sync the A_COPY with A in preparation for reintegrate
+  # Sync the A_COPY with A in preparation for reintegrate and commit as r6.
   svntest.main.run_svn(None, "up", wc_dir)
   svntest.main.run_svn(None, "merge", sbox.repo_url + "/A", A_COPY_path)
   svntest.main.run_svn(None, "ci", "-m", "sync A_COPY with A", wc_dir)
@@ -2244,10 +2243,6 @@ def reintegrate_creates_bogus_mergeinfo(
 
   # Reintegrate A_COPY to A.  The resulting merginfo on A should be
   # /A_COPY:4-6
-  #
-  # Currently this test fails because the resulting mergeinfo is /A_COPY:2-6.
-  # But A_COPY didn't exist unitl r4, so /A_COPY:2-3 describes merge source
-  # path-revs which don't exist.
   expected_output = wc.State(A_path, {
     'D/H/psi' : Item(status='U '),
     })
@@ -2393,7 +2388,7 @@ def no_source_subtree_mergeinfo(sbox):
   expected_elision = wc.State(os.path.join(wc_dir, 'A', 'B'), {
       })
   expected_disk = wc.State('', {
-      ''        : Item(props={SVN_PROP_MERGEINFO : '/A/B2:3-12'}),
+      ''        : Item(props={SVN_PROP_MERGEINFO : '/A/B2:4-12'}),
       'E'       : Item(),
       'E/alpha' : Item("AAA\n" +
                        "BBB\n" +