Index: subversion/tests/cmdline/merge_tests.py =================================================================== --- subversion/tests/cmdline/merge_tests.py (revision 22500) +++ subversion/tests/cmdline/merge_tests.py (working copy) @@ -3857,12 +3857,10 @@ expected_backup_status, expected_backup_skip) -def avoid_repeated_merge_using_inherited_merge_info(sbox): - "use inherited merge info to avoid repeated merge" +def create_deep_trees(wc_dir): + """Create A/B/F/E by moving A/B/E to A/B/F/E, copy A/B to + A/copy-of-B, update the WC to r3, and return the expected status.""" - sbox.build() - wc_dir = sbox.wc_dir - A_path = os.path.join(wc_dir, 'A') A_B_path = os.path.join(A_path, 'B') A_B_E_path = os.path.join(A_B_path, 'E') @@ -3909,12 +3907,30 @@ expected_status, None, None, None, None, None, wc_dir) + # Bring the entire WC up to date with rev 3, and return its status. + svntest.actions.run_and_verify_svn(None, None, [], 'update', wc_dir) + expected_status.tweak(wc_rev=3) + return expected_status + +def avoid_repeated_merge_using_inherited_merge_info(sbox): + "use inherited merge info to avoid repeated merge" + + sbox.build() + wc_dir = sbox.wc_dir + + A_path = os.path.join(wc_dir, 'A') + A_B_path = os.path.join(A_path, 'B') + A_B_E_path = os.path.join(A_B_path, 'E') + A_B_F_path = os.path.join(A_B_path, 'F') + copy_of_B_path = os.path.join(A_path, 'copy-of-B') + + # Create a deeper directory structure, bringing the WC to rev 3. + expected_status = create_deep_trees(wc_dir) + # Edit alpha and commit it, creating revision 4. alpha_path = os.path.join(A_B_F_path, 'E', 'alpha') new_content_for_alpha = 'new content to alpha\n' - fp = open(alpha_path, 'w') - fp.write(new_content_for_alpha) - fp.close() + svntest.main.file_write(alpha_path, new_content_for_alpha) expected_output = svntest.wc.State(wc_dir, { 'A/B/F/E/alpha' : Item(verb='Sending'), @@ -4019,6 +4035,153 @@ finally: os.chdir(saved_cwd) +def avoid_repeated_merge_on_subtree_with_merge_info(sbox): + "use subtree's merge info to avoid repeated merge" + + sbox.build() + wc_dir = sbox.wc_dir + + A_path = os.path.join(wc_dir, 'A') + A_B_path = os.path.join(A_path, 'B') + A_B_E_path = os.path.join(A_B_path, 'E') + A_B_F_path = os.path.join(A_B_path, 'F') + A_B_F_E_path = os.path.join(A_B_F_path, 'E') + copy_of_B_path = os.path.join(A_path, 'copy-of-B') + + # Create a deeper directory structure, bringing the WC to rev 3. + expected_status = create_deep_trees(wc_dir) + + # Edit alpha and commit it, creating revision 4. + alpha_path = os.path.join(A_B_F_E_path, 'alpha') + new_content_for_alpha = 'new content to alpha\n' + svntest.main.file_write(alpha_path, new_content_for_alpha) + + expected_output = svntest.wc.State(wc_dir, { + 'A/B/F/E/alpha' : Item(verb='Sending'), + }) + expected_status.tweak('A/B/F/E/alpha', wc_rev=4) + svntest.actions.run_and_verify_commit(wc_dir, expected_output, + expected_status, None, + None, None, None, None, wc_dir) + + copy_of_B_F_E_path = os.path.join(copy_of_B_path, 'F', 'E') + + # Search for the comment entitled "The Merge Kluge" elsewhere in + # this file, to understand why we shorten and chdir() below. + short_copy_of_B_F_E_path = shorten_path_kludge(copy_of_B_F_E_path) + + # Merge changes to alpha from rev 4. + expected_output = wc.State(short_copy_of_B_F_E_path, { + 'alpha' : Item(status='U '), + }) + + expected_status = wc.State(short_copy_of_B_F_E_path, { + '' : Item(status=' M', wc_rev=3), + 'alpha' : Item(status='M ', wc_rev=3), + 'beta' : Item(status=' ', wc_rev=3), + }) + + expected_disk = wc.State('', { + '' : Item(props={SVN_PROP_MERGE_INFO : '/A/B/F/E:4'}), + 'alpha' : Item(new_content_for_alpha), + 'beta' : Item("This is the file 'beta'.\n"), + }) + + expected_skip = wc.State(short_copy_of_B_F_E_path, { }) + saved_cwd = os.getcwd() + try: + os.chdir(svntest.main.work_dir) + svntest.actions.run_and_verify_merge(short_copy_of_B_F_E_path, '3', '4', + sbox.repo_url + '/A/B/F/E', + expected_output, + expected_disk, + expected_status, + expected_skip, + None, + None, + None, + None, + None, 1) + finally: + os.chdir(saved_cwd) + + expected_output = svntest.wc.State(copy_of_B_F_E_path, { + '' : Item(verb='Sending'), + 'alpha' : Item(verb='Sending'), + }) + + # Commit the result of the merge, creating revision 5. + svntest.actions.run_and_verify_commit(short_copy_of_B_F_E_path, + expected_output, None, None, + None, None, None, None, wc_dir) + + # Edit A/B/F/E/alpha and commit it, creating revision 6. + new_content_for_alpha = 'new content to alpha\none more line\n' + svntest.main.file_write(alpha_path, new_content_for_alpha) + + expected_output = svntest.wc.State(A_B_F_E_path, { + 'alpha' : Item(verb='Sending'), + }) + + expected_status = wc.State(A_B_F_E_path, { + '' : Item(status=' ', wc_rev=3), + 'alpha' : Item(status=' ', wc_rev=6), + 'beta' : Item(status=' ', wc_rev=3), + }) + + svntest.actions.run_and_verify_commit(A_B_F_E_path, expected_output, + expected_status, None, + None, None, None, None, wc_dir) + + # Search for the comment entitled "The Merge Kluge" elsewhere in + # this file, to understand why we shorten and chdir() below. + short_copy_of_B_path = shorten_path_kludge(copy_of_B_path) + + # Update the WC to bring /A/copy_of_B from rev 3 to rev 6. + # Without this update expected_status tree would be cumbersome to + # understand. + svntest.actions.run_and_verify_svn(None, None, [], 'update', wc_dir) + + # Merge changes from rev 6 of B (to alpha) into copy_of_B. + expected_output = wc.State(short_copy_of_B_path, {}) + expected_status = wc.State(short_copy_of_B_path, { + # When we merge multiple sub-targets, we record merge info on each + # child. In this particular case, as we don't have a successful + # merge, there's no change in the WC. + '' : Item(status=' ', wc_rev=6), + 'F/E' : Item(status=' ', wc_rev=6), + 'F/E/alpha' : Item(status=' ', wc_rev=6), + 'F/E/beta' : Item(status=' ', wc_rev=6), + 'lambda' : Item(status=' ', wc_rev=6), + 'F' : Item(status=' ', wc_rev=6), + }) + expected_disk = wc.State('', { + '' : Item(), + 'F/E' : Item(props={SVN_PROP_MERGE_INFO : '/A/B:4-6'}), + 'F/E/alpha' : Item(new_content_for_alpha), + 'F/E/beta' : Item("This is the file 'beta'.\n"), + 'F' : Item(), + 'lambda' : Item("This is the file 'lambda'.\n") + }) + expected_skip = wc.State(short_copy_of_B_path, { }) + saved_cwd = os.getcwd() + try: + os.chdir(svntest.main.work_dir) + svntest.actions.run_and_verify_merge(short_copy_of_B_path, '3', '6', + sbox.repo_url + \ + '/A/B', + expected_output, + expected_disk, + expected_status, + expected_skip, + None, + None, + None, + None, + None, 1) + finally: + os.chdir(saved_cwd) + ######################################################################## # Run the tests @@ -4064,6 +4227,7 @@ merge_conflict_markers_matching_eol, XFail(merge_eolstyle_handling), avoid_repeated_merge_using_inherited_merge_info, + XFail(avoid_repeated_merge_on_subtree_with_merge_info), ] if __name__ == '__main__':