def svndumpfilter_loses_mergeinfo(sbox): "svndumpfilter loses mergeinfo" #svndumpfilter loses mergeinfo if invoked without --renumber-revs ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3181. ## test_create(sbox) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.main.file_read(dumpfile_location) filtered_out = filter_and_return_output(dumpfile, "include", "trunk", "branch1", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out) # Verify the svn:mergeinfo properties svntest.actions.run_and_verify_svn(None, [sbox.repo_url+"/trunk - /branch1:4-8\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/trunk') svntest.actions.run_and_verify_svn(None, [sbox.repo_url+"/branch1 - /trunk:1-2\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/branch1')
def accepts_deltas(sbox): "accepts deltas in the input" # Accept format v3 (as created by 'svnadmin --deltas' or svnrdump). sbox.build(empty=True) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'simple_v3.dump') dump_in = svntest.actions.load_dumpfile(dumpfile_location) dump_out, err = filter_and_return_output(dump_in, 0, "include", "trunk", "--quiet") expected_revs = [ svntest.wc.State('', { 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}), 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), }), svntest.wc.State('', { 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}), 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), }), svntest.wc.State('', { 'trunk' : svntest.wc.StateItem(props={'story': 'Yada yada yada...'}), 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), }), ] load_and_verify_dumpstream(sbox, [], [], expected_revs, True, dump_out, '--ignore-uuid')
def accepts_deltas(sbox): "accepts deltas in the input" # Accept format v3 (as created by 'svnadmin --deltas' or svnrdump). sbox.build(empty=True) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'simple_v3.dump') dump_in = svntest.actions.load_dumpfile(dumpfile_location) dump_out, err = filter_and_return_output(dump_in, 0, "include", "trunk", "--quiet") expected_revs = [ svntest.wc.State('', { 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}), 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), }), svntest.wc.State('', { 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}), 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), }), svntest.wc.State('', { 'trunk' : svntest.wc.StateItem(props={'story': 'Yada yada yada...'}), 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), }), ] load_and_verify_dumpstream(sbox, [], [], expected_revs, True, dump_out, '--ignore-uuid')
def _simple_dumpfilter_test(sbox, dumpfile, *dumpargs): """Run svndumpfilter with arguments DUMPARGS, taking input from DUMPFILE. Check that the output consists of the standard Greek tree excluding all paths that start with 'A/B/E', 'A/D/G' or 'A/D/H'.""" wc_dir = sbox.wc_dir filtered_output, filtered_err = filter_and_return_output( dumpfile, 0, '--quiet', *dumpargs) # Setup our expectations load_and_verify_dumpstream(sbox, [], [], None, filtered_output, '--ignore-uuid') expected_disk = svntest.main.greek_state.copy() expected_disk.remove('A/B/E/alpha') expected_disk.remove('A/B/E/beta') expected_disk.remove('A/B/E') expected_disk.remove('A/D/H/chi') expected_disk.remove('A/D/H/psi') expected_disk.remove('A/D/H/omega') expected_disk.remove('A/D/H') expected_disk.remove('A/D/G/pi') expected_disk.remove('A/D/G/rho') expected_disk.remove('A/D/G/tau') expected_disk.remove('A/D/G') expected_output = svntest.wc.State( wc_dir, { 'A': Item(status='A '), 'A/B': Item(status='A '), 'A/B/lambda': Item(status='A '), 'A/B/F': Item(status='A '), 'A/mu': Item(status='A '), 'A/C': Item(status='A '), 'A/D': Item(status='A '), 'A/D/gamma': Item(status='A '), 'iota': Item(status='A '), }) expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.remove('A/B/E/alpha') expected_status.remove('A/B/E/beta') expected_status.remove('A/B/E') expected_status.remove('A/D/H/chi') expected_status.remove('A/D/H/psi') expected_status.remove('A/D/H/omega') expected_status.remove('A/D/H') expected_status.remove('A/D/G/pi') expected_status.remove('A/D/G/rho') expected_status.remove('A/D/G/tau') expected_status.remove('A/D/G') # Check that our paths really were excluded svntest.actions.run_and_verify_update(wc_dir, expected_output, expected_disk, expected_status)
def _simple_dumpfilter_test(sbox, dumpfile, *dumpargs): wc_dir = sbox.wc_dir filtered_output, filtered_err = filter_and_return_output( dumpfile, 0, '--quiet', *dumpargs) # Setup our expectations load_and_verify_dumpstream(sbox, [], [], None, filtered_output, '--ignore-uuid') expected_disk = svntest.main.greek_state.copy() expected_disk.remove('A/B/E/alpha') expected_disk.remove('A/B/E/beta') expected_disk.remove('A/B/E') expected_disk.remove('A/D/H/chi') expected_disk.remove('A/D/H/psi') expected_disk.remove('A/D/H/omega') expected_disk.remove('A/D/H') expected_disk.remove('A/D/G/pi') expected_disk.remove('A/D/G/rho') expected_disk.remove('A/D/G/tau') expected_disk.remove('A/D/G') expected_output = svntest.wc.State( wc_dir, { 'A': Item(status='A '), 'A/B': Item(status='A '), 'A/B/lambda': Item(status='A '), 'A/B/F': Item(status='A '), 'A/mu': Item(status='A '), 'A/C': Item(status='A '), 'A/D': Item(status='A '), 'A/D/gamma': Item(status='A '), 'iota': Item(status='A '), }) expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.remove('A/B/E/alpha') expected_status.remove('A/B/E/beta') expected_status.remove('A/B/E') expected_status.remove('A/D/H/chi') expected_status.remove('A/D/H/psi') expected_status.remove('A/D/H/omega') expected_status.remove('A/D/H') expected_status.remove('A/D/G/pi') expected_status.remove('A/D/G/rho') expected_status.remove('A/D/G/tau') expected_status.remove('A/D/G') # Check that our paths really were excluded svntest.actions.run_and_verify_update(wc_dir, expected_output, expected_disk, expected_status)
def _simple_dumpfilter_test(sbox, dumpfile, *dumpargs): wc_dir = sbox.wc_dir filtered_output, filtered_err = filter_and_return_output(dumpfile, 0, "--quiet", *dumpargs) # Setup our expectations load_and_verify_dumpstream(sbox, [], [], None, filtered_output, "--ignore-uuid") expected_disk = svntest.main.greek_state.copy() expected_disk.remove("A/B/E/alpha") expected_disk.remove("A/B/E/beta") expected_disk.remove("A/B/E") expected_disk.remove("A/D/H/chi") expected_disk.remove("A/D/H/psi") expected_disk.remove("A/D/H/omega") expected_disk.remove("A/D/H") expected_disk.remove("A/D/G/pi") expected_disk.remove("A/D/G/rho") expected_disk.remove("A/D/G/tau") expected_disk.remove("A/D/G") expected_output = svntest.wc.State( wc_dir, { "A": Item(status="A "), "A/B": Item(status="A "), "A/B/lambda": Item(status="A "), "A/B/F": Item(status="A "), "A/mu": Item(status="A "), "A/C": Item(status="A "), "A/D": Item(status="A "), "A/D/gamma": Item(status="A "), "iota": Item(status="A "), }, ) expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.remove("A/B/E/alpha") expected_status.remove("A/B/E/beta") expected_status.remove("A/B/E") expected_status.remove("A/D/H/chi") expected_status.remove("A/D/H/psi") expected_status.remove("A/D/H/omega") expected_status.remove("A/D/H") expected_status.remove("A/D/G/pi") expected_status.remove("A/D/G/rho") expected_status.remove("A/D/G/tau") expected_status.remove("A/D/G") # Check that our paths really were excluded svntest.actions.run_and_verify_update(wc_dir, expected_output, expected_disk, expected_status)
def reflect_dropped_renumbered_revs(sbox): "reflect dropped renumbered revs in svn:mergeinfo" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2982. ## # Test svndumpfilter with include option test_create(sbox) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.main.file_read(dumpfile_location) filtered_out = filter_and_return_output(dumpfile, "include", "trunk", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties svntest.actions.run_and_verify_svn(None, [sbox.repo_url+"/trunk - /branch1:4-5\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/trunk') svntest.actions.run_and_verify_svn(None, [sbox.repo_url+"/branch1 - /trunk:1-2\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/branch1') # Test svndumpfilter with exclude option test_create(sbox) filtered_out = filter_and_return_output(dumpfile, "exclude", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties svntest.actions.run_and_verify_svn(None, [sbox.repo_url+"/trunk - \n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/trunk') svntest.actions.run_and_verify_svn(None, [sbox.repo_url+"/branch2 - /trunk:1-2\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/branch2')
def reflect_dropped_renumbered_revs(sbox): "reflect dropped renumbered revs in svn:mergeinfo" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2982. ## # Test svndumpfilter with include option test_create(sbox) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), "svndumpfilter_tests_data", "with_merges.dump") dumpfile = open(dumpfile_location).read() filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "include", "trunk", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet", ) load_and_verify_dumpstream(sbox, [], [], None, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties url = sbox.repo_url expected_output = svntest.verify.UnorderedOutput([url + "/trunk - /branch1:4-5\n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], "propget", "svn:mergeinfo", "-R", sbox.repo_url) # Test svndumpfilter with exclude option test_create(sbox) filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "exclude", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet", ) load_and_verify_dumpstream(sbox, [], [], None, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties expected_output = svntest.verify.UnorderedOutput([url + "/trunk - \n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], "propget", "svn:mergeinfo", "-R", sbox.repo_url)
def svndumpfilter_loses_mergeinfo(sbox): "svndumpfilter loses mergeinfo" # svndumpfilter loses mergeinfo if invoked without --renumber-revs ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3181. ## test_create(sbox) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), "svndumpfilter_tests_data", "with_merges.dump") dumpfile = open(dumpfile_location).read() filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include", "trunk", "branch1", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out) # Verify the svn:mergeinfo properties url = sbox.repo_url expected_output = svntest.verify.UnorderedOutput([url + "/trunk - /branch1:4-8\n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], "propget", "svn:mergeinfo", "-R", sbox.repo_url)
def test(sbox, dumpfile, *dumpargs): """Run svndumpfilter with DUMPFILE as the input lines, load the result and check it matches EXPECTED_DISK, EXPECTED_OUTPUT, EXPECTED_STATUS.""" # Filter the Greek tree dump filtered_output, filtered_err = filter_and_return_output( dumpfile, 0, '--quiet', *dumpargs) if filtered_err: raise verify.UnexpectedStderr(filtered_err) # Load the filtered dump into a repo and check the result test_create(sbox) load_and_verify_dumpstream(sbox, [], [], None, filtered_output, '--ignore-uuid') svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output, expected_disk, expected_status)
def reflect_dropped_renumbered_revs(sbox): "reflect dropped renumbered revs in svn:mergeinfo" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2982. ## # Test svndumpfilter with include option test_create(sbox) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.main.file_read(dumpfile_location) filtered_out = filter_and_return_output(dumpfile, "include", "trunk", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties svntest.actions.run_and_verify_svn( None, [sbox.repo_url + "/trunk - /branch1:4-5\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/trunk') svntest.actions.run_and_verify_svn( None, [sbox.repo_url + "/branch1 - /trunk:1-2\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/branch1') # Test svndumpfilter with exclude option test_create(sbox) filtered_out = filter_and_return_output(dumpfile, "exclude", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties svntest.actions.run_and_verify_svn(None, [sbox.repo_url + "/trunk - \n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/trunk') svntest.actions.run_and_verify_svn( None, [sbox.repo_url + "/branch2 - /trunk:1-2\n"], [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url + '/branch2')
def svndumpfilter_loses_mergeinfo(sbox): "svndumpfilter loses mergeinfo" #svndumpfilter loses mergeinfo if invoked without --renumber-revs ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3181. ## test_create(sbox) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = open(dumpfile_location).read() filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "include", "trunk", "branch1", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_out) # Verify the svn:mergeinfo properties url = sbox.repo_url expected_output = svntest.verify.UnorderedOutput([ url + "/trunk - /branch1:4-8\n", ]) svntest.actions.run_and_verify_svn(None, expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url)
def dropped_but_not_renumbered_empty_revs(sbox): "mergeinfo maps correctly when dropping revs" test_create(sbox) # The dump file mergeinfo_included_full.dump represents this repository: # # # __________________________________________ # | | # | ____________________________|_____ # | | | | # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | # r1 | | | | | | # intial | | | |______ | | # import copy | copy | merge merge # | | | merge (r5) (r8) # | | | (r9) | | # | | | | | | # | | V V | | # | | branches/B2-------r11---r12----> | | # | | r7 |____| | | # | | | | | # | merge |___ | | # | (r6) | | | # | |_________________ | | | # | | merge | | # | | (r11-12) | | # | | | | | # V V V | | # branches/B1-------------------r10--------r13--> | | # r4 | | # | V V # branches/B1/B/E------------------------------r14---r15-> # # # The mergeinfo on mergeinfo_included_full.dump is: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:11-12 # /trunk:6,9 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:11-12 # /trunk/B/E:5-6,8-9 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:9 # # Use svndumpfilter to filter mergeinfo_included_full.dump, excluding # branches/B2, while dropping, but not renumbering, empty revisions. # # Load the filtered dump into an empty repository. Since we are excluding # /branches/B2 and dropping empty revs, revisions 7, 11, and 12 won't be # included in the filtered dump. full_dump = os.path.join(os.path.dirname(sys.argv[0]), 'svnadmin_tests_data', 'mergeinfo_included_full.dump') full_dump_contents = open(full_dump).read() filtered_dumpfile, filtered_out = filter_and_return_output( full_dump_contents, 8192, # Set a sufficiently large bufsize to avoid a deadlock "exclude", "branches/B2", "--skip-missing-merge-sources", "--drop-empty-revs") # Now load the filtered dump into an empty repository. load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile, '--ignore-uuid') # The mergeinfo in the newly loaded repos should have no references to the # dropped branch and the remaining merge source revs should be remapped to # reflect the fact that the loaded repository no longer has any empty # revisions: # # Properties on 'branches/B1': # svn:mergeinfo # /trunk:6,8 # ^ # With r7 dropped, r9 in the incoming # dump becomes r8 in the loaded repos. # # Properties on 'branches/B1/B/E': # svn:mergeinfo # /trunk/B/E:5-8 # ^ # With r7 dropped, r8 and r9 in the incoming # dump becomes r7 and r8 in the loaded repos. # Check the resulting mergeinfo. url = sbox.repo_url + "/branches" expected_output = svntest.verify.UnorderedOutput( [url + "/B1 - /trunk:6,8\n", url + "/B1/B/E - /trunk/B/E:5-8\n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url)
def filter_mergeinfo_revs_outside_of_dump_stream(sbox): "filter mergeinfo revs outside of dump stream" test_create(sbox) # Load a partial dump into an existing repository. # # Picture == 1k words: # # The dump file we filter in this test, 'mergeinfo_included_partial.dump', is # a dump of r6:HEAD of the following repos: # # __________________________________________ # | | # | ____________________________|_____ # | | | | # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | # r1 | | | | | | # intial | | | |______ | | # import copy | copy | merge merge # | | | merge (r5) (r8) # | | | (r9) | | # | | | | | | # | | V V | | # | | branches/B2-------r11---r12----> | | # | | r7 |____| | | # | | | | | # | merge |___ | | # | (r6) | | | # | |_________________ | | | # | | merge | | # | | (r11-12) | | # | | | | | # V V V | | # branches/B1-------------------r10--------r13--> | | # r4 | | # | V V # branches/B1/B/E------------------------------r14---r15-> # # # The mergeinfo on the complete repos would look like this: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:11-12 # /trunk:6,9 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:11-12 # /trunk/B/E:5-6,8-9 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:9 # # We will run the partial dump through svndumpfilter using the the # --skip-missing-merge-soruces which should strip out any revisions < 6. # Then we'll load the filtered result into an empty repository. This # should offset the incoming mergeinfo by -5. In addition, any mergeinfo # revisions that are adjusted to r1 should be removed because that implies # a merge of -r0:1, which is impossible. The resulting mergeinfo should # look like this: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:6-7 # /trunk:4 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:6-7 # /trunk/B/E:3-4 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:4 partial_dump = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'mergeinfo_included_partial.dump') partial_dump_contents = open(partial_dump).read() filtered_dumpfile2, filtered_out = filter_and_return_output( partial_dump_contents, 8192, # Set a sufficiently large bufsize to avoid a deadlock "include", "trunk", "branches", "--skip-missing-merge-sources", "--quiet") load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile2, '--ignore-uuid') # Check the resulting mergeinfo. url = sbox.repo_url + "/branches" expected_output = svntest.verify.UnorderedOutput([ url + "/B1 - /branches/B2:6-7\n", "/trunk:4\n", url + "/B2 - /trunk:4\n", url + "/B1/B/E - /branches/B2/B/E:6-7\n", "/trunk/B/E:3-4\n" ]) svntest.actions.run_and_verify_svn(None, expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) # Blow away the current repos, create an empty one in its place, and # then load this skeleton repos into the empty target: # # Projects/ (Added r1) # README (Added r2) # Project-X (Added r3) # Project-Y (Added r4) # Project-Z (Added r5) # docs/ (Added r6) # README (Added r6). test_create(sbox) skeleton_dumpfile = open( os.path.join(os.path.dirname(sys.argv[0]), 'svnadmin_tests_data', 'skeleton_repos.dump')).read() load_and_verify_dumpstream(sbox, [], [], None, skeleton_dumpfile, '--ignore-uuid') partial_dump2 = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'mergeinfo_included_partial.dump') partial_dump_contents2 = open(partial_dump2).read() # Now use the partial dump file we used above, but this time exclude # the B2 branch. Load the filtered dump into the /Projects/Project-X # subtree of the skeleton repos. filtered_dumpfile2, filtered_err = filter_and_return_output( partial_dump_contents2, 8192, # Set a sufficiently large bufsize to avoid a deadlock "exclude", "branches/B2", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs") # Starting with the same expectation we had when loading into an empty # repository, adjust each revision by +6 to account for the six revision # already present in the target repos, that gives: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:12-13 # /trunk:10 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:12-13 # /trunk/B/E:9-10 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:10 # # ...But /branches/B2 has been filtered out, so all references to # that branch should be gone, leaving: # # Properties on 'branches/B1': # svn:mergeinfo # /trunk:10 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /trunk/B/E:9-10 # # ...But wait, there's more! Because we use the '--drop-empty-revs' # option, when filtering out 'branches/B2' all the revisions that effect # only that branch should be dropped (i.e. original revs r7, r11, and r12). # In and of itself that has no effect, but we also specifiy the # '--renumber-revs' option, so when r7 is dropped, r8 should map to r7, # r9 to r8, and r10 to r9 (and so on). That should finally leave us with: # # Properties on 'branches/B1': # svn:mergeinfo # /trunk:9 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /trunk/B/E:8-9 # # This test currently fails with this mergeinfo: # # # # # Check that all the blather above really happens. First does # svndumpfilter report what we expect to stderr? expected_err = [ "Excluding (and dropping empty revisions for) prefixes:\n", " '/branches/B2'\n", "\n", "Revision 6 committed as 6.\n", "Revision 7 skipped.\n", # <-- DROP! "Revision 8 committed as 7.\n", "Revision 9 committed as 8.\n", "Revision 10 committed as 9.\n", "Revision 11 skipped.\n", # <-- DROP! "Revision 12 skipped.\n", # <-- DROP! "Revision 13 committed as 10.\n", "Revision 14 committed as 11.\n", "Revision 15 committed as 12.\n", "\n", "Dropped 3 revisions.\n", "\n", "Revisions renumbered as follows:\n", " 15 => 12\n", " 14 => 11\n", " 13 => 10\n", " 12 => (dropped)\n", # <-- DROP! " 11 => (dropped)\n", # <-- DROP! " 10 => 9\n", " 9 => 8\n", " 8 => 7\n", " 7 => (dropped)\n", # <-- DROP! " 6 => 6\n", "\n", "Dropped 2 nodes:\n", " '/branches/B2'\n", " '/branches/B2/D/H/chi'\n", "\n" ] svntest.verify.verify_outputs( "Actual svndumpfilter stderr does not agree with expected stderr", None, filtered_err, None, expected_err) # Now actually load the filtered dump into the skeleton repository # and then check the resulting mergeinfo. load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile2, '--parent-dir', '/Projects/Project-X', '--ignore-uuid') url = sbox.repo_url + "/Projects/Project-X/branches" expected_output = svntest.verify.UnorderedOutput([ url + "/B1 - /Projects/Project-X/trunk:9\n", url + "/B1/B/E - /Projects/Project-X/trunk/B/E:8-9\n" ]) svntest.actions.run_and_verify_svn(None, expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url)
def dumpfilter_with_targets(sbox): "svndumpfilter --targets blah" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2697. ## test_create(sbox) wc_dir = sbox.wc_dir dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'greek_tree.dump') dumpfile = svntest.main.file_read(dumpfile_location) targets_file = os.tempnam(svntest.main.temp_dir, 'tmp') targets = open(targets_file, 'w') targets.write('/A/D/H\n') targets.write('/A/D/G\n') targets.close() filtered_output = filter_and_return_output(dumpfile, 'exclude', '/A/B/E', '--targets', targets_file, '--quiet') os.remove(targets_file) # Setup our expectations load_and_verify_dumpstream(sbox, [], [], None, filtered_output, '--ignore-uuid') expected_disk = svntest.main.greek_state.copy() expected_disk.remove('A/B/E/alpha') expected_disk.remove('A/B/E/beta') expected_disk.remove('A/B/E') expected_disk.remove('A/D/H/chi') expected_disk.remove('A/D/H/psi') expected_disk.remove('A/D/H/omega') expected_disk.remove('A/D/H') expected_disk.remove('A/D/G/pi') expected_disk.remove('A/D/G/rho') expected_disk.remove('A/D/G/tau') expected_disk.remove('A/D/G') expected_output = svntest.wc.State(wc_dir, { 'A' : Item(status='A '), 'A/B' : Item(status='A '), 'A/B/lambda' : Item(status='A '), 'A/B/F' : Item(status='A '), 'A/mu' : Item(status='A '), 'A/C' : Item(status='A '), 'A/D' : Item(status='A '), 'A/D/gamma' : Item(status='A '), 'iota' : Item(status='A '), }) expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.remove('A/B/E/alpha') expected_status.remove('A/B/E/beta') expected_status.remove('A/B/E') expected_status.remove('A/D/H/chi') expected_status.remove('A/D/H/psi') expected_status.remove('A/D/H/omega') expected_status.remove('A/D/H') expected_status.remove('A/D/G/pi') expected_status.remove('A/D/G/rho') expected_status.remove('A/D/G/tau') expected_status.remove('A/D/G') # Check that our paths really were excluded svntest.actions.run_and_verify_update(wc_dir, expected_output, expected_disk, expected_status)
def dumpfilter_with_targets(sbox): "svndumpfilter --targets blah" ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2697. ## test_create(sbox) wc_dir = sbox.wc_dir dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'greek_tree.dump') dumpfile = svntest.main.file_read(dumpfile_location) targets_file = os.tempnam(svntest.main.temp_dir, 'tmp') targets = open(targets_file, 'w') targets.write('/A/D/H\n') targets.write('/A/D/G\n') targets.close() filtered_output = filter_and_return_output(dumpfile, 'exclude', '/A/B/E', '--targets', targets_file, '--quiet') os.remove(targets_file) # Setup our expectations load_and_verify_dumpstream(sbox, [], [], None, filtered_output, '--ignore-uuid') expected_disk = svntest.main.greek_state.copy() expected_disk.remove('A/B/E/alpha') expected_disk.remove('A/B/E/beta') expected_disk.remove('A/B/E') expected_disk.remove('A/D/H/chi') expected_disk.remove('A/D/H/psi') expected_disk.remove('A/D/H/omega') expected_disk.remove('A/D/H') expected_disk.remove('A/D/G/pi') expected_disk.remove('A/D/G/rho') expected_disk.remove('A/D/G/tau') expected_disk.remove('A/D/G') expected_output = svntest.wc.State( wc_dir, { 'A': Item(status='A '), 'A/B': Item(status='A '), 'A/B/lambda': Item(status='A '), 'A/B/F': Item(status='A '), 'A/mu': Item(status='A '), 'A/C': Item(status='A '), 'A/D': Item(status='A '), 'A/D/gamma': Item(status='A '), 'iota': Item(status='A '), }) expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.remove('A/B/E/alpha') expected_status.remove('A/B/E/beta') expected_status.remove('A/B/E') expected_status.remove('A/D/H/chi') expected_status.remove('A/D/H/psi') expected_status.remove('A/D/H/omega') expected_status.remove('A/D/H') expected_status.remove('A/D/G/pi') expected_status.remove('A/D/G/rho') expected_status.remove('A/D/G/tau') expected_status.remove('A/D/G') # Check that our paths really were excluded svntest.actions.run_and_verify_update(wc_dir, expected_output, expected_disk, expected_status)
def dropped_but_not_renumbered_empty_revs(sbox): "mergeinfo maps correctly when dropping revs" test_create(sbox) # The dump file mergeinfo_included_full.dump represents this repository: # # # __________________________________________ # | | # | ____________________________|_____ # | | | | # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | # r1 | | | | | | # intial | | | |______ | | # import copy | copy | merge merge # | | | merge (r5) (r8) # | | | (r9) | | # | | | | | | # | | V V | | # | | branches/B2-------r11---r12----> | | # | | r7 |____| | | # | | | | | # | merge |___ | | # | (r6) | | | # | |_________________ | | | # | | merge | | # | | (r11-12) | | # | | | | | # V V V | | # branches/B1-------------------r10--------r13--> | | # r4 | | # | V V # branches/B1/B/E------------------------------r14---r15-> # # # The mergeinfo on mergeinfo_included_full.dump is: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:11-12 # /trunk:6,9 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:11-12 # /trunk/B/E:5-6,8-9 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:9 # # Use svndumpfilter to filter mergeinfo_included_full.dump, excluding # branches/B2, while dropping, but not renumbering, empty revisions. # # Load the filtered dump into an empty repository. Since we are excluding # /branches/B2 and dropping empty revs, revisions 7, 11, and 12 won't be # included in the filtered dump. full_dump = os.path.join(os.path.dirname(sys.argv[0]), "svnadmin_tests_data", "mergeinfo_included_full.dump") full_dump_contents = open(full_dump).read() filtered_dumpfile, filtered_out = filter_and_return_output( full_dump_contents, 8192, # Set a sufficiently large bufsize to avoid a deadlock "exclude", "branches/B2", "--skip-missing-merge-sources", "--drop-empty-revs", ) # Now load the filtered dump into an empty repository. load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile, "--ignore-uuid") # The mergeinfo in the newly loaded repos should have no references to the # dropped branch and the remaining merge source revs should be remapped to # reflect the fact that the loaded repository no longer has any empty # revisions: # # Properties on 'branches/B1': # svn:mergeinfo # /trunk:6,8 # ^ # With r7 dropped, r9 in the incoming # dump becomes r8 in the loaded repos. # # Properties on 'branches/B1/B/E': # svn:mergeinfo # /trunk/B/E:5-8 # ^ # With r7 dropped, r8 and r9 in the incoming # dump becomes r7 and r8 in the loaded repos. # Check the resulting mergeinfo. url = sbox.repo_url + "/branches" expected_output = svntest.verify.UnorderedOutput([url + "/B1 - /trunk:6,8\n", url + "/B1/B/E - /trunk/B/E:5-8\n"]) svntest.actions.run_and_verify_svn(None, expected_output, [], "propget", "svn:mergeinfo", "-R", sbox.repo_url)
def filter_mergeinfo_revs_outside_of_dump_stream(sbox): "filter mergeinfo revs outside of dump stream" test_create(sbox) # Load a partial dump into an existing repository. # # Picture == 1k words: # # The dump file we filter in this test, 'mergeinfo_included_partial.dump', is # a dump of r6:HEAD of the following repos: # # __________________________________________ # | | # | ____________________________|_____ # | | | | # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | # r1 | | | | | | # intial | | | |______ | | # import copy | copy | merge merge # | | | merge (r5) (r8) # | | | (r9) | | # | | | | | | # | | V V | | # | | branches/B2-------r11---r12----> | | # | | r7 |____| | | # | | | | | # | merge |___ | | # | (r6) | | | # | |_________________ | | | # | | merge | | # | | (r11-12) | | # | | | | | # V V V | | # branches/B1-------------------r10--------r13--> | | # r4 | | # | V V # branches/B1/B/E------------------------------r14---r15-> # # # The mergeinfo on the complete repos would look like this: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:11-12 # /trunk:6,9 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:11-12 # /trunk/B/E:5-6,8-9 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:9 # # We will run the partial dump through svndumpfilter using the the # --skip-missing-merge-soruces which should strip out any revisions < 6. # Then we'll load the filtered result into an empty repository. This # should offset the incoming mergeinfo by -5. In addition, any mergeinfo # revisions that are adjusted to r1 should be removed because that implies # a merge of -r0:1, which is impossible. The resulting mergeinfo should # look like this: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:6-7 # /trunk:4 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:6-7 # /trunk/B/E:3-4 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:4 partial_dump = os.path.join( os.path.dirname(sys.argv[0]), "svndumpfilter_tests_data", "mergeinfo_included_partial.dump" ) partial_dump_contents = open(partial_dump).read() filtered_dumpfile2, filtered_out = filter_and_return_output( partial_dump_contents, 8192, # Set a sufficiently large bufsize to avoid a deadlock "include", "trunk", "branches", "--skip-missing-merge-sources", "--quiet", ) load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile2, "--ignore-uuid") # Check the resulting mergeinfo. url = sbox.repo_url + "/branches" expected_output = svntest.verify.UnorderedOutput( [ url + "/B1 - /branches/B2:6-7\n", "/trunk:4\n", url + "/B2 - /trunk:4\n", url + "/B1/B/E - /branches/B2/B/E:6-7\n", "/trunk/B/E:3-4\n", ] ) svntest.actions.run_and_verify_svn(None, expected_output, [], "propget", "svn:mergeinfo", "-R", sbox.repo_url) # Blow away the current repos, create an empty one in its place, and # then load this skeleton repos into the empty target: # # Projects/ (Added r1) # README (Added r2) # Project-X (Added r3) # Project-Y (Added r4) # Project-Z (Added r5) # docs/ (Added r6) # README (Added r6). test_create(sbox) skeleton_dumpfile = open( os.path.join(os.path.dirname(sys.argv[0]), "svnadmin_tests_data", "skeleton_repos.dump") ).read() load_and_verify_dumpstream(sbox, [], [], None, skeleton_dumpfile, "--ignore-uuid") partial_dump2 = os.path.join( os.path.dirname(sys.argv[0]), "svndumpfilter_tests_data", "mergeinfo_included_partial.dump" ) partial_dump_contents2 = open(partial_dump2).read() # Now use the partial dump file we used above, but this time exclude # the B2 branch. Load the filtered dump into the /Projects/Project-X # subtree of the skeleton repos. filtered_dumpfile2, filtered_err = filter_and_return_output( partial_dump_contents2, 8192, # Set a sufficiently large bufsize to avoid a deadlock "exclude", "branches/B2", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", ) # Starting with the same expectation we had when loading into an empty # repository, adjust each revision by +6 to account for the six revision # already present in the target repos, that gives: # # Properties on 'branches/B1': # svn:mergeinfo # /branches/B2:12-13 # /trunk:10 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /branches/B2/B/E:12-13 # /trunk/B/E:9-10 # Properties on 'branches/B2': # svn:mergeinfo # /trunk:10 # # ...But /branches/B2 has been filtered out, so all references to # that branch should be gone, leaving: # # Properties on 'branches/B1': # svn:mergeinfo # /trunk:10 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /trunk/B/E:9-10 # # ...But wait, there's more! Because we use the '--drop-empty-revs' # option, when filtering out 'branches/B2' all the revisions that effect # only that branch should be dropped (i.e. original revs r7, r11, and r12). # In and of itself that has no effect, but we also specifiy the # '--renumber-revs' option, so when r7 is dropped, r8 should map to r7, # r9 to r8, and r10 to r9 (and so on). That should finally leave us with: # # Properties on 'branches/B1': # svn:mergeinfo # /trunk:9 # Properties on 'branches/B1/B/E': # svn:mergeinfo # /trunk/B/E:8-9 # # This test currently fails with this mergeinfo: # # # # # Check that all the blather above really happens. First does # svndumpfilter report what we expect to stderr? expected_err = [ "Excluding (and dropping empty revisions for) prefixes:\n", " '/branches/B2'\n", "\n", "Revision 6 committed as 6.\n", "Revision 7 skipped.\n", # <-- DROP! "Revision 8 committed as 7.\n", "Revision 9 committed as 8.\n", "Revision 10 committed as 9.\n", "Revision 11 skipped.\n", # <-- DROP! "Revision 12 skipped.\n", # <-- DROP! "Revision 13 committed as 10.\n", "Revision 14 committed as 11.\n", "Revision 15 committed as 12.\n", "\n", "Dropped 3 revisions.\n", "\n", "Revisions renumbered as follows:\n", " 15 => 12\n", " 14 => 11\n", " 13 => 10\n", " 12 => (dropped)\n", # <-- DROP! " 11 => (dropped)\n", # <-- DROP! " 10 => 9\n", " 9 => 8\n", " 8 => 7\n", " 7 => (dropped)\n", # <-- DROP! " 6 => 6\n", "\n", "Dropped 2 nodes:\n", " '/branches/B2'\n", " '/branches/B2/D/H/chi'\n", "\n", ] svntest.verify.verify_outputs( "Actual svndumpfilter stderr does not agree with expected stderr", None, filtered_err, None, expected_err ) # Now actually load the filtered dump into the skeleton repository # and then check the resulting mergeinfo. load_and_verify_dumpstream( sbox, [], [], None, filtered_dumpfile2, "--parent-dir", "/Projects/Project-X", "--ignore-uuid" ) url = sbox.repo_url + "/Projects/Project-X/branches" expected_output = svntest.verify.UnorderedOutput( [url + "/B1 - /Projects/Project-X/trunk:9\n", url + "/B1/B/E - /Projects/Project-X/trunk/B/E:8-9\n"] ) svntest.actions.run_and_verify_svn(None, expected_output, [], "propget", "svn:mergeinfo", "-R", sbox.repo_url)