Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/externals_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/externals_tests.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/externals_tests.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/externals_tests.py Tue Sep 7 13:59:41 2010 @@ -1471,6 +1471,104 @@ def wc_repos_file_externals(sbox): None, None, None, None, None, True) +#---------------------------------------------------------------------- +def merge_target_with_externals(sbox): + "merge target with externals" + + # Test for a problem the plagued Subversion in the pre-1.7-single-DB world: + # Externals in a merge target would get meaningless explicit mergeinfo set + # on them. See http://svn.haxx.se/dev/archive-2010-08/0088.shtml + externals_test_setup(sbox) + wc_dir = sbox.wc_dir + repo_url = sbox.repo_url + + # Some paths we'll care about + A_path = os.path.join(wc_dir, "A") + A_branch_path = os.path.join(wc_dir, "A-branch") + A_gamma_branch_path = os.path.join(wc_dir, "A-branch", "D", "gamma") + + svntest.actions.run_and_verify_svn(None, None, [], + 'checkout', + repo_url, wc_dir) + + # Branch a...@1 to A-branch and make a simple text change on the latter in r8. + svntest.actions.run_and_verify_svn(None, None, [], 'copy', A_path + '@1', + A_branch_path) + svntest.actions.run_and_verify_svn(None, None, [], 'ci', + '-m', 'make a copy', wc_dir) + svntest.main.file_write(A_gamma_branch_path, "The new gamma!\n") + svntest.actions.run_and_verify_svn(None, None, [], 'ci', + '-m', 'branch edit', wc_dir) + svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir) + + # Merge r8 from A-branch back to A. There should be explicit mergeinfo + # only at the root of A; the externals should not get any. + svntest.actions.run_and_verify_svn(None, None, [], 'merge', '-c8', + repo_url + '/A-branch', A_path) + svntest.actions.run_and_verify_svn( + "Unexpected subtree mergeinfo created", + ["Properties on '" + A_path + "':\n", + " svn:mergeinfo\n", + " /A-branch:8\n"], + [], 'pg', svntest.main.SVN_PROP_MERGEINFO, '-vR', wc_dir) + +def update_modify_file_external(sbox): + "update that modifies a file external" + + sbox.build() + wc_dir = sbox.wc_dir + + # Setup A/external as file external to A/mu + externals_prop = "^/A/mu external\n" + change_external(sbox.ospath('A'), externals_prop) + expected_output = svntest.wc.State(wc_dir, { + 'A/external' : Item(status='E '), + }) + expected_disk = svntest.main.greek_state.copy() + expected_disk.add({ + 'A' : Item(props={'svn:externals':externals_prop}), + 'A/external' : Item("This is the file 'mu'.\n"), + }) + expected_status = svntest.actions.get_virginal_state(wc_dir, 2) + expected_status.add({ + 'A/external' : Item(status=' ', wc_rev='2', switched='X'), + }) + svntest.actions.run_and_verify_update(wc_dir, + expected_output, + expected_disk, + expected_status, + None, None, None, None, None, + True) + + # Modify A/mu + svntest.main.file_append(sbox.ospath('A/mu'), 'appended mu text') + expected_output = svntest.wc.State(wc_dir, { + 'A/mu' : Item(verb='Sending'), + }) + expected_status.tweak('A/mu', wc_rev=3) + svntest.actions.run_and_verify_commit(wc_dir, + expected_output, + expected_status, + None, + wc_dir) + + # Update to modify the file external, this asserts in update_editor.c + expected_output = svntest.wc.State(wc_dir, { + 'A/external' : Item(status='E '), + }) + expected_disk.tweak('A/mu', 'A/external', + contents=expected_disk.desc['A/mu'].contents + + 'appended mu text') + expected_status = svntest.actions.get_virginal_state(wc_dir, 3) + expected_status.add({ + 'A/external' : Item(status=' ', wc_rev='3', switched='X'), + }) + svntest.actions.run_and_verify_update(wc_dir, + expected_output, + expected_disk, + expected_status, + None, None, None, None, None, + True) ######################################################################## # Run the tests @@ -1501,6 +1599,8 @@ test_list = [ None, export_sparse_wc_with_externals, relegate_external, wc_repos_file_externals, + merge_target_with_externals, + XFail(update_modify_file_external), ] if __name__ == '__main__':
Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/merge_authz_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/merge_authz_tests.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/merge_authz_tests.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/merge_authz_tests.py Tue Sep 7 13:59:41 2010 @@ -82,13 +82,6 @@ def mergeinfo_and_skipped_paths(sbox): # 2) Destination of merge is inaccessible due to authz restrictions. # 3) Source *and* destination of merge is inaccessible due to authz # restrictions. - # 4) File path is versioned but is missing from disk due to OS deletion. - # This isn't technically part of issue #2893 but we handle this case - # and it didn't warrant its own test). - # - # Eventually we should also test(?): - # - # 5) Dir path is versioned but is missing from disk due to an OS deletion. sbox.build() wc_dir = sbox.wc_dir @@ -122,27 +115,20 @@ def mergeinfo_and_skipped_paths(sbox): omega_path = os.path.join(wc_restricted, "A_COPY", "D", "H", "omega") zeta_path = os.path.join(wc_dir, "A", "D", "H", "zeta") - # Restrict access to some more of the merge destination the - # old fashioned way, delete it via the OS. - ### TODO: Delete a versioned directory? - os.remove(omega_path) - # Merge r4:8 into the restricted WC's A_COPY. # # We expect A_COPY/B/E to be skipped because we can't access the source # and A_COPY/D/H/omega because it is missing. Since we have A_COPY/B/E # we should override it's inherited mergeinfo, giving it just what it - # inherited from A_COPY before the merge. omega is missing, but since - # it is a file we can record the fact that it is missing in its parent - # directory A_COPY/D/H. + # inherited from A_COPY before the merge. expected_output = wc.State(A_COPY_path, { 'D/G/rho' : Item(status='U '), 'D/H/psi' : Item(status='U '), + 'D/H/omega' : Item(status='U '), }) expected_mergeinfo_output = wc.State(A_COPY_path, { '' : Item(status=' U'), 'B/E' : Item(status=' U'), - 'D/H/omega' : Item(status=' U'), }) expected_elision_output = wc.State(A_COPY_path, { }) @@ -150,7 +136,7 @@ def mergeinfo_and_skipped_paths(sbox): '' : Item(status=' M', wc_rev=8), 'D/H/chi' : Item(status=' ', wc_rev=8), 'D/H/psi' : Item(status='M ', wc_rev=8), - 'D/H/omega' : Item(status='!M', wc_rev=8), + 'D/H/omega' : Item(status='M ', wc_rev=8), 'D/H' : Item(status=' ', wc_rev=8), 'D/G/pi' : Item(status=' ', wc_rev=8), 'D/G/rho' : Item(status='M ', wc_rev=8), @@ -171,9 +157,7 @@ def mergeinfo_and_skipped_paths(sbox): '' : Item(props={SVN_PROP_MERGEINFO : '/A:5-8'}), 'D/H/psi' : Item("New content"), 'D/H/chi' : Item("This is the file 'chi'.\n"), - # 'D/H/omega' : run_and_verify_merge() doesn't support checking - # the props on a missing path, so we do that - # manually (see below). + 'D/H/omega' : Item("New content"), 'D/H' : Item(), 'D/G/pi' : Item("This is the file 'pi'.\n"), 'D/G/rho' : Item("New content"), @@ -192,7 +176,6 @@ def mergeinfo_and_skipped_paths(sbox): }) expected_skip = wc.State(A_COPY_path, { 'B/E' : Item(), - 'D/H/omega' : Item(), }) svntest.actions.run_and_verify_merge(A_COPY_path, '4', '8', sbox.repo_url + '/A', None, @@ -205,10 +188,6 @@ def mergeinfo_and_skipped_paths(sbox): None, None, None, None, None, 1) - # Manually check the props on A_COPY/D/H/omega. - svntest.actions.run_and_verify_svn(None, ['\n'], [], - 'pg', SVN_PROP_MERGEINFO, omega_path) - # Merge r4:8 into the restricted WC's A_COPY_2. # # As before we expect A_COPY_2/B/E to be skipped because we can't access the Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tests.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tests.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tests.py Tue Sep 7 13:59:41 2010 @@ -1733,6 +1733,10 @@ def merge_into_missing(sbox): 'Q/baz' : Item(status='! ', wc_rev='3'), }) + # Use --ignore-ancestry because merge tracking aware merges raise an + # error when the merge target is missing subtrees due to OS-level + # deletes. + ### Need to real and dry-run separately since real merge notifies Q ### twice! svntest.actions.run_and_verify_merge(F_path, '1', '2', F_url, None, @@ -1743,23 +1747,20 @@ def merge_into_missing(sbox): expected_status, expected_skip, None, None, None, None, None, - 0, 0, '--dry-run', F_path) + 0, 0, '--dry-run', + '--ignore-ancestry', F_path) expected_status = wc.State(F_path, { - '' : Item(status=' M', wc_rev=1), - 'foo' : Item(status='!M', wc_rev=2), + '' : Item(status=' ', wc_rev=1), + 'foo' : Item(status='! ', wc_rev=2), 'Q' : Item(status='! ', wc_rev='?'), }) expected_mergeinfo_output = wc.State(F_path, { - '' : Item(status=' U'), - 'foo' : Item(status=' U'), # Mergeinfo is set on missing/obstructed files. }) if single_db: # Revision is known and we can record mergeinfo expected_status.tweak('Q', wc_rev='2', entry_rev='?') - expected_mergeinfo_output.add({'Q' : Item(status=' U')}) - # Missing data still available expected_status.add({ 'Q/R' : Item(status='! ', wc_rev='3'), 'Q/R/bar' : Item(status='! ', wc_rev='3'), @@ -1774,7 +1775,8 @@ def merge_into_missing(sbox): expected_status, expected_skip, None, None, None, None, None, - 0, 0) + 0, 0, + '--ignore-ancestry', F_path) # This merge fails when it attempts to descend into the missing # directory. That's OK, there is no real need to support merge into @@ -1789,8 +1791,8 @@ def merge_into_missing(sbox): # Check working copy is not locked. expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.add({ - 'A/B/F' : Item(status=' M', wc_rev=1), - 'A/B/F/foo' : Item(status='!M', wc_rev=2), + 'A/B/F' : Item(status=' ', wc_rev=1), + 'A/B/F/foo' : Item(status='! ', wc_rev=2), 'A/B/F/Q' : Item(status='! ', wc_rev='?'), }) if single_db: @@ -14995,6 +14997,7 @@ def skipped_files_get_correct_mergeinfo( # Some paths we'll care about A_COPY_path = os.path.join(wc_dir, "A_COPY") + H_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H") psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi") psi_path = os.path.join(wc_dir, "A", "D", "H", "psi") @@ -15022,15 +15025,21 @@ def skipped_files_get_correct_mergeinfo( [], 'merge', '-c3', sbox.repo_url + '/A', A_COPY_path) svntest.main.run_svn(None, 'commit', '-m', 'initial merge', wc_dir) - # Update WC to uniform revision and then delete, via the OS, A_COPY/D/H/psi - # and then merge all available revisions from A to A_COPY. A_COPY/D/H/psi - # should be reported as skipped and get explicit mergeinfo set on it - # reflecting what it previously inherited from A_COPY after the first - # merge, i.e. '/A/D/H/psi:3'. Issue #3440 occurred when empty mergeinfo - # was set on A_COPY/D/H/psi, making it appear that r3 was never merged. + # Update WC to uniform revision and then set the depth on A_COPY/D/H to + # empty. Then merge all available revisions from A to A_COPY. + # A_COPY/D/H/psi and A_COPY/D/H/omega are not present due to their + # parent's depth and should be reported as skipped. A_COPY/D/H should + # get explicit mergeinfo set on it reflecting what it previously inherited + # from A_COPY after the first merge, i.e. '/A/D/H:3', plus non-inheritable + # mergeinfo describing what was done during this merge, + # i.e. '/A/D/H:2*,4-8*'. + # + # Issue #3440 occurred when empty mergeinfo was set on A_COPY/D/H, making + # it appear that r3 was never merged. svntest.actions.run_and_verify_svn(None, ["At revision 8.\n"], [], 'up', wc_dir) - os.remove(psi_COPY_path) + svntest.actions.run_and_verify_svn(None, None, [], + 'up', '--set-depth=empty', H_COPY_path) expected_status = wc.State(A_COPY_path, { '' : Item(status=' M'), 'B' : Item(status=' '), @@ -15047,10 +15056,7 @@ def skipped_files_get_correct_mergeinfo( 'D/G/rho' : Item(status='M '), 'D/G/tau' : Item(status=' '), 'D/gamma' : Item(status=' '), - 'D/H' : Item(status=' '), - 'D/H/chi' : Item(status=' '), - 'D/H/psi' : Item(status='!M'), - 'D/H/omega' : Item(status='M '), + 'D/H' : Item(status=' M'), }) expected_status.tweak(wc_rev=8) expected_disk = wc.State('', { @@ -15069,71 +15075,18 @@ def skipped_files_get_correct_mergeinfo( 'D/G/rho' : Item("New content"), 'D/G/tau' : Item("This is the file 'tau'.\n"), 'D/gamma' : Item("This is the file 'gamma'.\n"), - 'D/H' : Item(), - 'D/H/chi' : Item("This is the file 'chi'.\n"), - #'D/H/psi' : Nothing here, this file was deleted via the OS. - 'D/H/omega' : Item("New content"), + 'D/H' : Item(props={SVN_PROP_MERGEINFO : '/A/D/H:2*,3,4-8*'}), }) expected_skip = wc.State(A_COPY_path, - {'D/H/psi' : Item()}) + {'D/H/psi' : Item(), + 'D/H/omega' : Item()}) expected_output = wc.State(A_COPY_path, {'B/E/beta' : Item(status='U '), - 'D/G/rho' : Item(status='U '), - 'D/H/omega' : Item(status='U '),}) - expected_mergeinfo_output = wc.State(A_COPY_path, { - '' : Item(status=' U'), - 'D/H/psi' : Item(status=' U'), - }) - expected_elision_output = wc.State(A_COPY_path, { - }) - svntest.actions.run_and_verify_merge(A_COPY_path, None, None, - sbox.repo_url + '/A', None, - expected_output, - expected_mergeinfo_output, - expected_elision_output, - expected_disk, - expected_status, - expected_skip, - None, None, None, None, None, - 1, 1) - # run_and_verify_merge cannot check the properties on A_COPY/D/H/psi - # since that file is not on disk, so we'll check the file's mergeinfo - # directly with svn propget. - svntest.actions.run_and_verify_svn( - 'Incorrect override mergeinfo set on skipped path', - ["/A/D/H/psi:3\n"], [], 'pg', 'svn:mergeinfo', psi_COPY_path) - - # Now test another aspect of issue #3440, that a skipped path with - # explicit mergeinfo doesn't get it's mergeinfo updated. - # - # First revert all changes to the WC and then merge -r2:6 from A/D/H/psi - # to A_COPY/D/H/psi, creating explicit mergeinfo of '/A/D/H/psi:3-6' on - # the latter. Commit this merge as r9 and then update the WC. - svntest.actions.run_and_verify_svn(None, None, [], - 'revert', '-R', wc_dir) - svntest.actions.run_and_verify_svn( - None, - expected_merge_output([[3,6]], - [' U ' + psi_COPY_path + '\n', - ' G ' + psi_COPY_path + '\n']), - [], 'merge', '-r2:6', sbox.repo_url + '/A/D/H/psi', psi_COPY_path) - svntest.main.run_svn(None, 'commit', '-m', - 'subtree merge to create explicit mergeinfo', - wc_dir) - svntest.actions.run_and_verify_svn(None, ["At revision 9.\n"], [], - 'up', wc_dir) - - # Remove A_COPY/D/H/psi again and then merge all available revisions - # from A to A_COPY. The results should be mostly similar to the - # previous merge we did above, execept that A_COPY/D/H/psi should not - # have it's mergeinfo changed. - os.remove(psi_COPY_path) - expected_status.tweak(wc_rev=9) - expected_status.tweak('D/H/psi', status='! ') - expected_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A:2-9'}) + 'D/G/rho' : Item(status='U ')}) expected_mergeinfo_output = wc.State(A_COPY_path, { - '' : Item(status=' U'), - 'D/H/psi' : Item(status=' U'), + '' : Item(status=' U'), + 'D/H' : Item(status=' G'), # ' G' because override mergeinfo gets set + # on this, the root of a 'missing' subtree. }) expected_elision_output = wc.State(A_COPY_path, { }) @@ -15148,16 +15101,6 @@ def skipped_files_get_correct_mergeinfo( None, None, None, None, None, 1, 1) - # run_and_verify_merge cannot check the properties on A_COPY/D/H/psi - # since that file is not on disk, so we'll check the file's mergeinfo - # directly with svn propget. Issue #3440 also occurred here, when an - # the missing file's mergeinfo was updated, making it appear that r2 - # and r7-9 were also merged into A_COPY/D/H/psi, which is clearly not - # the case since psi isn't present. - svntest.actions.run_and_verify_svn( - 'Mergeinfo on skipped path altered', - ["/A/D/H/psi:3-6\n"], [], 'pg', 'svn:mergeinfo', psi_COPY_path) - #---------------------------------------------------------------------- # Test for issue #3115 'Case only renames resulting from merges don't # work or break the WC on case-insensitive file systems'. @@ -15899,6 +15842,87 @@ def merge_into_locally_added_directory(s True, True, new_dir_path) sbox.simple_commit() +#---------------------------------------------------------------------- +# Test for issue #2915 'Handle mergeinfo for subtrees missing due to removal +# by non-svn command' +def merge_with_os_deleted_subtrees(sbox): + "merge tracking fails if target missing subtrees" + + # r1: Create a greek tree. + sbox.build() + wc_dir = sbox.wc_dir + + # r2 - r6: Copy A to A_COPY and then make some text changes under A. + set_up_branch(sbox) + + # Some paths we'll care about + A_COPY_path = os.path.join(wc_dir, "A_COPY") + C_COPY_path = os.path.join(wc_dir, "A_COPY", "C") + psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi") + mu_COPY_path = os.path.join(wc_dir, "A_COPY", "mu") + G_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G") + + # Remove several subtrees from disk. + svntest.main.safe_rmtree(C_COPY_path) + svntest.main.safe_rmtree(G_COPY_path) + os.remove(psi_COPY_path) + os.remove(mu_COPY_path) + + # Be sure the regex paths are properly escaped on Windows, see the + # note about "The Backslash Plague" in expected_merge_output(). + if sys.platform == 'win32': + re_sep = '\\\\' + else: + re_sep = os.sep + + # Common part of the expected error message for all cases we will test. + err_re = "svn: Merge tracking not allowed with missing subtrees; " + \ + "try restoring these items first:" + \ + "|(\n)" + \ + "|(.*apr_err.*\n)" # In case of debug build + + # Case 1: Infinite depth merge into infinite depth WC target. + # Every missing subtree under the target should be reported as missing. + missing = "|(.*A_COPY" + re_sep + "mu\n)" + \ + "|(.*A_COPY" + re_sep + "D" + re_sep + "G\n)" + \ + "|(.*A_COPY" + re_sep + "C\n)" + \ + "|(.*A_COPY" + re_sep + "D" + re_sep + "H" + re_sep + "psi\n)" + exit_code, out, err = svntest.actions.run_and_verify_svn( + "Missing subtrees should raise error", [], svntest.verify.AnyOutput, + 'merge', sbox.repo_url + '/A', A_COPY_path) + svntest.verify.verify_outputs("Merge failed but not in the way expected", + err, None, err_re + missing, None, + True) # Match *all* lines of stderr + + # Case 2: Immediates depth merge into infinite depth WC target. + # Only the two immediate children of the merge target should be reported + # as missing. + missing = "|(.*A_COPY" + re_sep + "mu\n)" + \ + "|(.*A_COPY" + re_sep + "C\n)" + exit_code, out, err = svntest.actions.run_and_verify_svn( + "Missing subtrees should raise error", [], svntest.verify.AnyOutput, + 'merge', sbox.repo_url + '/A', A_COPY_path, '--depth=immediates') + svntest.verify.verify_outputs("Merge failed but not in the way expected", + err, None, err_re + missing, None, True) + + # Case 3: Files depth merge into infinite depth WC target. + # Only the single file child of the merge target should be reported + # as missing. + missing = "|(.*A_COPY" + re_sep + "mu\n)" + exit_code, out, err = svntest.actions.run_and_verify_svn( + "Missing subtrees should raise error", [], svntest.verify.AnyOutput, + 'merge', sbox.repo_url + '/A', A_COPY_path, '--depth=files') + svntest.verify.verify_outputs("Merge failed but not in the way expected", + err, None, err_re + missing, None, True) + + # Case 4: Empty depth merge into infinite depth WC target. + # Only the...oh, wait, the target is present and that is as deep + # as the merge goes, so this merge should succeed! + svntest.actions.run_and_verify_svn( + "Depth empty merge should succeed as long at the target is present", + svntest.verify.AnyOutput, [], 'merge', sbox.repo_url + '/A', + A_COPY_path, '--depth=empty') + ######################################################################## # Run the tests @@ -16087,6 +16111,7 @@ test_list = [ None, copy_causes_phantom_eol_conflict, merge_into_locally_added_file, merge_into_locally_added_directory, + merge_with_os_deleted_subtrees, ] if __name__ == '__main__': Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tree_conflict_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tree_conflict_tests.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tree_conflict_tests.py Tue Sep 7 13:59:41 2010 @@ -1272,16 +1272,28 @@ def tree_conflicts_merge_edit_onto_missi # local tree missing (via shell delete), incoming leaf edit + # Note: In 1.7 merge tracking aware merges raise an error if the + # merge target has subtrees missing due to a shell delete. To + # preserve the original intent of this test we'll run the merge + # with the --ignore-ancestry option, which neither considers nor + # records mergeinfo. With this option the merge should "succeed" + # while skipping the missing paths. Of course with no mergeinfo + # recorded and everything skipped, there is nothing to commit, so + # unlike most of the tree conflict tests we don't bother with the + # final commit step. + sbox.build() expected_output = wc.State('', { }) expected_disk = disk_after_tree_del + # Don't expect any mergeinfo property changes because we run + # the merge with the --ignore-ancestry option. expected_status = svntest.wc.State('', { - '' : Item(status=' M', wc_rev=3), + '' : Item(status=' ', wc_rev=3), 'F' : Item(status=' ', wc_rev=3), - 'F/alpha' : Item(status='!M', wc_rev=3), + 'F/alpha' : Item(status='! ', wc_rev=3), 'D' : Item(status=' ', wc_rev=3), 'D/D1' : Item(status='! ', wc_rev='?'), 'DF' : Item(status=' ', wc_rev=3), @@ -1327,18 +1339,7 @@ def tree_conflicts_merge_edit_onto_missi expected_disk, expected_status, expected_skip, - - ### This should not be happening! - ### The commit succeeds (it only commits mergeinfo). - ### But then the work queue freaks out while trying to install - ### F/alpha into the WC, because F/alpha is missing from disk. - ### We end up with a working copy that cannot be cleaned up. - ### To make this test pass for now we'll expect this error. - ### When the problem is fixed this test will start to fail - ### and should be adjusted. - commit_block_string=".*Error bumping revisions post-commit", - - ) ], False) + ) ], False, do_commit_conflicts=False, ignore_ancestry=True) #---------------------------------------------------------------------- def tree_conflicts_merge_del_onto_missing(sbox): @@ -1346,16 +1347,28 @@ def tree_conflicts_merge_del_onto_missin # local tree missing (via shell delete), incoming leaf edit + # Note: In 1.7 merge tracking aware merges raise an error if the + # merge target has subtrees missing due to a shell delete. To + # preserve the original intent of this test we'll run the merge + # with the --ignore-ancestry option, which neither considers nor + # records mergeinfo. With this option the merge should "succeed" + # while skipping the missing paths. Of course with no mergeinfo + # recorded and everything skipped, there is nothing to commit, so + # unlike most of the tree conflict tests we don't bother with the + # final commit step. + sbox.build() expected_output = wc.State('', { }) expected_disk = disk_after_tree_del + # Don't expect any mergeinfo property changes because we run + # the merge with the --ignore-ancestry option. expected_status = svntest.wc.State('', { - '' : Item(status=' M', wc_rev=3), + '' : Item(status=' ', wc_rev=3), 'F' : Item(status=' ', wc_rev=3), - 'F/alpha' : Item(status='!M', wc_rev=3), + 'F/alpha' : Item(status='! ', wc_rev=3), 'D' : Item(status=' ', wc_rev=3), 'D/D1' : Item(status='! ', wc_rev='?'), 'DF' : Item(status=' ', wc_rev=3), @@ -1401,18 +1414,7 @@ def tree_conflicts_merge_del_onto_missin expected_disk, expected_status, expected_skip, - - ### This should not be happening! - ### The commit succeeds (it only commits mergeinfo). - ### But then the work queue freaks out while trying to install - ### F/alpha into the WC, because F/alpha is missing from disk. - ### We end up with a working copy that cannot be cleaned up. - ### To make this test pass for now we'll expect this error. - ### When the problem is fixed this test will start to fail - ### and should be adjusted. - commit_block_string=".*Error bumping revisions post-commit", - - ) ], False) + ) ], False, do_commit_conflicts=False, ignore_ancestry=True) #---------------------------------------------------------------------- def merge_replace_setup(sbox): Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/revert_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/revert_tests.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/revert_tests.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/revert_tests.py Tue Sep 7 13:59:41 2010 @@ -851,29 +851,37 @@ def status_of_missing_dir_after_revert_r os.path.join(G_path, 'alpha'), os.path.join(G_path, 'beta')] + if svntest.main.wc_is_singledb(wc_dir): + # These nodes are not lost in single-db + revert_paths += [ os.path.join(G_path, 'pi'), + os.path.join(G_path, 'rho'), + os.path.join(G_path, 'tau')] + expected_output = svntest.verify.UnorderedOutput([ "Reverted '%s'\n" % path for path in revert_paths]) svntest.actions.run_and_verify_svn(None, expected_output, [], "revert", "-R", G_path) - ### GS (Oct 11): this is stupid. after a revert, there should be - ### *NO* status whatsoever. ugh. this status behavior - ### has been twiddled over the 1.6/1.7 dev cycle, but - ### it "should" just disappear. - ### Is it a bug that we'd need to run revert twice to finish the job? + # Revert leaves these added nodes as unversioned expected_output = svntest.verify.UnorderedOutput( - ["A " + os.path.join(G_path, "pi") + "\n", - "A " + os.path.join(G_path, "rho") + "\n", - "A " + os.path.join(G_path, "tau") + "\n"]) + ["? " + os.path.join(G_path, "pi") + "\n", + "? " + os.path.join(G_path, "rho") + "\n", + "? " + os.path.join(G_path, "tau") + "\n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], "status", wc_dir) svntest.main.safe_rmtree(G_path) - expected_output = svntest.verify.UnorderedOutput( - ["! " + G_path + "\n"]) + if svntest.main.wc_is_singledb(wc_dir): + expected_output = svntest.verify.UnorderedOutput( + ["! " + G_path + "\n", + "! " + os.path.join(G_path, "alpha") + "\n", + "! " + os.path.join(G_path, "beta") + "\n"]) + else: + expected_output = svntest.verify.UnorderedOutput( + ["! " + G_path + "\n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], "status", wc_dir) @@ -1054,8 +1062,7 @@ test_list = [ None, revert_propdel__file, revert_replaced_with_history_file_1, status_of_missing_dir_after_revert, - Wimp("revert behavior needs better definition", - status_of_missing_dir_after_revert_replaced_with_history_dir), + status_of_missing_dir_after_revert_replaced_with_history_dir, revert_replaced_with_history_file_2, revert_tree_conflicts_in_updated_files, revert_add_over_not_present_dir, Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/svntest/actions.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/svntest/actions.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/svntest/actions.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/svntest/actions.py Tue Sep 7 13:59:41 2010 @@ -2680,7 +2680,9 @@ def deep_trees_run_tests_scheme_for_swit def deep_trees_run_tests_scheme_for_merge(sbox, greater_scheme, - do_commit_local_changes): + do_commit_local_changes, + do_commit_conflicts=True, + ignore_ancestry=False): """ Runs a given list of tests for conflicts occuring at a merge operation. @@ -2714,12 +2716,14 @@ def deep_trees_run_tests_scheme_for_merg Then, in effect, the local changes are committed as well. 8) In each test case subdir, the "incoming" subdir is merged into the - "local" subdir. - This causes conflicts between the "local" state in the working - copy and the "incoming" state from the incoming subdir. - - 9) A commit is performed in each separate container, to verify - that each tree-conflict indeed blocks a commit. + "local" subdir. If ignore_ancestry is True, then the merge is done + with the --ignore-ancestry option, so mergeinfo is neither considered + nor recorded. This causes conflicts between the "local" state in the + working copy and the "incoming" state from the incoming subdir. + + 9) If do_commit_conflicts is True, then a commit is performed in each + separate container, to verify that each tree-conflict indeed blocks + a commit. The sbox parameter is just the sbox passed to a test function. No need to call sbox.build(), since it is called (once) within this function. @@ -2851,10 +2855,15 @@ def deep_trees_run_tests_scheme_for_merg x_skip.copy() x_skip.wc_dir = local + varargs = (local,) + if ignore_ancestry: + varargs = varargs + ('--ignore-ancestry',) + run_and_verify_merge(local, None, None, incoming, None, x_out, None, None, x_disk, None, x_skip, - error_re_string = test_case.error_re_string, - dry_run = False) + test_case.error_re_string, + None, None, None, None, + False, False, *varargs) run_and_verify_unquiet_status(local, x_status) except: print("ERROR IN: Tests scheme for merge: " @@ -2864,21 +2873,22 @@ def deep_trees_run_tests_scheme_for_merg # 9) Verify that commit fails. - for test_case in greater_scheme: - try: - local = j(wc_dir, test_case.name, 'local') - - x_status = test_case.expected_status - if x_status != None: - x_status.copy() - x_status.wc_dir = local - - run_and_verify_commit(local, None, x_status, - test_case.commit_block_string, - local) - except: - print("ERROR IN: Tests scheme for merge: " - + "while checking commit-blocking in '%s'" % test_case.name) - raise + if do_commit_conflicts: + for test_case in greater_scheme: + try: + local = j(wc_dir, test_case.name, 'local') + + x_status = test_case.expected_status + if x_status != None: + x_status.copy() + x_status.wc_dir = local + + run_and_verify_commit(local, None, x_status, + test_case.commit_block_string, + local) + except: + print("ERROR IN: Tests scheme for merge: " + + "while checking commit-blocking in '%s'" % test_case.name) + raise Modified: subversion/branches/javahl-ra/subversion/tests/cmdline/update_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/cmdline/update_tests.py?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/cmdline/update_tests.py (original) +++ subversion/branches/javahl-ra/subversion/tests/cmdline/update_tests.py Tue Sep 7 13:59:41 2010 @@ -5683,6 +5683,44 @@ def add_moved_file_has_props2(sbox): svntest.actions.run_and_verify_status(wc_dir, expected_status) +# A regression test for a 1.7-dev crash upon updating a WC to a different +# revision when it contained an excluded dir. +def update_with_excluded_subdir(sbox): + """update with an excluded subdir""" + sbox.build() + + wc_dir = sbox.wc_dir + + G = os.path.join(os.path.join(wc_dir, 'A', 'D', 'G')) + + # Make the directory 'G' excluded. + expected_output = svntest.wc.State(wc_dir, { + 'A/D/G' : Item(status='D '), + }) + expected_disk = svntest.main.greek_state.copy() + expected_disk.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau') + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau') + svntest.actions.run_and_verify_update(wc_dir, expected_output, + expected_disk, expected_status, + None, None, None, None, None, False, + '--set-depth=exclude', G) + + # Commit a new revision so there is something to update to. + svntest.main.run_svn(None, 'mkdir', '-m', '', sbox.repo_url + '/New') + + # Test updating the WC. + expected_output = svntest.wc.State(wc_dir, { + 'New' : Item(status='A ') }) + expected_disk.add({ + 'New' : Item() }) + expected_status.add({ + 'New' : Item(status=' ') }) + expected_status.tweak(wc_rev=2) + svntest.actions.run_and_verify_update(wc_dir, expected_output, + expected_disk, expected_status) + + ####################################################################### # Run the tests @@ -5753,6 +5791,7 @@ test_list = [ None, mergeinfo_updates_merge_with_local_mods, add_moved_file_has_props, XFail(add_moved_file_has_props2), + update_with_excluded_subdir, ] if __name__ == '__main__': Modified: subversion/branches/javahl-ra/subversion/tests/libsvn_wc/db-test.c URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/tests/libsvn_wc/db-test.c?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/subversion/tests/libsvn_wc/db-test.c (original) +++ subversion/branches/javahl-ra/subversion/tests/libsvn_wc/db-test.c Tue Sep 7 13:59:41 2010 @@ -324,6 +324,9 @@ create_fake_wc(const char *subdir, int f #ifdef SVN_WC__NODE_DATA statements[STMT_CREATE_NODE_DATA], #endif +#ifdef SVN_WC__NODES + statements[STMT_CREATE_NODES], +#endif TESTING_DATA, NULL }; @@ -1288,8 +1291,7 @@ test_global_relocate(apr_pool_t *pool) SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE); /* Test relocating to a repos not existant in the db */ - SVN_ERR(svn_wc__db_global_relocate(db, local_abspath, ROOT_THREE, TRUE, - pool)); + SVN_ERR(svn_wc__db_global_relocate(db, local_abspath, ROOT_THREE, pool)); SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, &repos_relpath, &repos_root_url, &repos_uuid, NULL, NULL, NULL, NULL, Modified: subversion/branches/javahl-ra/tools/dev/unix-build/Makefile.svn URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/tools/dev/unix-build/Makefile.svn?rev=993368&r1=993367&r2=993368&view=diff ============================================================================== --- subversion/branches/javahl-ra/tools/dev/unix-build/Makefile.svn (original) +++ subversion/branches/javahl-ra/tools/dev/unix-build/Makefile.svn Tue Sep 7 13:59:41 2010 @@ -37,7 +37,8 @@ GNU_ICONV_VER = 1.13.1 APR_UTIL_VER = 1.3.9 HTTPD_VER = 2.2.15 NEON_VER = 0.29.3 -SERF_VER = 0.6.x +SERF_VER = 0.7.x +CYRUS_SASL_VER = 2.1.23 SQLITE_VER = 3.6.23.1 BDB_DIST = db-$(BDB_VER).tar.gz @@ -46,6 +47,7 @@ GNU_ICONV_DIST = libiconv-$(GNU_ICONV_VE NEON_DIST = neon-$(NEON_VER).tar.gz #SERF_DIST = serf-$(SERF_VER).tar.gz SQLITE_DIST = sqlite-$(SQLITE_VER).tar.gz +CYRUS_SASL_DIST = cyrus-sasl-$(CYRUS_SASL_VER).tar.gz HTTPD_DIST = httpd-$(HTTPD_VER).tar.bz2 DISTFILES = $(DISTDIR)/$(NEON_DIST) \ @@ -53,7 +55,8 @@ DISTFILES = $(DISTDIR)/$(NEON_DIST) \ $(DISTDIR)/$(SQLITE_DIST) \ $(DISTDIR)/$(HTTPD_DIST) \ $(DISTDIR)/$(APR_ICONV_DIST) \ - $(DISTDIR)/$(GNU_ICONV_DIST) + $(DISTDIR)/$(GNU_ICONV_DIST) \ + $(DISTDIR)/$(CYRUS_SASL_DIST) FETCH_CMD = wget -c @@ -68,6 +71,7 @@ NEON_URL = http://webdav.org/neon/$(NEON #SERF_URL = http://serf.googlecode.com/files/$(SERF_DIST) SERF_URL = http://serf.googlecode.com/svn/branches/$(SERF_VER) SQLITE_URL = http://www.sqlite.org/$(SQLITE_DIST) +CYRUS_SASL_URL = ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/$(CYRUS_SASL_DIST) BDB_SRCDIR = $(SRCDIR)/db-$(BDB_VER) APR_SRCDIR = $(SRCDIR)/apr-$(APR_VER) @@ -78,6 +82,7 @@ HTTPD_SRCDIR = $(SRCDIR)/httpd-$(HTTPD_V NEON_SRCDIR = $(SRCDIR)/neon-$(NEON_VER) SERF_SRCDIR = $(SRCDIR)/serf-$(SERF_VER) SQLITE_SRCDIR = $(SRCDIR)/sqlite-$(SQLITE_VER) +CYRUS_SASL_SRCDIR = $(SRCDIR)/cyrus-sasl-$(CYRUS_SASL_VER) SVN_SRCDIR = $(SVN_WC) BDB_OBJDIR = $(OBJDIR)/db-$(BDB_VER) @@ -89,6 +94,7 @@ HTTPD_OBJDIR = $(OBJDIR)/httpd-$(HTTPD_V NEON_OBJDIR = $(OBJDIR)/neon-$(NEON_VER) SERF_OBJDIR = $(OBJDIR)/serf-$(SERF_VER) SQLITE_OBJDIR = $(OBJDIR)/sqlite-$(SQLITE_VER) +CYRUS_SASL_OBJDIR = $(OBJDIR)/cyrus-sasl-$(CYRUS_SASL_VER) SVN_OBJDIR = $(OBJDIR)/$(SVN_REL_WC) # Tweak this for out-of-tree builds. Note that running individual @@ -103,16 +109,17 @@ svn_builddir ?=$(SVN_WC) .PHONY: all reset clean nuke all: dirs-create bdb-install apr-install iconv-install apr-util-install \ - httpd-install neon-install serf-install sqlite-install svn-install \ - svn-bindings-install + httpd-install neon-install serf-install sqlite-install \ + cyrus-sasl-install svn-install svn-bindings-install # Use these to start a build from the beginning. reset: dirs-reset bdb-reset apr-reset iconv-reset apr-util-reset \ - httpd-reset neon-reset serf-reset sqlite-reset svn-reset + httpd-reset neon-reset serf-reset sqlite-reset cyrus-sasl-reset \ + svn-reset # Use to save disc space. clean: bdb-clean apr-clean iconv-clean apr-util-clean httpd-clean \ - neon-clean serf-clean svn-clean + neon-clean serf-clean cyrus-sasl-clean svn-clean # Nukes everything (including installed binaries!) # Use this to start ALL OVER AGAIN! Use with caution! @@ -656,6 +663,56 @@ $(SQLITE_OBJDIR)/.installed: $(SQLITE_OB touch $@ ####################################################################### +# cyrus-sasl +####################################################################### + +cyrus-sasl-retrieve: $(CYRUS_SASL_OBJDIR)/.retrieved +cyrus-sasl-configure: $(CYRUS_SASL_OBJDIR)/.configured +cyrus-sasl-compile: $(CYRUS_SASL_OBJDIR)/.compiled +cyrus-sasl-install: $(CYRUS_SASL_OBJDIR)/.installed +cyrus-sasl-reset: + $(foreach f, .retrieved .configured .compiled .installed, \ + rm -f $(CYRUS_SASL_OBJDIR)/$(f);) + +cyrus-sasl-clean: + -(cd $(CYRUS_SASL_OBJDIR) && make clean) + +# fetch distfile for cyrus-sasl +$(DISTDIR)/$(CYRUS_SASL_DIST): + cd $(DISTDIR) && $(FETCH_CMD) $(CYRUS_SASL_URL) + +# retrieve cyrus-sasl +$(CYRUS_SASL_OBJDIR)/.retrieved: $(DISTDIR)/$(CYRUS_SASL_DIST) + [ -d $(CYRUS_SASL_OBJDIR) ] || mkdir -p $(CYRUS_SASL_OBJDIR) + tar -C $(SRCDIR) -zxf $(DISTDIR)/$(CYRUS_SASL_DIST) + touch $@ + +# configure cyrus-sasl +$(CYRUS_SASL_OBJDIR)/.configured: $(CYRUS_SASL_OBJDIR)/.retrieved + cd $(CYRUS_SASL_OBJDIR) \ + && env CFLAGS="-g" $(CYRUS_SASL_SRCDIR)/configure \ + --with-dbpath=$(PREFIX)/cyrus-sasl/etc/sasldb2 \ + --with-plugindir=$(PREFIX)/cyrus-sasl/lib/sasl2 \ + --with-configdir=$(PREFIX)/cyrus-sasl/lib/sasl2 \ + --with-bdb-libdir=$(PREFIX)/bdb/lib \ + --with-bdb-incdir=$(PREFIX)/bdb/include \ + --with-dblib=berkeley \ + --with-sqlite=$(PREFIX)/sqlite \ + --prefix=$(PREFIX)/cyrus-sasl + touch $@ + +# compile cyrus-sasl +$(CYRUS_SASL_OBJDIR)/.compiled: $(CYRUS_SASL_OBJDIR)/.configured + (cd $(CYRUS_SASL_OBJDIR) && make) + touch $@ + +# install cyrus-sasl +$(CYRUS_SASL_OBJDIR)/.installed: $(CYRUS_SASL_OBJDIR)/.compiled + (cd $(CYRUS_SASL_OBJDIR) && make install) + touch $@ + + +####################################################################### # svn ####################################################################### @@ -746,7 +803,7 @@ $(SVN_OBJDIR)/.configured: $(SVN_OBJDIR) --with-serf="$(PREFIX)/serf" \ --with-sqlite="$(PREFIX)/sqlite" \ --with-berkeley-db="$(BDB_FLAG)" \ - --with-sasl="no" \ + --with-sasl="$(PREFIX)/cyrus-sasl" \ --with-ruby-sitedir="$(SVN_PREFIX)/lib/ruby/site_ruby" \ --disable-mod-activation \ $(JAVAHL_FLAG)
