def non_inheritable_mergeinfo(sbox): "non-inheritable mergeinfo shows as merged" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_COPY_path = os.path.join(wc_dir, "A_COPY") D_COPY_path = os.path.join(wc_dir, "A_COPY", "D") rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho") # Update the WC, then merge r4 from A to A_COPY and r6 from A to A_COPY # at --depth empty and commit the merges as r7. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], 'up', wc_dir) expected_status.tweak(wc_rev=6) svntest.actions.run_and_verify_svn( None, expected_merge_output([[4]], [ 'U ' + rho_COPY_path + '\n', ' U ' + A_COPY_path + '\n', ]), [], 'merge', '-c4', sbox.repo_url + '/A', A_COPY_path) svntest.actions.run_and_verify_svn( None, expected_merge_output([[6]], ' G ' + A_COPY_path + '\n'), [], 'merge', '-c6', sbox.repo_url + '/A', A_COPY_path, '--depth', 'empty') expected_output = wc.State(wc_dir, { 'A_COPY': Item(verb='Sending'), 'A_COPY/D/G/rho': Item(verb='Sending'), }) expected_status.tweak('A_COPY', 'A_COPY/D/G/rho', wc_rev=7) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) # Update the WC a last time to ensure full inheritance. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(7), [], 'up', wc_dir) # Despite being non-inheritable, r6 should still show as merged to A_COPY # and not eligible for merging. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ['4', '6*'], sbox.repo_url + '/A', A_COPY_path, '--show-revs', 'merged') svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ['3', '5', '6*'], sbox.repo_url + '/A', A_COPY_path, '--show-revs', 'eligible') # But if we drop down to A_COPY/D, r6 should show as eligible because it # was only merged into A_COPY, no deeper. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ['4'], sbox.repo_url + '/A/D', D_COPY_path, '--show-revs', 'merged') svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ['3', '6'], sbox.repo_url + '/A/D', D_COPY_path, '--show-revs', 'eligible')
def expected_automatic_merge_output(target, expect_3ways): """Calculate the expected output.""" # (This is rather specific to the current implementation.) # Match a notification for each rev-range. if expect_3ways: rev_ranges = [] for base, right in expect_3ways: if base[0] == right[0]: base_rev = int(base[1:]) right_rev = int(right[1:]) rev_ranges += [(base_rev + 1, right_rev)]; else: rev_ranges = None # Match any content modifications; but not of the root of the branch # because we don't intentionally modify the branch root node in most # tests and we don't want to accidentally overlook a mergeinfo change. lines = ["(A |D |[UG] | [UG]|[UG][UG]) " + target + os.path.sep + ".*\n"] # Match mergeinfo changes. (### Subtrees are not yet supported here.) lines += [" [UG] " + target + "\n"] # At the moment, the automatic merge code sometimes says 'Merging # differences between repository URLs' and sometimes 'Merging r3 through # r5', but it's not trivial to predict which, so expect either form. lines += ["--- Merging .* into '%s':\n" % (target,), "--- Recording mergeinfo for merge .* into '%s':\n" % (target,)] return expected_merge_output(rev_ranges, lines, target=target)
def expected_symmetric_merge_output(target, expect_3ways): """Calculate the expected output.""" # (This is rather specific to the current implementation.) # Match a notification for each rev-range. if expect_3ways: rev_ranges = [] for base, right in expect_3ways: if base[0] == right[0]: base_rev = int(base[1:]) right_rev = int(right[1:]) rev_ranges += [(base_rev + 1, right_rev)] else: rev_ranges = None # Match any content modifications; but not of the root of the branch # because we don't intentionally modify the branch root node in most # tests and we don't want to accidentally overlook a mergeinfo change. lines = ["(A |D |[UG] | [UG]|[UG][UG]) " + target + os.path.sep + ".*\n"] # Match mergeinfo changes. (### Subtrees are not yet supported here.) lines += [" [UG] " + target + "\n"] # At the moment, the symmetric merge code sometimes says 'Merging # differences between repository URLs' and sometimes 'Merging r3 through # r5', but it's not trivial to predict which, so expect either form. lines += [ "--- Merging .* into '%s':\n" % (target, ), "--- Recording mergeinfo for merge .* into '%s':\n" % (target, ) ] return expected_merge_output(rev_ranges, lines, target=target)
def do_text_conflicting_merge(): svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive', A_COPY_path) svntest.actions.run_and_verify_svn( None, expected_merge_output( [[3]], ["C %s\n" % psi_COPY_path, " U %s\n" % A_COPY_path], target=A_COPY_path, text_conflicts=1), [], 'merge', '-c3', '--allow-mixed-revisions', sbox.repo_url + '/A', A_COPY_path)
def do_text_conflicting_merge(): svntest.actions.run_and_verify_svn(None, None, [], 'revert', '--recursive', A_COPY_path) svntest.actions.run_and_verify_svn( None, expected_merge_output([[3]], [ "C %s\n" % psi_COPY_path, " U %s\n" % A_COPY_path], target=A_COPY_path, text_conflicts=1), [], 'merge', '-c3', '--allow-mixed-revisions', sbox.repo_url + '/A', A_COPY_path)
def mergeinfo_on_pegged_wc_path(sbox): "svn mergeinfo on pegged working copy target" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_path = os.path.join(wc_dir, "A") A_COPY_path = os.path.join(wc_dir, "A_COPY") psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi") omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega") beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta") # Do a couple merges # # r7 - Merge -c3,6 from A to A_COPY. svntest.actions.run_and_verify_svn( None, expected_merge_output([[3],[6]], ['U ' + psi_COPY_path + '\n', 'U ' + omega_COPY_path + '\n', ' U ' + A_COPY_path + '\n', ' G ' + A_COPY_path + '\n',]), [], 'merge', '-c3,6', sbox.repo_url + '/A', A_COPY_path) svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'Merge r3 and r6') # r8 - Merge -c5 from A to A_COPY. svntest.actions.run_and_verify_svn( None, expected_merge_output([[5]], ['U ' + beta_COPY_path + '\n', ' U ' + A_COPY_path + '\n']), [], 'merge', '-c5', '--allow-mixed-revisions', sbox.repo_url + '/A', A_COPY_path) svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'Merge r5') # Ask for merged and eligible revisions to A_COPY pegged at various values. # Prior to issue #3180 fix the peg revision was ignored. # # A_COPY pegged to non-existent revision svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version('.*No such revision 99'), [], A_path, A_COPY_path + '@99', '--show-revs', 'merged') # A_COPY@BASE svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['3','5','6'], A_path, A_COPY_path + '@BASE', '--show-revs', 'merged') # A_COPY@HEAD svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['3','5','6'], A_path, A_COPY_path + '@HEAD', '--show-revs', 'merged') # A_COPY@4 (Prior to any merges) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), [], A_path, A_COPY_path + '@4', '--show-revs', 'merged') # A_COPY@COMMITTED (r8) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['3','5','6'], A_path, A_COPY_path + '@COMMITTED', '--show-revs', 'merged') # A_COPY@PREV (r7) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['3', '6'], A_path, A_COPY_path + '@PREV', '--show-revs', 'merged') # A_COPY@BASE svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['4'], A_path, A_COPY_path + '@BASE', '--show-revs', 'eligible') # A_COPY@HEAD svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['4'], A_path, A_COPY_path + '@HEAD', '--show-revs', 'eligible') # A_COPY@4 (Prior to any merges) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['3', '4', '5', '6'], A_path, A_COPY_path + '@4', '--show-revs', 'eligible') # A_COPY@COMMITTED (r8) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['4'], A_path, A_COPY_path + '@COMMITTED', '--show-revs', 'eligible') # A_COPY@PREV (r7) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['4', '5'], A_path, A_COPY_path + '@PREV', '--show-revs', 'eligible')
def recursive_mergeinfo(sbox): "test svn mergeinfo -R" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_path = os.path.join(wc_dir, "A") A_COPY_path = os.path.join(wc_dir, "A_COPY") B_COPY_path = os.path.join(wc_dir, "A_COPY", "B") C_COPY_path = os.path.join(wc_dir, "A_COPY", "C") rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho") H_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H") F_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F") omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega") beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta") A2_path = os.path.join(wc_dir, "A2") nu_path = os.path.join(wc_dir, "A2", "B", "F", "nu") nu_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F", "nu") nu2_path = os.path.join(wc_dir, "A2", "C", "nu2") # Rename A to A2 in r7. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], 'up', wc_dir) svntest.actions.run_and_verify_svn(None, None, [], 'ren', A_path, A2_path) svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'rename A to A2') # Add the files A/B/F/nu and A/C/nu2 and commit them as r8. svntest.main.file_write(nu_path, "A new file.\n") svntest.main.file_write(nu2_path, "Another new file.\n") svntest.main.run_svn(None, "add", nu_path, nu2_path) svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'Add 2 new files') # Do several merges to create varied subtree mergeinfo # Merge r4 from A2 to A_COPY at depth empty svntest.actions.run_and_verify_svn(None, exp_noop_up_out(8), [], 'up', wc_dir) svntest.actions.run_and_verify_svn( None, expected_merge_output([[4]], ' U ' + A_COPY_path + '\n'), [], 'merge', '-c4', '--depth', 'empty', sbox.repo_url + '/A2', A_COPY_path) # Merge r6 from A2/D/H to A_COPY/D/H svntest.actions.run_and_verify_svn( None, expected_merge_output([[6]], ['U ' + omega_COPY_path + '\n', ' G ' + H_COPY_path + '\n']), [], 'merge', '-c6', sbox.repo_url + '/A2/D/H', H_COPY_path) # Merge r5 from A2 to A_COPY svntest.actions.run_and_verify_svn( None, expected_merge_output([[5]], ['U ' + beta_COPY_path + '\n', ' G ' + A_COPY_path + '\n', ' G ' + B_COPY_path + '\n', ' U ' + B_COPY_path + '\n',], # Elision elides=True), [], 'merge', '-c5', sbox.repo_url + '/A2', A_COPY_path) # Reverse merge -r5 from A2/C to A_COPY/C leaving empty mergeinfo on # A_COPY/C. svntest.actions.run_and_verify_svn( None, expected_merge_output([[-5]], ' G ' + C_COPY_path + '\n'), [], 'merge', '-c-5', sbox.repo_url + '/A2/C', C_COPY_path) # Merge r8 from A2/B/F to A_COPY/B/F svntest.actions.run_and_verify_svn( None, expected_merge_output([[8]], ['A ' + nu_COPY_path + '\n', ' G ' + F_COPY_path + '\n']), [], 'merge', '-c8', sbox.repo_url + '/A2/B/F', F_COPY_path) # Commit everything this far as r9 svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'Many merges') svntest.actions.run_and_verify_svn(None, exp_noop_up_out(9), [], 'up', wc_dir) # Test svn mergeinfo -R / --depth infinity. # Asking for eligible revisions from A2 to A_COPY should show: # # r3 - Was never merged. # # r4 - Was merged at depth empty, so while there is mergeinfo for the # revision, the actual text change to A_COPY/D/G/rho hasn't yet # happened. # # r8* - Was only partially merged to the subtree at A_COPY/B/F. The # addition of A_COPY/C/nu2 is still outstanding. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['3', '4*', '8*'], sbox.repo_url + '/A2', sbox.repo_url + '/A_COPY', '--show-revs', 'eligible', '-R') # Asking for merged revisions from A2 to A_COPY should show: # # r4* - Was merged at depth empty, so while there is mergeinfo for the # revision, the actual text change to A_COPY/D/G/rho hasn't yet # happened. # # r5 - Was merged at depth infinity to the root of the 'branch', so it # should show as fully merged. # # r6 - This was a subtree merge, but since the subtree A_COPY/D/H was # the ancestor of the only change made in r6 it is considered # fully merged. # # r8* - Was only partially merged to the subtree at A_COPY/B/F. The # addition of A_COPY/C/nu2 is still outstanding. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['4*', '5', '6', '8*'], A2_path, A_COPY_path, '--show-revs', 'merged', '--depth', 'infinity') # A couple tests of problems found with initial issue #3242 fixes. # We should be able to check for the merged revs from a URL to a URL # when the latter has explicit mergeinfo... svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['6'], sbox.repo_url + '/A2/D/H', sbox.repo_url + '/A_COPY/D/H', '--show-revs', 'merged') # ...and when the latter has inherited mergeinfo. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['6'], sbox.repo_url + '/A2/D/H/omega', sbox.repo_url + '/A_COPY/D/H/omega', '--show-revs', 'merged')
def non_inheritable_mergeinfo(sbox): "non-inheritable mergeinfo shows as merged" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_COPY_path = os.path.join(wc_dir, "A_COPY") D_COPY_path = os.path.join(wc_dir, "A_COPY", "D") rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho") # Update the WC, then merge r4 from A to A_COPY and r6 from A to A_COPY # at --depth empty and commit the merges as r7. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], 'up', wc_dir) expected_status.tweak(wc_rev=6) svntest.actions.run_and_verify_svn( None, expected_merge_output([[4]], ['U ' + rho_COPY_path + '\n', ' U ' + A_COPY_path + '\n',]), [], 'merge', '-c4', sbox.repo_url + '/A', A_COPY_path) svntest.actions.run_and_verify_svn( None, expected_merge_output([[6]], ' G ' + A_COPY_path + '\n'), [], 'merge', '-c6', sbox.repo_url + '/A', A_COPY_path, '--depth', 'empty') expected_output = wc.State(wc_dir, { 'A_COPY' : Item(verb='Sending'), 'A_COPY/D/G/rho' : Item(verb='Sending'), }) expected_status.tweak('A_COPY', 'A_COPY/D/G/rho', wc_rev=7) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) # Update the WC a last time to ensure full inheritance. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(7), [], 'up', wc_dir) # Despite being non-inheritable, r6 should still show as merged to A_COPY # and not eligible for merging. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['4','6*'], sbox.repo_url + '/A', A_COPY_path) svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['3','5','6*'], sbox.repo_url + '/A', A_COPY_path, '--show-revs', 'eligible') # But if we drop down to A_COPY/D, r6 should show as eligible because it # was only merged into A_COPY, no deeper. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['4'], sbox.repo_url + '/A/D', D_COPY_path) svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['3','6'], sbox.repo_url + '/A/D', D_COPY_path, '--show-revs', 'eligible')
def merge_fails_if_subtree_is_deleted_on_src(sbox): "merge fails if subtree is deleted on src" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2876. ## # Create a WC sbox.build() wc_dir = sbox.wc_dir if is_ra_type_svn() or is_ra_type_dav(): write_authz_file(sbox, {"/" : "* = rw", "/unrelated" : ("* =\n" + svntest.main.wc_author2 + " = rw")}) # Some paths we'll care about Acopy_path = os.path.join(wc_dir, 'A_copy') gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma') Acopy_gamma_path = os.path.join(wc_dir, 'A_copy', 'D', 'gamma') Acopy_D_path = os.path.join(wc_dir, 'A_copy', 'D') A_url = sbox.repo_url + '/A' Acopy_url = sbox.repo_url + '/A_copy' # Contents to be added to 'gamma' new_content = "line1\nline2\nline3\nline4\nline5\n" svntest.main.file_write(gamma_path, new_content) # Create expected output tree for commit expected_output = wc.State(wc_dir, { 'A/D/gamma' : Item(verb='Sending'), }) # Create expected status tree for commit expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.tweak('A/D/gamma', wc_rev=2) # Commit the new content svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) svntest.actions.run_and_verify_svn(None, None, [], 'cp', A_url, Acopy_url, '-m', 'create a new copy of A') # Update working copy svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir) svntest.main.file_substitute(gamma_path, "line1", "this is line1") # Create expected output tree for commit expected_output = wc.State(wc_dir, { 'A/D/gamma' : Item(verb='Sending'), }) # Create expected status tree for commit expected_status.tweak(wc_rev=3) expected_status.tweak('A/D/gamma', wc_rev=4) expected_status.add({ 'A_copy' : Item(status=' ', wc_rev=3), 'A_copy/B' : Item(status=' ', wc_rev=3), 'A_copy/B/lambda' : Item(status=' ', wc_rev=3), 'A_copy/B/E' : Item(status=' ', wc_rev=3), 'A_copy/B/E/alpha': Item(status=' ', wc_rev=3), 'A_copy/B/E/beta' : Item(status=' ', wc_rev=3), 'A_copy/B/F' : Item(status=' ', wc_rev=3), 'A_copy/mu' : Item(status=' ', wc_rev=3), 'A_copy/C' : Item(status=' ', wc_rev=3), 'A_copy/D' : Item(status=' ', wc_rev=3), 'A_copy/D/gamma' : Item(status=' ', wc_rev=3), 'A_copy/D/G' : Item(status=' ', wc_rev=3), 'A_copy/D/G/pi' : Item(status=' ', wc_rev=3), 'A_copy/D/G/rho' : Item(status=' ', wc_rev=3), 'A_copy/D/G/tau' : Item(status=' ', wc_rev=3), 'A_copy/D/H' : Item(status=' ', wc_rev=3), 'A_copy/D/H/chi' : Item(status=' ', wc_rev=3), 'A_copy/D/H/omega': Item(status=' ', wc_rev=3), 'A_copy/D/H/psi' : Item(status=' ', wc_rev=3), }) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) # Delete A/D/gamma from working copy svntest.actions.run_and_verify_svn(None, None, [], 'delete', gamma_path) # Create expected output tree for commit expected_output = wc.State(wc_dir, { 'A/D/gamma' : Item(verb='Deleting'), }) expected_status.remove('A/D/gamma') svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir, wc_dir) svntest.actions.run_and_verify_svn(None, expected_merge_output([[3,4]], 'U ' + Acopy_gamma_path + '\n'), [], 'merge', '-r1:4', A_url + '/D/gamma' + '@4', Acopy_gamma_path) # r6: create an empty (unreadable) commit. # Empty or unreadable revisions used to crash a svn 1.6+ client when # used with a 1.5 server: # http://svn.haxx.se/dev/archive-2009-04/0476.shtml svntest.main.run_svn(None, 'mkdir', sbox.repo_url + '/unrelated', '--username', svntest.main.wc_author2, '-m', 'creating a rev with no paths.') # This merge causes a tree conflict. Since the result of the previous # merge of A/D/gamma into A_copy/D has not yet been committed, it is # considered a local modification of A_Copy/D/gamma by the following # merge. A delete merged ontop of a modified file is a tree conflict. # See notes/tree-conflicts/detection.txt svntest.actions.run_and_verify_svn(None, expected_merge_output([[6], [3,6]], ['D ' + Acopy_gamma_path + '\n', 'C ' + Acopy_D_path + '\n']), [], 'merge', '-r1:6', '--force', A_url, Acopy_path)
def reintegrate_fails_if_no_root_access(sbox): "reintegrate fails if no root access" # If a user is authorized to a reintegrate source and target, they # should be able to reintegrate, regardless of what authorization # they have to parents of the source and target. # # See http://subversion.tigris.org/issues/show_bug.cgi?id=3242#desc78 # Some paths we'll care about wc_dir = sbox.wc_dir A_path = os.path.join(wc_dir, 'A') A_COPY_path = os.path.join(wc_dir, 'A_COPY') beta_COPY_path = os.path.join(wc_dir, 'A_COPY', 'B', 'E', 'beta') rho_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'G', 'rho') omega_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'H', 'omega') psi_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'H', 'psi') # Copy A@1 to A_COPY in r2, and then make some changes to A in r3-6. sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Make a change on the branch, to A_COPY/mu, commit in r7. svntest.main.file_write(os.path.join(wc_dir, "A_COPY", "mu"), "Changed on the branch.") expected_output = wc.State(wc_dir, {'A_COPY/mu' : Item(verb='Sending')}) expected_status.tweak('A_COPY/mu', wc_rev=7) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) expected_disk.tweak('A_COPY/mu', contents='Changed on the branch.') # Update the WC. svntest.main.run_svn(None, 'up', wc_dir) # Sync A_COPY with A. expected_output = expected_merge_output([[2,7]], ['U ' + beta_COPY_path + '\n', 'U ' + rho_COPY_path + '\n', 'U ' + omega_COPY_path + '\n', 'U ' + psi_COPY_path + '\n', # Mergeinfo notification ' U ' + A_COPY_path + '\n']) svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge', sbox.repo_url + '/A', A_COPY_path) svntest.main.run_svn(None, 'ci', '-m', 'synch A_COPY with A', wc_dir) # Update so we are ready for reintegrate. svntest.main.run_svn(None, 'up', wc_dir) # Change authz file so everybody has access to everything but the root. if is_ra_type_svn() or is_ra_type_dav(): write_restrictive_svnserve_conf(sbox.repo_dir) write_authz_file(sbox, {"/" : "* =", "/A" : "* = rw", "/A_COPY" : "* = rw", "/iota" : "* = rw"}) # Now reintegrate A_COPY back to A. The lack of access to the root of the # repository shouldn't be a problem. expected_output = wc.State(A_path, { 'mu' : Item(status='U '), }) expected_disk = wc.State('', { '' : Item(props={SVN_PROP_MERGEINFO : '/A_COPY:2-8'}), 'B' : Item(), 'B/lambda' : Item("This is the file 'lambda'.\n"), 'B/E' : Item(), 'B/E/alpha' : Item("This is the file 'alpha'.\n"), 'B/E/beta' : Item("New content"), 'B/F' : Item(), 'mu' : Item("Changed on the branch."), 'C' : Item(), 'D' : Item(), 'D/gamma' : Item("This is the file 'gamma'.\n"), 'D/G' : Item(), 'D/G/pi' : Item("This is the file 'pi'.\n"), 'D/G/rho' : Item("New content"), 'D/G/tau' : Item("This is the file 'tau'.\n"), 'D/H' : Item(), 'D/H/chi' : Item("This is the file 'chi'.\n"), 'D/H/omega' : Item("New content"), 'D/H/psi' : Item("New content"), }) expected_status = wc.State(A_path, { "B" : Item(status=' ', wc_rev=8), "B/lambda" : Item(status=' ', wc_rev=8), "B/E" : Item(status=' ', wc_rev=8), "B/E/alpha" : Item(status=' ', wc_rev=8), "B/E/beta" : Item(status=' ', wc_rev=8), "B/F" : Item(status=' ', wc_rev=8), "mu" : Item(status='M ', wc_rev=8), "C" : Item(status=' ', wc_rev=8), "D" : Item(status=' ', wc_rev=8), "D/gamma" : Item(status=' ', wc_rev=8), "D/G" : Item(status=' ', wc_rev=8), "D/G/pi" : Item(status=' ', wc_rev=8), "D/G/rho" : Item(status=' ', wc_rev=8), "D/G/tau" : Item(status=' ', wc_rev=8), "D/H" : Item(status=' ', wc_rev=8), "D/H/chi" : Item(status=' ', wc_rev=8), "D/H/omega" : Item(status=' ', wc_rev=8), "D/H/psi" : Item(status=' ', wc_rev=8), "" : Item(status=' M', wc_rev=8), }) expected_skip = wc.State(A_path, {}) svntest.actions.run_and_verify_merge(A_path, None, None, sbox.repo_url + '/A_COPY', expected_output, expected_disk, expected_status, expected_skip, None, None, None, None, None, True, True, '--reintegrate')
def recursive_mergeinfo(sbox): "test svn mergeinfo -R" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_path = os.path.join(wc_dir, "A") A_COPY_path = os.path.join(wc_dir, "A_COPY") B_COPY_path = os.path.join(wc_dir, "A_COPY", "B") C_COPY_path = os.path.join(wc_dir, "A_COPY", "C") rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho") H_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H") F_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F") omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega") beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta") A2_path = os.path.join(wc_dir, "A2") nu_path = os.path.join(wc_dir, "A2", "B", "F", "nu") nu_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F", "nu") nu2_path = os.path.join(wc_dir, "A2", "C", "nu2") # Rename A to A2 in r7. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], "up", wc_dir) svntest.actions.run_and_verify_svn(None, None, [], "ren", A_path, A2_path) svntest.actions.run_and_verify_svn(None, None, [], "ci", wc_dir, "-m", "rename A to A2") # Add the files A/B/F/nu and A/C/nu2 and commit them as r8. svntest.main.file_write(nu_path, "A new file.\n") svntest.main.file_write(nu2_path, "Another new file.\n") svntest.main.run_svn(None, "add", nu_path, nu2_path) svntest.actions.run_and_verify_svn(None, None, [], "ci", wc_dir, "-m", "Add 2 new files") # Do several merges to create varied subtree mergeinfo # Merge r4 from A2 to A_COPY at depth empty svntest.actions.run_and_verify_svn(None, exp_noop_up_out(8), [], "up", wc_dir) svntest.actions.run_and_verify_svn( None, expected_merge_output([[4]], " U " + A_COPY_path + "\n"), [], "merge", "-c4", "--depth", "empty", sbox.repo_url + "/A2", A_COPY_path, ) # Merge r6 from A2/D/H to A_COPY/D/H svntest.actions.run_and_verify_svn( None, expected_merge_output([[6]], ["U " + omega_COPY_path + "\n", " G " + H_COPY_path + "\n"]), [], "merge", "-c6", sbox.repo_url + "/A2/D/H", H_COPY_path, ) # Merge r5 from A2 to A_COPY svntest.actions.run_and_verify_svn( None, expected_merge_output( [[5]], [ "U " + beta_COPY_path + "\n", " G " + A_COPY_path + "\n", " G " + B_COPY_path + "\n", " U " + B_COPY_path + "\n", ], # Elision elides=True, ), [], "merge", "-c5", sbox.repo_url + "/A2", A_COPY_path, ) # Reverse merge -r5 from A2/C to A_COPY/C leaving empty mergeinfo on # A_COPY/C. svntest.actions.run_and_verify_svn( None, expected_merge_output([[-5]], " G " + C_COPY_path + "\n"), [], "merge", "-c-5", sbox.repo_url + "/A2/C", C_COPY_path, ) # Merge r8 from A2/B/F to A_COPY/B/F svntest.actions.run_and_verify_svn( None, expected_merge_output([[8]], ["A " + nu_COPY_path + "\n", " G " + F_COPY_path + "\n"]), [], "merge", "-c8", sbox.repo_url + "/A2/B/F", F_COPY_path, ) # Commit everything this far as r9 svntest.actions.run_and_verify_svn(None, None, [], "ci", wc_dir, "-m", "Many merges") svntest.actions.run_and_verify_svn(None, exp_noop_up_out(9), [], "up", wc_dir) # Test svn mergeinfo -R / --depth infinity. # Asking for eligible revisions from A2 to A_COPY should show: # # r3 - Was never merged. # # r4 - Was merged at depth empty, so while there is mergeinfo for the # revision, the actual text change to A_COPY/D/G/rho hasn't yet # happened. # # r8* - Was only partially merged to the subtree at A_COPY/B/F. The # addition of A_COPY/C/nu2 is still outstanding. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "4*", "8*"], sbox.repo_url + "/A2", sbox.repo_url + "/A_COPY", "--show-revs", "eligible", "-R", ) # Do the same as above, but test that we can request the revisions # in reverse order. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["8*", "4*", "3"], sbox.repo_url + "/A2", sbox.repo_url + "/A_COPY", "--show-revs", "eligible", "-R", "-r", "9:0", ) # Asking for merged revisions from A2 to A_COPY should show: # # r4* - Was merged at depth empty, so while there is mergeinfo for the # revision, the actual text change to A_COPY/D/G/rho hasn't yet # happened. # # r5 - Was merged at depth infinity to the root of the 'branch', so it # should show as fully merged. # # r6 - This was a subtree merge, but since the subtree A_COPY/D/H was # the ancestor of the only change made in r6 it is considered # fully merged. # # r8* - Was only partially merged to the subtree at A_COPY/B/F. The # addition of A_COPY/C/nu2 is still outstanding. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4*", "5", "6", "8*"], A2_path, A_COPY_path, "--show-revs", "merged", "--depth", "infinity", ) # Do the same as above, but test that we can request the revisions # in reverse order. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["8*", "6", "5", "4*"], A2_path, A_COPY_path, "--show-revs", "merged", "--depth", "infinity", "-r", "9:0", ) # A couple tests of problems found with initial issue #3242 fixes. # We should be able to check for the merged revs from a URL to a URL # when the latter has explicit mergeinfo... svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["6"], sbox.repo_url + "/A2/D/H", sbox.repo_url + "/A_COPY/D/H", "--show-revs", "merged", ) # ...and when the latter has inherited mergeinfo. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["6"], sbox.repo_url + "/A2/D/H/omega", sbox.repo_url + "/A_COPY/D/H/omega", "--show-revs", "merged", )
def recursive_mergeinfo(sbox): "test svn mergeinfo -R" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_path = os.path.join(wc_dir, "A") A_COPY_path = os.path.join(wc_dir, "A_COPY") B_COPY_path = os.path.join(wc_dir, "A_COPY", "B") C_COPY_path = os.path.join(wc_dir, "A_COPY", "C") rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho") H_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H") F_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F") omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega") beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta") A2_path = os.path.join(wc_dir, "A2") nu_path = os.path.join(wc_dir, "A2", "B", "F", "nu") nu_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "F", "nu") nu2_path = os.path.join(wc_dir, "A2", "C", "nu2") # Rename A to A2 in r7. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], 'up', wc_dir) svntest.actions.run_and_verify_svn(None, None, [], 'ren', A_path, A2_path) svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'rename A to A2') # Add the files A/B/F/nu and A/C/nu2 and commit them as r8. svntest.main.file_write(nu_path, "A new file.\n") svntest.main.file_write(nu2_path, "Another new file.\n") svntest.main.run_svn(None, "add", nu_path, nu2_path) svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'Add 2 new files') # Do several merges to create varied subtree mergeinfo # Merge r4 from A2 to A_COPY at depth empty svntest.actions.run_and_verify_svn(None, exp_noop_up_out(8), [], 'up', wc_dir) svntest.actions.run_and_verify_svn( None, expected_merge_output([[4]], ' U ' + A_COPY_path + '\n'), [], 'merge', '-c4', '--depth', 'empty', sbox.repo_url + '/A2', A_COPY_path) # Merge r6 from A2/D/H to A_COPY/D/H svntest.actions.run_and_verify_svn( None, expected_merge_output([[6]], ['U ' + omega_COPY_path + '\n', ' G ' + H_COPY_path + '\n']), [], 'merge', '-c6', sbox.repo_url + '/A2/D/H', H_COPY_path) # Merge r5 from A2 to A_COPY svntest.actions.run_and_verify_svn( None, expected_merge_output([[5]], ['U ' + beta_COPY_path + '\n', ' G ' + A_COPY_path + '\n', ' G ' + B_COPY_path + '\n', ' U ' + B_COPY_path + '\n',], # Elision elides=True), [], 'merge', '-c5', sbox.repo_url + '/A2', A_COPY_path) # Reverse merge -r5 from A2/C to A_COPY/C leaving empty mergeinfo on # A_COPY/C. svntest.actions.run_and_verify_svn( None, expected_merge_output([[-5]], ' G ' + C_COPY_path + '\n'), [], 'merge', '-c-5', sbox.repo_url + '/A2/C', C_COPY_path) # Merge r8 from A2/B/F to A_COPY/B/F svntest.actions.run_and_verify_svn( None, expected_merge_output([[8]], ['A ' + nu_COPY_path + '\n', ' G ' + F_COPY_path + '\n']), [], 'merge', '-c8', sbox.repo_url + '/A2/B/F', F_COPY_path) # Commit everything this far as r9 svntest.actions.run_and_verify_svn(None, None, [], 'ci', wc_dir, '-m', 'Many merges') svntest.actions.run_and_verify_svn(None, exp_noop_up_out(9), [], 'up', wc_dir) # Test svn mergeinfo -R / --depth infinity. # Asking for eligible revisions from A2 to A_COPY should show: # # r3 - Was never merged. # # r4 - Was merged at depth empty, so while there is mergeinfo for the # revision, the actual text change to A_COPY/D/G/rho hasn't yet # happened. # # r8* - Was only partially merged to the subtree at A_COPY/B/F. The # addition of A_COPY/C/nu2 is still outstanding. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['3', '4*', '8*'], sbox.repo_url + '/A2', sbox.repo_url + '/A_COPY', '--show-revs', 'eligible', '-R') # Do the same as above, but test that we can request the revisions # in reverse order. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['8*', '4*', '3'], sbox.repo_url + '/A2', sbox.repo_url + '/A_COPY', '--show-revs', 'eligible', '-R', '-r', '9:0') # Asking for merged revisions from A2 to A_COPY should show: # # r4* - Was merged at depth empty, so while there is mergeinfo for the # revision, the actual text change to A_COPY/D/G/rho hasn't yet # happened. # # r5 - Was merged at depth infinity to the root of the 'branch', so it # should show as fully merged. # # r6 - This was a subtree merge, but since the subtree A_COPY/D/H was # the ancestor of the only change made in r6 it is considered # fully merged. # # r8* - Was only partially merged to the subtree at A_COPY/B/F. The # addition of A_COPY/C/nu2 is still outstanding. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['4*', '5', '6', '8*'], A2_path, A_COPY_path, '--show-revs', 'merged', '--depth', 'infinity') # Do the same as above, but test that we can request the revisions # in reverse order. svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""), ['8*', '6', '5', '4*'], A2_path, A_COPY_path, '--show-revs', 'merged', '--depth', 'infinity', '-r', '9:0') # A couple tests of problems found with initial issue #3242 fixes. # We should be able to check for the merged revs from a URL to a URL # when the latter has explicit mergeinfo... svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['6'], sbox.repo_url + '/A2/D/H', sbox.repo_url + '/A_COPY/D/H', '--show-revs', 'merged') # ...and when the latter has inherited mergeinfo. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(''), ['6'], sbox.repo_url + '/A2/D/H/omega', sbox.repo_url + '/A_COPY/D/H/omega', '--show-revs', 'merged')
def mergeinfo_on_pegged_wc_path(sbox): "svn mergeinfo on pegged working copy target" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_path = os.path.join(wc_dir, "A") A_COPY_path = os.path.join(wc_dir, "A_COPY") psi_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "psi") omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega") beta_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "beta") # Do a couple merges # # r7 - Merge -c3,6 from A to A_COPY. svntest.actions.run_and_verify_svn( None, expected_merge_output( [[3], [6]], [ "U " + psi_COPY_path + "\n", "U " + omega_COPY_path + "\n", " U " + A_COPY_path + "\n", " G " + A_COPY_path + "\n", ], ), [], "merge", "-c3,6", sbox.repo_url + "/A", A_COPY_path, ) svntest.actions.run_and_verify_svn(None, None, [], "ci", wc_dir, "-m", "Merge r3 and r6") # r8 - Merge -c5 from A to A_COPY. svntest.actions.run_and_verify_svn( None, expected_merge_output([[5]], ["U " + beta_COPY_path + "\n", " U " + A_COPY_path + "\n"]), [], "merge", "-c5", "--allow-mixed-revisions", sbox.repo_url + "/A", A_COPY_path, ) svntest.actions.run_and_verify_svn(None, None, [], "ci", wc_dir, "-m", "Merge r5") # Ask for merged and eligible revisions to A_COPY pegged at various values. # Prior to issue #3180 fix the peg revision was ignored. # # A_COPY pegged to non-existent revision svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(".*No such revision 99"), [], A_path, A_COPY_path + "@99", "--show-revs", "merged", ) # A_COPY@BASE svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "5", "6"], A_path, A_COPY_path + "@BASE", "--show-revs", "merged" ) # A_COPY@HEAD svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "5", "6"], A_path, A_COPY_path + "@HEAD", "--show-revs", "merged" ) # A_COPY@4 (Prior to any merges) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), [], A_path, A_COPY_path + "@4", "--show-revs", "merged" ) # A_COPY@COMMITTED (r8) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "5", "6"], A_path, A_COPY_path + "@COMMITTED", "--show-revs", "merged", ) # A_COPY@PREV (r7) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "6"], A_path, A_COPY_path + "@PREV", "--show-revs", "merged" ) # A_COPY@BASE svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4"], A_path, A_COPY_path + "@BASE", "--show-revs", "eligible" ) # A_COPY@HEAD svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4"], A_path, A_COPY_path + "@HEAD", "--show-revs", "eligible" ) # A_COPY@4 (Prior to any merges) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "4", "5", "6"], A_path, A_COPY_path + "@4", "--show-revs", "eligible" ) # A_COPY@COMMITTED (r8) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4"], A_path, A_COPY_path + "@COMMITTED", "--show-revs", "eligible" ) # A_COPY@PREV (r7) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4", "5"], A_path, A_COPY_path + "@PREV", "--show-revs", "eligible" )
def merge_fails_if_subtree_is_deleted_on_src(sbox): "merge fails if subtree is deleted on src" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2876. ## # Create a WC sbox.build() wc_dir = sbox.wc_dir if is_ra_type_svn() or is_ra_type_dav(): write_authz_file(sbox, {"/" : "* = rw", "/unrelated" : ("* =\n" + svntest.main.wc_author2 + " = rw")}) # Some paths we'll care about Acopy_path = sbox.ospath('A_copy') gamma_path = sbox.ospath('A/D/gamma') Acopy_gamma_path = sbox.ospath('A_copy/D/gamma') Acopy_D_path = sbox.ospath('A_copy/D') A_url = sbox.repo_url + '/A' Acopy_url = sbox.repo_url + '/A_copy' # Contents to be added to 'gamma' new_content = "line1\nline2\nline3\nline4\nline5\n" svntest.main.file_write(gamma_path, new_content) # Create expected output tree for commit expected_output = wc.State(wc_dir, { 'A/D/gamma' : Item(verb='Sending'), }) # Create expected status tree for commit expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.tweak('A/D/gamma', wc_rev=2) # Commit the new content svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) svntest.actions.run_and_verify_svn(None, None, [], 'cp', A_url, Acopy_url, '-m', 'create a new copy of A') # Update working copy svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir) svntest.main.file_substitute(gamma_path, "line1", "this is line1") # Create expected output tree for commit expected_output = wc.State(wc_dir, { 'A/D/gamma' : Item(verb='Sending'), }) # Create expected status tree for commit expected_status.tweak(wc_rev=3) expected_status.tweak('A/D/gamma', wc_rev=4) expected_status.add({ 'A_copy' : Item(status=' ', wc_rev=3), 'A_copy/B' : Item(status=' ', wc_rev=3), 'A_copy/B/lambda' : Item(status=' ', wc_rev=3), 'A_copy/B/E' : Item(status=' ', wc_rev=3), 'A_copy/B/E/alpha': Item(status=' ', wc_rev=3), 'A_copy/B/E/beta' : Item(status=' ', wc_rev=3), 'A_copy/B/F' : Item(status=' ', wc_rev=3), 'A_copy/mu' : Item(status=' ', wc_rev=3), 'A_copy/C' : Item(status=' ', wc_rev=3), 'A_copy/D' : Item(status=' ', wc_rev=3), 'A_copy/D/gamma' : Item(status=' ', wc_rev=3), 'A_copy/D/G' : Item(status=' ', wc_rev=3), 'A_copy/D/G/pi' : Item(status=' ', wc_rev=3), 'A_copy/D/G/rho' : Item(status=' ', wc_rev=3), 'A_copy/D/G/tau' : Item(status=' ', wc_rev=3), 'A_copy/D/H' : Item(status=' ', wc_rev=3), 'A_copy/D/H/chi' : Item(status=' ', wc_rev=3), 'A_copy/D/H/omega': Item(status=' ', wc_rev=3), 'A_copy/D/H/psi' : Item(status=' ', wc_rev=3), }) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) # Delete A/D/gamma from working copy svntest.actions.run_and_verify_svn(None, None, [], 'delete', gamma_path) # Create expected output tree for commit expected_output = wc.State(wc_dir, { 'A/D/gamma' : Item(verb='Deleting'), }) expected_status.remove('A/D/gamma') svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir, wc_dir) svntest.actions.run_and_verify_svn( None, expected_merge_output([[3,4]], ['U ' + Acopy_gamma_path + '\n', ' U ' + Acopy_gamma_path + '\n']), [], 'merge', '-r1:4', A_url + '/D/gamma' + '@4', Acopy_gamma_path) # r6: create an empty (unreadable) commit. # Empty or unreadable revisions used to crash a svn 1.6+ client when # used with a 1.5 server: # http://svn.haxx.se/dev/archive-2009-04/0476.shtml svntest.main.run_svn(None, 'mkdir', sbox.repo_url + '/unrelated', '--username', svntest.main.wc_author2, '-m', 'creating a rev with no paths.') # A delete merged ontop of a modified file is normally a tree conflict, # see notes/tree-conflicts/detection.txt, but --force currently avoids # this. svntest.actions.run_and_verify_svn( None, expected_merge_output([[3,6]], ['D ' + Acopy_gamma_path + '\n', ' U ' + Acopy_path + '\n']), [], 'merge', '-r1:6', '--force', A_url, Acopy_path)
def reintegrate_fails_if_no_root_access(sbox): "reintegrate fails if no root access" # If a user is authorized to a reintegrate source and target, they # should be able to reintegrate, regardless of what authorization # they have to parents of the source and target. # # See http://subversion.tigris.org/issues/show_bug.cgi?id=3242#desc78 # Some paths we'll care about wc_dir = sbox.wc_dir A_path = sbox.ospath('A') A_COPY_path = sbox.ospath('A_COPY') beta_COPY_path = sbox.ospath('A_COPY/B/E/beta') rho_COPY_path = sbox.ospath('A_COPY/D/G/rho') omega_COPY_path = sbox.ospath('A_COPY/D/H/omega') psi_COPY_path = sbox.ospath('A_COPY/D/H/psi') # Copy A@1 to A_COPY in r2, and then make some changes to A in r3-6. sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Make a change on the branch, to A_COPY/mu, commit in r7. svntest.main.file_write(sbox.ospath("A_COPY/mu"), "Changed on the branch.") expected_output = wc.State(wc_dir, {'A_COPY/mu' : Item(verb='Sending')}) expected_status.tweak('A_COPY/mu', wc_rev=7) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) expected_disk.tweak('A_COPY/mu', contents='Changed on the branch.') # Update the WC. svntest.main.run_svn(None, 'up', wc_dir) # Sync A_COPY with A. expected_output = expected_merge_output([[2,7]], ['U ' + beta_COPY_path + '\n', 'U ' + rho_COPY_path + '\n', 'U ' + omega_COPY_path + '\n', 'U ' + psi_COPY_path + '\n', # Mergeinfo notification ' U ' + A_COPY_path + '\n']) svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge', sbox.repo_url + '/A', A_COPY_path) svntest.main.run_svn(None, 'ci', '-m', 'synch A_COPY with A', wc_dir) # Update so we are ready for reintegrate. svntest.main.run_svn(None, 'up', wc_dir) # Change authz file so everybody has access to everything but the root. if is_ra_type_svn() or is_ra_type_dav(): write_restrictive_svnserve_conf(sbox.repo_dir) write_authz_file(sbox, {"/" : "* =", "/A" : "* = rw", "/A_COPY" : "* = rw", "/iota" : "* = rw"}) # Now reintegrate A_COPY back to A. The lack of access to the root of the # repository shouldn't be a problem. expected_output = wc.State(A_path, { 'mu' : Item(status='U '), }) expected_mergeinfo_output = wc.State(A_path, { '' : Item(status=' U'), }) expected_elision_output = wc.State(A_path, { }) expected_disk = wc.State('', { '' : Item(props={SVN_PROP_MERGEINFO : '/A_COPY:2-8'}), 'B' : Item(), 'B/lambda' : Item("This is the file 'lambda'.\n"), 'B/E' : Item(), 'B/E/alpha' : Item("This is the file 'alpha'.\n"), 'B/E/beta' : Item("New content"), 'B/F' : Item(), 'mu' : Item("Changed on the branch."), 'C' : Item(), 'D' : Item(), 'D/gamma' : Item("This is the file 'gamma'.\n"), 'D/G' : Item(), 'D/G/pi' : Item("This is the file 'pi'.\n"), 'D/G/rho' : Item("New content"), 'D/G/tau' : Item("This is the file 'tau'.\n"), 'D/H' : Item(), 'D/H/chi' : Item("This is the file 'chi'.\n"), 'D/H/omega' : Item("New content"), 'D/H/psi' : Item("New content"), }) expected_status = wc.State(A_path, { "B" : Item(status=' ', wc_rev=8), "B/lambda" : Item(status=' ', wc_rev=8), "B/E" : Item(status=' ', wc_rev=8), "B/E/alpha" : Item(status=' ', wc_rev=8), "B/E/beta" : Item(status=' ', wc_rev=8), "B/F" : Item(status=' ', wc_rev=8), "mu" : Item(status='M ', wc_rev=8), "C" : Item(status=' ', wc_rev=8), "D" : Item(status=' ', wc_rev=8), "D/gamma" : Item(status=' ', wc_rev=8), "D/G" : Item(status=' ', wc_rev=8), "D/G/pi" : Item(status=' ', wc_rev=8), "D/G/rho" : Item(status=' ', wc_rev=8), "D/G/tau" : Item(status=' ', wc_rev=8), "D/H" : Item(status=' ', wc_rev=8), "D/H/chi" : Item(status=' ', wc_rev=8), "D/H/omega" : Item(status=' ', wc_rev=8), "D/H/psi" : Item(status=' ', wc_rev=8), "" : Item(status=' M', wc_rev=8), }) expected_skip = wc.State(A_path, {}) svntest.actions.run_and_verify_merge(A_path, None, None, sbox.repo_url + '/A_COPY', None, expected_output, expected_mergeinfo_output, expected_elision_output, expected_disk, expected_status, expected_skip, None, None, None, None, None, True, True, '--reintegrate', A_path)
def non_inheritable_mergeinfo(sbox): "non-inheritable mergeinfo shows as merged" sbox.build() wc_dir = sbox.wc_dir expected_disk, expected_status = set_up_branch(sbox) # Some paths we'll care about A_COPY_path = os.path.join(wc_dir, "A_COPY") D_COPY_path = os.path.join(wc_dir, "A_COPY", "D") rho_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "G", "rho") # Update the WC, then merge r4 from A to A_COPY and r6 from A to A_COPY # at --depth empty and commit the merges as r7. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(6), [], "up", wc_dir) expected_status.tweak(wc_rev=6) svntest.actions.run_and_verify_svn( None, expected_merge_output([[4]], ["U " + rho_COPY_path + "\n", " U " + A_COPY_path + "\n"]), [], "merge", "-c4", sbox.repo_url + "/A", A_COPY_path, ) svntest.actions.run_and_verify_svn( None, expected_merge_output([[6]], " G " + A_COPY_path + "\n"), [], "merge", "-c6", sbox.repo_url + "/A", A_COPY_path, "--depth", "empty", ) expected_output = wc.State(wc_dir, {"A_COPY": Item(verb="Sending"), "A_COPY/D/G/rho": Item(verb="Sending")}) expected_status.tweak("A_COPY", "A_COPY/D/G/rho", wc_rev=7) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, None, wc_dir) # Update the WC a last time to ensure full inheritance. svntest.actions.run_and_verify_svn(None, exp_noop_up_out(7), [], "up", wc_dir) # Despite being non-inheritable, r6 should still show as merged to A_COPY # and not eligible for merging. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4", "6*"], sbox.repo_url + "/A", A_COPY_path, "--show-revs", "merged" ) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "5", "6*"], sbox.repo_url + "/A", A_COPY_path, "--show-revs", "eligible", ) # But if we drop down to A_COPY/D, r6 should show as eligible because it # was only merged into A_COPY, no deeper. svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["4"], sbox.repo_url + "/A/D", D_COPY_path, "--show-revs", "merged" ) svntest.actions.run_and_verify_mergeinfo( adjust_error_for_server_version(""), ["3", "6"], sbox.repo_url + "/A/D", D_COPY_path, "--show-revs", "eligible" )