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)
Exemple #2
0
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)
Exemple #5
0
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)
Exemple #7
0
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)
Exemple #9
0
    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)
Exemple #11
0
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)
Exemple #12
0
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)