def svndumpfilter_loses_mergeinfo(sbox): "svndumpfilter loses mergeinfo" #svndumpfilter loses mergeinfo if invoked without --renumber-revs ## See https://issues.apache.org/jira/browse/SVN-3181. ## sbox.build(empty=True) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.actions.load_dumpfile(dumpfile_location) filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include", "trunk", "branch1", "--quiet") load_dumpstream(sbox, 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(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. ## sbox.build(empty=True) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.actions.load_dumpfile(dumpfile_location) filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include", "trunk", "branch1", "--quiet") load_dumpstream(sbox, 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(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_dumpstream(sbox, 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 _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_dumpstream(sbox, 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 https://issues.apache.org/jira/browse/SVN-2982. ## # Test svndumpfilter with include option sbox.build(empty=True) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.actions.load_dumpfile(dumpfile_location) filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "include", "trunk", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_dumpstream(sbox, 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(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) # Test svndumpfilter with exclude option sbox.build(empty=True) filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "exclude", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_dumpstream(sbox, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties expected_output = svntest.verify.UnorderedOutput([ url + "/trunk - \n", ]) svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url)
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 sbox.build(empty=True) dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 'svndumpfilter_tests_data', 'with_merges.dump') dumpfile = svntest.actions.load_dumpfile(dumpfile_location) filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "include", "trunk", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_dumpstream(sbox, 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(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url) # Test svndumpfilter with exclude option sbox.build(empty=True) filtered_out, filtered_err = filter_and_return_output( dumpfile, 0, "exclude", "branch1", "--skip-missing-merge-sources", "--drop-empty-revs", "--renumber-revs", "--quiet") load_dumpstream(sbox, filtered_out, "--ignore-uuid") # Verify the svn:mergeinfo properties expected_output = svntest.verify.UnorderedOutput([ url + "/trunk - \n", ]) svntest.actions.run_and_verify_svn(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url)
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_dumpstream(sbox, 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_dumpstream(sbox, 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 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_dumpstream(sbox, filtered_output, '--ignore-uuid') svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output, expected_disk, expected_status)
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 sbox.build(empty=True) load_dumpstream(sbox, filtered_output, '--ignore-uuid') svntest.actions.run_and_verify_update(sbox.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 | | | | | | # initial | | | |______ | | # 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_dumpstream(sbox, 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 | | | | | | # initial | | | |______ | | # 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_dumpstream(sbox, 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_dumpstream(sbox, 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_dumpstream(sbox, 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 dropped_but_not_renumbered_empty_revs(sbox): "mergeinfo maps correctly when dropping revs" sbox.build(empty=True) # The dump file mergeinfo_included_full.dump represents this repository: # # # __________________________________________ # | | # | ____________________________|_____ # | | | | # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | # r1 | | | | | | # initial | | | |______ | | # 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 = svntest.actions.load_dumpfile(full_dump) filtered_dumpfile, filtered_out = filter_and_return_output( full_dump_contents, 16384, # 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_dumpstream(sbox, 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(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" sbox.build(empty=True) # 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 | | | | | | # initial | | | |______ | | # 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 # referring to the initial revision in the dump file (r6) should be # removed because the change it refers to (r5:6) is not wholly within the # dumpfile. 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 = svntest.actions.load_dumpfile(partial_dump) 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_dumpstream(sbox, 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(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). sbox.build(empty=True) skeleton_location = os.path.join(os.path.dirname(sys.argv[0]), 'svnadmin_tests_data', 'skeleton_repos.dump') skeleton_dumpfile = svntest.actions.load_dumpfile(skeleton_location) load_dumpstream(sbox, 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 = svntest.actions.load_dumpfile(partial_dump2) # 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_dumpstream(sbox, 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(expected_output, [], 'propget', 'svn:mergeinfo', '-R', sbox.repo_url)