You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2010/01/24 00:49:27 UTC

svn commit: r902509 [2/3] - in /subversion/trunk/subversion: include/ libsvn_client/ svn/ tests/cmdline/ tests/cmdline/svntest/

Modified: subversion/trunk/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_tests.py?rev=902509&r1=902508&r2=902509&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_tests.py Sat Jan 23 23:49:26 2010
@@ -45,24 +45,36 @@
 from svntest.actions import make_conflict_marker_text
 from svntest.actions import inject_conflict_into_expected_state
 
-def expected_merge_output(rev_ranges, additional_lines=None, foreign=False):
+def expected_merge_output(rev_ranges, additional_lines=None, foreign=False,
+                          elides=False, two_url=False):
   """Generate an (inefficient) regex representing the expected merge
-  output from REV_RANGES (a list of 'range' lists of the form [start, end] or
-  [single_rev] --> [single_rev - 1, single_rev]), and ADDITIONAL_LINES (a list
-  of strings).  If REV_RANGES is None then only the standard notification for
-  a 3-way merge is expected."""
+  output and mergeinfo notifications from REV_RANGES (a list of 'range' lists
+  of the form [start, end] or [single_rev] --> [single_rev - 1, single_rev]),
+  and ADDITIONAL_LINES (a list of strings).  If REV_RANGES is None then only
+  the standard notification for a 3-way merge is expected.  If ELIDES is true
+  add to the regex an expression representing elision notification.  If TWO_URL
+  us true tweak the regex to expect the appropriate mergeinfo notification
+  for a 3-way merge."""
   if rev_ranges is None:
     lines = [svntest.main.merge_notify_line(None, None, False, foreign)]
   else:
-   lines = []
-   for rng in rev_ranges:
-     start_rev = rng[0]
-     if len(rng) > 1:
-       end_rev = rng[1]
-     else:
-       end_rev = None
-     lines += [svntest.main.merge_notify_line(start_rev, end_rev,
-                                              True, foreign)]
+    lines = []
+    for rng in rev_ranges:
+      start_rev = rng[0]
+      if len(rng) > 1:
+        end_rev = rng[1]
+      else:
+        end_rev = None
+      lines += [svntest.main.merge_notify_line(start_rev, end_rev,
+                                               True, foreign)]
+      lines += [svntest.main.mergeinfo_notify_line(start_rev, end_rev)]
+
+  if (elides):
+    lines += ["--- Eliding mergeinfo from .*\n"]
+
+  if (two_url):
+    lines += ["--- Recording mergeinfo for merge between repository URLs .*\n"]
+
   if isinstance(additional_lines, list):
     # Address "The Backslash Plague"
     #
@@ -252,7 +264,8 @@
                                         'A/D/G/rho'  : Item(status='U '),
                                         'A/D/G/tau'  : Item(status='C '),
                                         })
-
+  expected_mergeinfo_output = wc.State(other_wc, {''  : Item(status=' U')})
+  expected_elision_output = wc.State(other_wc, {})
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.tweak('A/mu',
                       contents=expected_disk.desc['A/mu'].contents
@@ -285,8 +298,10 @@
                                 "tau\.merge-left\.r1"]
 
   svntest.actions.run_and_verify_merge(other_wc, '1', '3',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -302,13 +317,14 @@
   #
   # run_and_verify_merge doesn't support merging to a file WCPATH
   # so use run_and_verify_svn.
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[-3]], 'G    ' +
-                                                           other_rho_path +
-                                                           '\n'),
-                                     [], 'merge', '-c-3',
-                                     sbox.repo_url + '/A/D/G/rho',
-                                     other_rho_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[-3]],
+                          ['G    ' + other_rho_path + '\n',
+                           ' G   ' + other_rho_path + '\n',]),
+    [], 'merge', '-c-3',
+    sbox.repo_url + '/A/D/G/rho',
+    other_rho_path)
 
   # Now *prepend* ten or so lines to A/D/G/rho.  Since rho had ten
   # lines appended in revision 2, and then another ten in revision 3,
@@ -325,8 +341,17 @@
   # We expect no merge attempt for pi and tau because they inherit
   # mergeinfo from the WC root.  There is explicit mergeinfo on rho
   # ('/A/D/G/rho:2') so expect it to be merged (cleanly).
+  G_path = os.path.join(other_wc, 'A', 'D', 'G')
   expected_output = wc.State(os.path.join(other_wc, 'A', 'D', 'G'),
                              {'rho' : Item(status='G ')})
+  expected_mergeinfo_output = wc.State(G_path, {
+    ''    : Item(status=' G'),
+    'rho' : Item(status=' G')
+    })
+  expected_elision_output = wc.State(G_path, {
+    ''    : Item(status=' U'),
+    'rho' : Item(status=' U')
+    })
   expected_disk = wc.State("", {
     'pi'    : Item("This is the file 'pi'.\n"),
     'rho'   : Item("This is the file 'rho'.\n"),
@@ -357,8 +382,10 @@
   svntest.actions.run_and_verify_merge(
     os.path.join(other_wc, 'A', 'D', 'G'),
     '2', '3',
-    sbox.repo_url + '/A/D/G',
+    sbox.repo_url + '/A/D/G', None,
     expected_output,
+    expected_mergeinfo_output,
+    expected_elision_output,
     expected_disk,
     expected_status,
     expected_skip,
@@ -435,6 +462,11 @@
     'foo'    : Item(status='A '),
     'foo2'   : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(C_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(C_path, {
+    })
   expected_disk = wc.State('', {
     ''       : Item(props={SVN_PROP_MERGEINFO : '/A/B/F:2'}),
     'Q'      : Item(),
@@ -456,8 +488,10 @@
 
   expected_skip = wc.State(C_path, { })
 
-  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url,
+  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -565,15 +599,18 @@
   # Merge rev 3 into B2
 
   # The local mods to the paths modified in r3 cause the paths to be
-  # tree-conflicted upon deletion, resulting in only mergeinfo changes.
-  # The target of the merge 'B2' gets mergeinfo for r3 and B2's two skipped
-  # children, 'E' and 'lambda', get override mergeinfo reflecting their
-  # mergeinfo prior to the merge (in this case no mergeinfo at all).
+  # tree-conflicted upon deletion, resulting in only the mergeinfo change
+  # to the target of the merge 'B2'.
   expected_output = wc.State(B2_path, {
     ''        : Item(),
     'lambda'  : Item(status='  ', treeconflict='C'),
     'E'       : Item(status='  ', treeconflict='C'),
     })
+  expected_mergeinfo_output = wc.State(B2_path, {
+    ''         : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(B2_path, {
+    })
   expected_disk = wc.State('', {
     ''        : Item(props={SVN_PROP_MERGEINFO : '/A/B:3'}),
     'E'       : Item(props={'foo' : 'foo_val'}),
@@ -593,8 +630,10 @@
     })
   expected_status2.tweak(wc_rev=2)
   expected_skip = wc.State('', { })
-  svntest.actions.run_and_verify_merge(B2_path, '2', '3', B_url,
+  svntest.actions.run_and_verify_merge(B2_path, '2', '3', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status2,
                                        expected_skip,
@@ -691,6 +730,11 @@
     'E/alpha'  : Item(status=' U'),
     'E/beta'   : Item(status=' U'),
     })
+  expected_mergeinfo_output = wc.State(B2_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(B2_path, {
+    })
   expected_disk = wc.State('', {
     ''         : Item(props={SVN_PROP_MERGEINFO : '/A/B:4'}),
     'E'        : Item(),
@@ -713,8 +757,10 @@
     })
   expected_status.tweak(wc_rev=4)
   expected_skip = wc.State('', { })
-  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url,
+  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -729,8 +775,13 @@
   expected_status.tweak('', status='  ')
   expected_disk.remove('')
   expected_disk.tweak('E', 'E/alpha', 'E/beta', props={})
-  svntest.actions.run_and_verify_merge(B2_path, '2', '1', B_url,
+  expected_elision_output = wc.State(B2_path, {
+    '' : Item(status=' U'),
+    })
+  svntest.actions.run_and_verify_merge(B2_path, '2', '1', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -755,8 +806,12 @@
   expected_status.tweak('', status=' M')
   expected_status.tweak('E', 'E/alpha', 'E/beta', status=' C')
   expected_output.tweak('E', 'E/alpha', 'E/beta', status=' C')
-  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url,
+  expected_elision_output = wc.State(B2_path, {
+    })
+  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -865,6 +920,11 @@
   expected_output = wc.State('', {
     'newfile'         : Item(status='  ', treeconflict='C'),
     })
+  expected_mergeinfo_output = wc.State('', {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State('', {
+    })
   expected_status = wc.State('', {
     ''     : Item(status=' M' ),
     'pi'   : Item(status='  ' ),
@@ -887,8 +947,10 @@
     })
   expected_skip = wc.State('', {
     })
-  svntest.actions.run_and_verify_merge('', '2', '3', Q_url,
+  svntest.actions.run_and_verify_merge('', '2', '3', Q_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -941,6 +1003,11 @@
     'lambda'  : Item(status='U '),
     'E'       : Item(status='  ', treeconflict='C'),
     })
+  expected_mergeinfo_output = wc.State(I_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(I_path, {
+    })
   expected_disk = wc.State('', {
     ''        : Item(props={SVN_PROP_MERGEINFO : '/A/B:3'}),
     'F'       : Item(),
@@ -957,8 +1024,10 @@
     })
   expected_skip = wc.State(I_path, {
     })
-  svntest.actions.run_and_verify_merge(I_path, '2', '3', B_url,
+  svntest.actions.run_and_verify_merge(I_path, '2', '3', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -1006,6 +1075,11 @@
   expected_output = wc.State(I_path, {
     'F'       : Item(status='  ', treeconflict='C'),
     })
+  expected_mergeinfo_output = wc.State(I_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(I_path, {
+    })
   expected_disk = wc.State('', {
     'E'       : Item(),
     'E/alpha' : Item("This is the file 'alpha'.\n"),
@@ -1015,8 +1089,10 @@
   expected_skip = wc.State(I_path, {
     })
 
-  svntest.actions.run_and_verify_merge(I_path, '2', '4', B_url,
+  svntest.actions.run_and_verify_merge(I_path, '2', '4', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        None,
                                        expected_skip,
@@ -1137,25 +1213,26 @@
   # appears to be impossible to get the expected_foo trees working
   # right.  I think something is still assuming a directory target.
   if arg_flav == 'r':
-    svntest.actions.run_and_verify_svn(None ,
-                                       expected_merge_output([[2]], 'U    ' +
-                                                             rho_path + '\n'),
-                                       [],
-                                       'merge', '-r', '1:2',
-                                       rho_url, rho_path)
+    svntest.actions.run_and_verify_svn(
+      None,
+      expected_merge_output([[2]],
+                            ['U    ' + rho_path + '\n',
+                             ' U   ' + rho_path + '\n']),
+      [], 'merge', '-r', '1:2', rho_url, rho_path)
   elif arg_flav == 'c':
-    svntest.actions.run_and_verify_svn(None ,
-                                       expected_merge_output([[2]], 'U    ' +
-                                                             rho_path + '\n'),
-                                       [],
-                                       'merge', '-c', '2',
-                                       rho_url, rho_path)
+    svntest.actions.run_and_verify_svn(
+      None,
+      expected_merge_output([[2]],
+                            ['U    ' + rho_path + '\n',
+                             ' U   ' + rho_path + '\n']),
+      [], 'merge', '-c', '2', rho_url, rho_path)
   elif arg_flav == '*':
-    svntest.actions.run_and_verify_svn(None ,
-                                       expected_merge_output([[2]], 'U    ' +
-                                                             rho_path + '\n'),
-                                       [],
-                                       'merge', rho_url, rho_path)
+    svntest.actions.run_and_verify_svn(
+      None,
+      expected_merge_output([[2]],
+                            ['U    ' + rho_path + '\n',
+                             ' U   ' + rho_path + '\n']),
+      [], 'merge', rho_url, rho_path)
 
   expected_status.tweak(wc_rev=1)
   expected_status.tweak('A/D/G/rho', status='MM')
@@ -1184,11 +1261,14 @@
     merge_cmd += ['-c', '2']
 
   if record_only:
-    expected_output = []
+    expected_output = expected_merge_output([[2]],
+                                            [' U   rho\n'])
     merge_cmd.append('--record-only')
     rho_expected_status = ' M'
   else:
-    expected_output = expected_merge_output([[2]], 'U    rho\n')
+    expected_output = expected_merge_output([[2]],
+                                            ['U    rho\n',
+                                             ' U   rho\n'])
     rho_expected_status = 'MM'
   merge_cmd.append(rho_url)
 
@@ -1278,13 +1358,15 @@
   if arg_flav == 'r':
     svntest.actions.run_and_verify_svn(None,
                                        expected_merge_output([[2]],
-                                                             'U    mu\n'),
+                                                             ['U    mu\n',
+                                                              ' U   mu\n']),
                                        [],
                                        'merge', '-r', '1:2', 'mu')
   elif arg_flav == 'c':
     svntest.actions.run_and_verify_svn(None,
                                        expected_merge_output([[2]],
-                                                             'U    mu\n'),
+                                                             ['U    mu\n',
+                                                              ' U   mu\n']),
                                        [],
                                        'merge', '-c', '2', 'mu')
 
@@ -1295,7 +1377,8 @@
     svntest.actions.run_and_verify_svn(None, None, [], 'merge', 'mu')
     svntest.actions.run_and_verify_svn(None,
                                        expected_merge_output([[2]],
-                                                             'U    mu\n'),
+                                                             ['U    mu\n',
+                                                              ' U   mu\n']),
                                        [],
                                        'merge', 'mu@2')
 
@@ -1307,13 +1390,19 @@
   if arg_flav == 'r':
     svntest.actions.run_and_verify_svn(None,
                                        expected_merge_output([[-2]],
-                                                             'G    mu\n'),
+                                                             ['G    mu\n',
+                                                              ' U   mu\n',
+                                                              ' G   mu\n',],
+                                                             elides=True),
                                        [],
                                        'merge', '-r', '2:1', mu_url)
   elif arg_flav == 'c':
     svntest.actions.run_and_verify_svn(None,
                                        expected_merge_output([[-2]],
-                                                             'G    mu\n'),
+                                                             ['G    mu\n',
+                                                              ' U   mu\n',
+                                                              ' G   mu\n'],
+                                                             elides=True),
                                        [],
                                        'merge', '-c', '-2', mu_url)
   elif arg_flav == '*':
@@ -1322,7 +1411,10 @@
     # r2 to enable continuation of the test case.
     svntest.actions.run_and_verify_svn(None,
                                        expected_merge_output([[-2]],
-                                                             'G    mu\n'),
+                                                             ['G    mu\n',
+                                                              ' U   mu\n',
+                                                              ' G   mu\n'],
+                                                             elides=True),
                                        [],
                                        'merge', '-c', '-2', mu_url)
 
@@ -1402,7 +1494,9 @@
   # Cannot use run_and_verify_merge with a file target
   svntest.actions.run_and_verify_svn(None,
                                      expected_merge_output([[-2]],
-                                                           'U    mu\n'),
+                                                           ['U    mu\n',
+                                                            ' U   mu\n'],
+                                                           elides=True),
                                      [],
                                      'merge', '-r', 'HEAD:PREV', 'mu')
 
@@ -1496,6 +1590,11 @@
   expected_output = wc.State(other_wc, {
     'A/theta' : Item(status='U '),
     })
+  expected_mergeinfo_output = wc.State(other_wc, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(other_wc, {
+    })
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.add({
     ''        : Item(props={SVN_PROP_MERGEINFO : '/:3'}),
@@ -1510,8 +1609,10 @@
   expected_skip = wc.State('', { })
 
   svntest.actions.run_and_verify_merge(other_wc, '2', '3',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -1566,6 +1667,8 @@
   expected_output = wc.State(wc_dir, {
     "A/theta" : Item(status="  ", treeconflict='C'),
     })
+  expected_elision_output = wc.State(wc_dir, {
+    })
 
   # As greek_state is rooted at / instead of /A (our merge target), we
   # need a sub-tree of it rather than straight copy.
@@ -1586,14 +1689,22 @@
 
   # If we merge into wc_dir alone, theta appears at the WC root,
   # which is in the wrong location -- append "/A" to stay on target.
-  svntest.actions.run_and_verify_merge2(A_path, "2", "3",
-                                        branch_A_url, A_url,
-                                        expected_output,
-                                        expected_disk,
-                                        expected_status,
-                                        expected_skip,
-                                        None, None, None, None, None,
-                                        1)
+  #
+  # Note we don't bother checking expected mergeinfo output because
+  # three-way merges record mergeinfo multiple times on the same
+  # path, 'A' in this case.  The first recording is reported as ' U'
+  # but the second is reported as ' G'.  Our expected tree structures
+  # can't handle checking for multiple values for the same key.
+  svntest.actions.run_and_verify_merge(A_path, "2", "3",
+                                       branch_A_url, A_url,
+                                       expected_output,
+                                       None, # expected_mergeinfo_output
+                                       expected_elision_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, None, None, None, None,
+                                       1)
 
 #----------------------------------------------------------------------
 # Regression test for Issue #1297:
@@ -1634,6 +1745,11 @@
   expected_output = svntest.wc.State(branch_path, {
     'newfile' : Item(status='A '),
     })
+  expected_mergeinfo_output = svntest.wc.State(branch_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(branch_path, {
+    })
   expected_disk = wc.State('', {
     'alpha'   : Item("This is the file 'alpha'.\n"),
     'beta'    : Item("This is the file 'beta'.\n"),
@@ -1648,8 +1764,10 @@
   expected_skip = wc.State('', { })
 
   svntest.actions.run_and_verify_merge(branch_path,
-                                       '1', 'HEAD', trunk_url,
+                                       '1', 'HEAD', trunk_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip)
@@ -1723,6 +1841,11 @@
     'Q'      : Item(status='A '),
     'Q/bar'  : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(C_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(C_path, {
+    })
   expected_disk = wc.State('', {
     ''       : Item(props={SVN_PROP_MERGEINFO : '/A/B/F:2'}),
     'Q'      : Item(),
@@ -1740,8 +1863,10 @@
   # Unversioned:
   svntest.main.file_append(os.path.join(C_path, "foo"), "foo")
 
-  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url,
+  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -1762,6 +1887,11 @@
   expected_output = wc.State(C_path, {
     'foo'    : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(C_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(C_path, {
+    })
   expected_disk = wc.State('', {
     ''       : Item(props={SVN_PROP_MERGEINFO : '/A/B/F:2'}),
     'Q'      : Item("foo"),
@@ -1776,8 +1906,10 @@
     'Q/bar' : Item(),
     })
 
-  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url,
+  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -1813,6 +1945,11 @@
 
   expected_output = wc.State(wc_dir, {
     })
+  expected_mergeinfo_output = wc.State(wc_dir, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(wc_dir, {
+    })
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.remove('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau')
   expected_disk.add({
@@ -1829,10 +1966,11 @@
     'iota'   : Item(),
     'A/D/G'  : Item(),
     })
-
   svntest.actions.run_and_verify_merge(wc_dir, '2', '3',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status.copy(wc_dir),
                                        expected_skip,
@@ -1875,6 +2013,11 @@
   svntest.main.file_append(lambda_path, "foo") # unversioned
 
   expected_output = wc.State(wc_dir, { })
+  expected_mergeinfo_output = wc.State(wc_dir, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(wc_dir, {
+    })
   expected_disk.add({
     'A/B/lambda'      : Item("foo"),
     })
@@ -1888,8 +2031,10 @@
   expected_status_short.tweak('', status=' M')
 
   svntest.actions.run_and_verify_merge(wc_dir, '3', '4',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status_short,
                                        expected_skip,
@@ -1909,6 +2054,8 @@
     ''            : Item(verb='Sending'),
     'A/B/lambda'  : Item(verb='Adding'),
     })
+  expected_mergeinfo_output = wc.State(wc_dir, {})
+  expected_elision_output = wc.State(wc_dir, {})
   expected_status.tweak(wc_rev=5)
   expected_status.add({
     'A/B/lambda'  : Item(wc_rev=6, status='  '),
@@ -1930,8 +2077,10 @@
   # By using --ignore-ancestry we disregard the mergeinfo and *really* try to
   # merge into a missing path.  This is another facet of issue #2898.
   svntest.actions.run_and_verify_merge(wc_dir, '3', '4',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status.copy(wc_dir),
                                        expected_skip,
@@ -2002,6 +2151,10 @@
 
   expected_output = wc.State(F_path, {
     })
+  expected_mergeinfo_output = wc.State(F_path, {
+    })
+  expected_elision_output = wc.State(F_path, {
+    })
   expected_disk = wc.State('', {
     })
   expected_status = wc.State(F_path, {
@@ -2016,8 +2169,10 @@
 
   ### Need to real and dry-run separately since real merge notifies Q
   ### twice!
-  svntest.actions.run_and_verify_merge(F_path, '1', '2', F_url,
+  svntest.actions.run_and_verify_merge(F_path, '1', '2', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2029,8 +2184,14 @@
     'foo'   : Item(status='!M', wc_rev=2),
     'Q'     : Item(status='! ', wc_rev='?'),
     })
-  svntest.actions.run_and_verify_merge(F_path, '1', '2', F_url,
+  expected_mergeinfo_output = wc.State(F_path, {
+    ''    : Item(status=' U'),
+    'foo' : Item(status=' U'), # Mergeinfo is set on missing/obstructed files.
+    })
+  svntest.actions.run_and_verify_merge(F_path, '1', '2', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2092,6 +2253,11 @@
   expected_output = wc.State(F_path, {
     'zig'  : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(F_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(F_path, {
+    })
   expected_disk = wc.State('', {
     ''         : Item(props={SVN_PROP_MERGEINFO : '/A/B/E:2'}),
     'zig'      : Item("zig contents", {'foo':'foo_val'}),
@@ -2099,8 +2265,10 @@
   expected_skip = wc.State('', { })
   expected_status = None  # status is optional
 
-  svntest.actions.run_and_verify_merge(F_path, '1', '2', E_url,
+  svntest.actions.run_and_verify_merge(F_path, '1', '2', E_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2247,7 +2415,10 @@
   theta_L_url = sbox.repo_url + '/L/theta'
   svntest.actions.run_and_verify_svn(None,
                                      expected_merge_output(None,
-                                                           'U    theta\n'),
+                                                           ['U    theta\n',
+                                                            ' U   theta\n',
+                                                            ' G   theta\n',],
+                                                           two_url=True),
                                      [],
                                      'merge', theta_J_url, theta_L_url)
   os.chdir(saved_cwd)
@@ -2356,12 +2527,19 @@
         expected_disk_dic[key] = Item('%s/%s' % (target[1], target[2]), {})
 
   expected_output = wc.State(F_path, expected_output_dic)
+  expected_mergeinfo_output = wc.State(F_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(F_path, {
+    })
   expected_disk = wc.State('', expected_disk_dic)
   expected_skip = wc.State('', { })
   expected_status = None  # status is optional
 
-  svntest.actions.run_and_verify_merge(F_path, '1', '2', E_url,
+  svntest.actions.run_and_verify_merge(F_path, '1', '2', E_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2441,6 +2619,11 @@
   expected_output = wc.State(bpath, {
     'f'  : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(bpath, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(bpath, {
+    })
   expected_disk = wc.State('', {
     'f'      : Item("$Revision: 4 $"),
     })
@@ -2451,8 +2634,10 @@
   expected_skip = wc.State(bpath, { })
 
   svntest.actions.run_and_verify_merge(bpath, '2', 'HEAD',
-                                       sbox.repo_url + '/t',
+                                       sbox.repo_url + '/t', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip)
@@ -2552,6 +2737,11 @@
     'foo/new file'   : Item(status='A '),
     'foo/new file 2' : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(C_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(C_path, {
+    })
   expected_disk = wc.State('', {
     ''               : Item(props={SVN_PROP_MERGEINFO : '/A/B/F:2'}),
     'foo' : Item(),
@@ -2565,8 +2755,10 @@
     'foo/new file 2' : Item(status='  ', wc_rev='-', copied='+'),
     })
   expected_skip = wc.State(C_path, { })
-  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url,
+  svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2667,6 +2859,11 @@
     'foo/bar'        : Item(status='A '),
     'foo/bar/new file 3' : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(C_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(C_path, {
+    })
   expected_disk = wc.State('', {
     ''    : Item(props={SVN_PROP_MERGEINFO : '/A/B/F:2-5'}),
     'foo' : Item(),
@@ -2684,8 +2881,10 @@
     'foo/new file'   : Item(status='D ', wc_rev='-', copied='+'),
     })
   expected_skip = wc.State(C_path, { })
-  svntest.actions.run_and_verify_merge(C_path, '2', '5', F_url,
+  svntest.actions.run_and_verify_merge(C_path, '2', '5', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2773,6 +2972,11 @@
     'foo/bar'            : Item(status='A '),
     'foo/bar/new file 3' : Item(status='A '),
     })
+  expected_mergeinfo_output = wc.State(C_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(C_path, {
+    })
   expected_disk = wc.State('', {
     ''    : Item(props={SVN_PROP_MERGEINFO : '/A/B/F:2-5'}),
     'foo' : Item(),
@@ -2789,8 +2993,10 @@
     'foo/new file'       : Item(status='D ', wc_rev=3),
     })
   expected_skip = wc.State(C_path, { })
-  svntest.actions.run_and_verify_merge(C_path, '2', '5', F_url,
+  svntest.actions.run_and_verify_merge(C_path, '2', '5', F_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -2807,6 +3013,7 @@
     'A/C/foo/bar'            : Item(verb='Adding'),
 
     })
+  
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.add({
     'A/B/F/foo'                : Item(status='  ', wc_rev=5),
@@ -2892,7 +3099,7 @@
   # Merge from C to F onto the wc_dir
   # We can't use run_and_verify_merge because it doesn't support this
   # syntax of the merge command.
-  ### TODO: We can use run_and_verify_merge2() here now.
+  ### TODO: We can use run_and_verify_merge() here now.
   expected_output = expected_merge_output(None, "A    " + foo_path + "\n")
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'merge', C_url, F_url, wc_dir)
@@ -2994,7 +3201,11 @@
     'E/alpha'  : Item(status=' C'),
     'E/beta'   : Item(status=' C'),
     })
-
+  expected_mergeinfo_output = wc.State(B2_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(B2_path, {
+    })
   expected_disk = wc.State('', {
     ''         : Item(props={SVN_PROP_MERGEINFO : "/A/B:4"}),
     'E'        : Item(),
@@ -3021,8 +3232,10 @@
   # should have 3 'prej' files left behind, describing prop conflicts:
   extra_files = ['alpha.*\.prej', 'beta.*\.prej', 'dir_conflicts.*\.prej']
 
-  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url,
+  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3118,7 +3331,11 @@
     'E'        : Item(status=' C'),
     'E/alpha'  : Item(status=' C'),
     })
-
+  expected_mergeinfo_output = wc.State(B2_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(B2_path, {
+    })
   expected_disk = wc.State('', {
     ''         : Item(props={SVN_PROP_MERGEINFO : '/A/B:4'}),
     'E'        : Item(),
@@ -3145,8 +3362,10 @@
   # should have 2 'prej' files left behind, describing prop conflicts:
   extra_files = ['alpha.*\.prej', 'dir_conflicts.*\.prej']
 
-  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url,
+  svntest.actions.run_and_verify_merge(B2_path, '3', '4', B_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3177,6 +3396,7 @@
   expected_output = svntest.wc.State(wc_dir, {
     'A/B/E/alpha' : Item(verb='Sending'),
     })
+
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/B/E/alpha', wc_rev=2, status='  ')
   svntest.actions.run_and_verify_commit(wc_dir,
@@ -3187,7 +3407,12 @@
   # Use 'svn merge' to undo the commit.  ('svn merge -r2:1')
   # Result should be a single local-prop-mod.
   expected_output = wc.State(wc_dir, {'A/B/E/alpha'  : Item(status=' U'), })
-
+  expected_mergeinfo_output = wc.State(wc_dir, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(wc_dir, {
+    '' : Item(status=' U'),
+    })
   expected_disk = svntest.main.greek_state.copy()
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
@@ -3196,8 +3421,10 @@
   expected_skip = wc.State('', { })
 
   svntest.actions.run_and_verify_merge(wc_dir, '2', '1',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3210,7 +3437,9 @@
   # Change mind, re-apply the change ('svn merge -r1:2').
   # This should merge cleanly into existing prop-mod, status shows nothing.
   expected_output = wc.State(wc_dir, {'A/B/E/alpha'  : Item(status=' C'), })
-
+  expected_mergeinfo_output = wc.State(wc_dir, {})
+  expected_elision_output = wc.State(wc_dir, {})
+  expected_elision_output = wc.State(wc_dir, {})
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.add({'A/B/E/alpha.prej'
      : Item("Trying to create property 'foo' with value 'foo_val',\n"
@@ -3225,8 +3454,10 @@
   # the merge logic will claim we already have this change (because it
   # was unable to record the previous undoing merge).
   svntest.actions.run_and_verify_merge(wc_dir, '1', '2',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3270,15 +3501,21 @@
 
   # Mark r5 as merged into trunk, to create disparate revision ranges
   # which need to be merged.
-  svntest.actions.run_and_verify_svn(None, [], [],
-                                     'merge', '-c5', '--record-only',
-                                     branch_A_url, A_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[5]],
+                          [' U   ' + A_path + '\n']),
+    [], 'merge', '-c5', '--record-only',
+    branch_A_url, A_path)
 
 
   # Try to merge r4:6 into trunk, without r3.  It should fail.
   expected_output = wc.State(A_path, {
     'mu'       : Item(status='C '),
     })
+  expected_mergeinfo_output = wc.State(A_path, {})
+  expected_elision_output = wc.State(A_path, {
+    })
   expected_disk = wc.State('', {
     'mu'        : Item("This is the file 'mu'.\n"
                        + make_conflict_marker_text("r3\n" * 3, "r4\n" * 3, 4)),
@@ -3324,8 +3561,10 @@
   expected_status.tweak(wc_rev=2)
   expected_skip = wc.State('', { })
   expected_error = "conflicts were produced while merging r3:4"
-  svntest.actions.run_and_verify_merge(A_path, '3', '6', branch_A_url,
+  svntest.actions.run_and_verify_merge(A_path, '3', '6', branch_A_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3400,12 +3639,20 @@
   expected_output = svntest.wc.State(wc_dir, {
     'A/D/G/rho': Item(status='R ')
     })
+  expected_mergeinfo_output = svntest.wc.State(wc_dir, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(wc_dir, {
+    '' : Item(status=' U')
+    })
   expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
   expected_skip = wc.State(wc_dir, { })
   expected_disk.tweak('A/D/G/rho', contents="This is the file 'rho'.\n")
   svntest.actions.run_and_verify_merge(wc_dir, '3', '1',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip)
@@ -3500,12 +3747,20 @@
   expected_output = svntest.wc.State(wc_dir, {
     'A/D/G/rho': Item(status='R ')
     })
+  expected_mergeinfo_output = svntest.wc.State(wc_dir, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(wc_dir, {
+    '' : Item(status=' U')
+    })
   expected_status.tweak('A/D/G/rho', status='R ', copied='+', wc_rev='-')
   expected_skip = wc.State(wc_dir, { })
   expected_disk.tweak('A/D/G/rho', contents="This is the file 'rho'.\n")
   svntest.actions.run_and_verify_merge(wc_dir, '3', '1',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip)
@@ -3568,6 +3823,11 @@
   # Lines changed only by whitespaces - both in local or remote -
   # should be ignored
   expected_output = wc.State(sbox.wc_dir, { file_name : Item(status='G ') })
+  expected_mergeinfo_output = wc.State(sbox.wc_dir, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(sbox.wc_dir, {
+    })
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.tweak(file_name,
                       contents="    Aa\n"
@@ -3580,8 +3840,10 @@
   expected_skip = wc.State('', { })
 
   svntest.actions.run_and_verify_merge(sbox.wc_dir, '2', '3',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3642,6 +3904,11 @@
   # Lines changed only by eolstyle - both in local or remote -
   # should be ignored
   expected_output = wc.State(sbox.wc_dir, { file_name : Item(status='G ') })
+  expected_mergeinfo_output = wc.State(sbox.wc_dir, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(sbox.wc_dir, {
+    })
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.tweak(file_name,
                       contents="Aa\n"
@@ -3654,8 +3921,10 @@
   expected_skip = wc.State('', { })
 
   svntest.actions.run_and_verify_merge(sbox.wc_dir, '2', '3',
-                                       sbox.repo_url,
+                                       sbox.repo_url, None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -3698,6 +3967,11 @@
   expected_output = wc.State(E_path, {
     'alpha'   : Item(status='  ', treeconflict='C'),
     })
+  expected_mergeinfo_output = wc.State(E_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(E_path, {
+    })
   expected_disk = wc.State('', {
     'alpha'   : Item("This is the file 'alpha'.\n"),
     'beta'    : Item("This is the file 'beta'.\n"),
@@ -3709,9 +3983,10 @@
     })
   expected_skip = wc.State(E_path, { })
   svntest.actions.run_and_verify_merge(E_path, '1', '2',
-                                       sbox.repo_url + \
-                                       '/A/C',
+                                       sbox.repo_url + '/A/C', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip)
@@ -3834,12 +4109,18 @@
     expected_backup_status.tweak('A/mu', status='C ')
     expected_backup_status.tweak(wc_rev = cur_rev - 1)
     expected_backup_status.tweak('', status= ' M')
-
+    expected_mergeinfo_output = wc.State(wc_backup, {
+      '' : Item(status=' U'),
+      })
+    expected_elision_output = wc.State(wc_backup, {
+      })
     expected_backup_skip = wc.State('', { })
 
     svntest.actions.run_and_verify_merge(wc_backup, cur_rev - 1, cur_rev,
-                                         sbox.repo_url,
+                                         sbox.repo_url, None,
                                          expected_backup_output,
+                                         expected_mergeinfo_output,
+                                         expected_elision_output,
                                          expected_backup_disk,
                                          expected_backup_status,
                                          expected_backup_skip)
@@ -3889,14 +4170,21 @@
   expected_backup_output = svntest.wc.State(wc_backup, {
     'A/mu' : Item(status='GU'),
     })
+  expected_mergeinfo_output = svntest.wc.State(wc_backup, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(wc_backup, {
+    })
   expected_backup_status = svntest.actions.get_virginal_state(wc_backup, 1)
   expected_backup_status.tweak('', status=' M')
   expected_backup_status.tweak('A/mu', status='MM')
 
   expected_backup_skip = wc.State('', { })
 
-  svntest.actions.run_and_verify_merge(wc_backup, '1', '2', sbox.repo_url,
+  svntest.actions.run_and_verify_merge(wc_backup, '1', '2', sbox.repo_url, None,
                                        expected_backup_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_backup_disk,
                                        expected_backup_status,
                                        expected_backup_skip)
@@ -3916,14 +4204,19 @@
   expected_backup_output = svntest.wc.State(wc_backup, {
     'A/mu' : Item(status='GU'),
     })
+  expected_mergeinfo_output = svntest.wc.State(wc_backup, {
+    '' : Item(status=' G'),
+    })
   expected_backup_status = svntest.actions.get_virginal_state(wc_backup, 1)
   expected_backup_status.tweak('', status=' M')
   expected_backup_status.tweak('A/mu', status='MM')
-  svntest.actions.run_and_verify_merge(wc_backup, '2', '3', sbox.repo_url,
-                                        expected_backup_output,
-                                        expected_backup_disk,
-                                        expected_backup_status,
-                                        expected_backup_skip)
+  svntest.actions.run_and_verify_merge(wc_backup, '2', '3', sbox.repo_url, None,
+                                       expected_backup_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_backup_disk,
+                                       expected_backup_status,
+                                       expected_backup_skip)
 
   # Test 3: now delete the eol-style property and commit, merge this revision
   # in the still changed mu in the second working copy; there should be no
@@ -3944,8 +4237,10 @@
   expected_backup_status = svntest.actions.get_virginal_state(wc_backup, 1)
   expected_backup_status.tweak('', status=' M')
   expected_backup_status.tweak('A/mu', status='M ')
-  svntest.actions.run_and_verify_merge(wc_backup, '3', '4', sbox.repo_url,
+  svntest.actions.run_and_verify_merge(wc_backup, '3', '4', sbox.repo_url, None,
                                        expected_backup_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_backup_disk,
                                        expected_backup_status,
                                        expected_backup_skip)
@@ -4086,6 +4381,11 @@
   expected_output = wc.State(copy_of_B_path, {
     'F/E/alpha'   : Item(status='U '),
     })
+  expected_mergeinfo_output = wc.State(copy_of_B_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(copy_of_B_path, {
+    })
   expected_status = wc.State(copy_of_B_path, {
     ''           : Item(status=' M', wc_rev=5),
     'F/E'        : Item(status='  ', wc_rev=5),
@@ -4111,9 +4411,10 @@
   expected_skip = wc.State(copy_of_B_path, { })
 
   svntest.actions.run_and_verify_merge(copy_of_B_path, '4', '5',
-                                       sbox.repo_url + \
-                                       '/A/B',
+                                       sbox.repo_url + '/A/B', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4146,9 +4447,15 @@
     'alpha' : Item(status='  ', wc_rev=6),
     'beta'  : Item(status='  ', wc_rev=6),
     })
-  svntest.actions.run_and_verify_svn(None, [], [], 'merge', '-r4:5',
-                                    sbox.repo_url + '/A/B/F/E',
-                                     copy_of_B_F_E_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[5]],
+                          [' U   ' + copy_of_B_F_E_path + '\n',
+                           ' G   ' + copy_of_B_F_E_path + '\n'],
+                          elides=True),
+    [], 'merge', '-r4:5',
+    sbox.repo_url + '/A/B/F/E',
+    copy_of_B_F_E_path)
   svntest.actions.run_and_verify_status(copy_of_B_F_E_path,
                                         expected_status)
 
@@ -4195,6 +4502,10 @@
     expected_output = wc.State(path_name, {
       'alpha'   : Item(status='U '),
       })
+    expected_mergeinfo_output = wc.State(path_name, {
+      '' : Item(status=' U'),
+      })
+    expected_elision_output = wc.State(path_name, {})
     expected_status = wc.State(path_name, {
       ''      : Item(status=' M', wc_rev=4),
       'alpha' : Item(status='M ', wc_rev=4),
@@ -4208,8 +4519,10 @@
     expected_skip = wc.State(path_name, { })
 
     svntest.actions.run_and_verify_merge(path_name, '4', '5',
-                                         sbox.repo_url + '/A/B/F/E',
+                                         sbox.repo_url + '/A/B/F/E', None,
                                          expected_output,
+                                         expected_mergeinfo_output,
+                                         expected_elision_output,
                                          expected_disk,
                                          expected_status,
                                          expected_skip,
@@ -4254,6 +4567,13 @@
   expected_output = wc.State(copy_of_B_path, {
     'F/E/alpha' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(copy_of_B_path, {
+    ''    : Item(status=' U'),
+    'F/E' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(copy_of_B_path, {
+    'F/E' : Item(status=' U')
+    })
   expected_status = wc.State(copy_of_B_path, {
     # The subtree mergeinfo on F/E1 is not updated because
     # this merge does not affect that subtree.
@@ -4281,8 +4601,10 @@
     })
   expected_skip = wc.State(copy_of_B_path, { })
   svntest.actions.run_and_verify_merge(copy_of_B_path, '4', '8',
-                                       sbox.repo_url + '/A/B',
+                                       sbox.repo_url + '/A/B', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4310,6 +4632,12 @@
   # mergeinfo on A/copy-of-B/F/E1 remains unchanged as that subtree was
   # untouched by the merge.
   expected_output = wc.State(copy_of_B_F_path, {})
+  expected_mergeinfo_output = wc.State(copy_of_B_F_path, {
+    ''  : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(copy_of_B_F_path, {
+    'E' : Item(status=' U')
+    })
   expected_status = wc.State(copy_of_B_F_path, {
     ''         : Item(status=' M', wc_rev=8),
     'E'        : Item(status=' M', wc_rev=8),
@@ -4331,8 +4659,10 @@
     })
   expected_skip = wc.State(copy_of_B_F_path, { })
   svntest.actions.run_and_verify_merge(copy_of_B_F_path, '4', '5',
-                                       sbox.repo_url + '/A/B/F',
+                                       sbox.repo_url + '/A/B/F', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4374,15 +4704,12 @@
   if sys.platform == 'win32':
     merge_url = merge_url.replace('\\', '/')
 
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[new_rev]],
-                                                           'U    ' +
-                                                           dst_path +
-                                                           '\n'),
-                                     [],
-                                     'merge', '-c', str(new_rev),
-                                     merge_url,
-                                     dst_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[new_rev]],
+                          ['U    ' + dst_path + '\n',
+                           ' U   ' + dst_path + '\n']),
+    [], 'merge', '-c', str(new_rev), merge_url, dst_path)
 
   svntest.actions.run_and_verify_status(dst_path, expected_status)
 
@@ -4461,7 +4788,11 @@
   expected_output = wc.State(copy_of_A_D_path, {
     'umlaut'  : Item(status='A '),
     })
-
+  expected_mergeinfo_output = wc.State(copy_of_A_D_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(copy_of_A_D_path, {
+    })
   # No subtree with explicit mergeinfo is affected by this merge, so they
   # all remain unchanged from before the merge.  The only mergeinfo updated
   # is that on the target 'A/copy-of-D.
@@ -4505,8 +4836,10 @@
   svntest.actions.run_and_verify_merge(copy_of_A_D_path,
                                        2,
                                        str(rev_to_merge_to_copy_of_D),
-                                       sbox.repo_url + '/A/D',
+                                       sbox.repo_url + '/A/D', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4694,6 +5027,11 @@
   expected_output = wc.State(D_COPY_path, {
     'G/rho' : Item(status='U '),
     })
+  expected_mergeinfo_output = wc.State(D_COPY_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(D_COPY_path, {
+    })
   expected_status = wc.State(D_COPY_path, {
     ''        : Item(status=' M', wc_rev=2),
     'G'       : Item(status='  ', wc_rev=2),
@@ -4722,9 +5060,10 @@
     })
   expected_skip = wc.State(D_COPY_path, { })
   svntest.actions.run_and_verify_merge(D_COPY_path, '3', '4',
-                                       sbox.repo_url + \
-                                       '/A/D',
+                                       sbox.repo_url + '/A/D', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4736,6 +5075,13 @@
   # should not be repeated.  We test issue #2734 here with (with a
   # directory as the merge target).
   expected_output = wc.State(G_COPY_path, { })
+  # A_COPY/D/G gets mergeinfo set, but it immediately elides to A_COPY/D.
+  expected_mergeinfo_output = wc.State(G_COPY_path, {
+    '' : Item(status=' G'),
+    })
+  expected_elision_output = wc.State(G_COPY_path, {
+    '' : Item(status=' U'),
+    })
   expected_status = wc.State(G_COPY_path, {
     ''    : Item(status='  ', wc_rev=2),
     'pi'  : Item(status='  ', wc_rev=2),
@@ -4749,9 +5095,10 @@
     })
   expected_skip = wc.State(G_COPY_path, { })
   svntest.actions.run_and_verify_merge(G_COPY_path, '3', '4',
-                                       sbox.repo_url + \
-                                       '/A/D/G',
+                                       sbox.repo_url + '/A/D/G', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4763,6 +5110,11 @@
   expected_output = wc.State(B_COPY_path, {
     'E/beta' : Item(status='U '),
     })
+  expected_mergeinfo_output = wc.State(B_COPY_path, {
+    '' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(B_COPY_path, {
+    })
   expected_status = wc.State(B_COPY_path, {
     ''        : Item(status=' M', wc_rev=2),
     'E'       : Item(status='  ', wc_rev=2),
@@ -4782,9 +5134,10 @@
   expected_skip = wc.State(B_COPY_path, { })
 
   svntest.actions.run_and_verify_merge(B_COPY_path, '4', '5',
-                                       sbox.repo_url + \
-                                       '/A/B',
+                                       sbox.repo_url + '/A/B', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4817,6 +5170,12 @@
   expected_output = wc.State(A_COPY_path, {
     'D/H/psi'   : Item(status='U '),
     })
+  expected_mergeinfo_output = wc.State(A_COPY_path, {
+    ''  : Item(status=' U'),
+    'D' : Item(status=' G'),
+    })
+  expected_elision_output = wc.State(A_COPY_path, {
+    })
   expected_status = wc.State(A_COPY_path, {
     ''          : Item(status=' M', wc_rev=2),
     'B'         : Item(status=' M', wc_rev=2),
@@ -4861,9 +5220,10 @@
     })
   expected_skip = wc.State(A_COPY_path, { })
   svntest.actions.run_and_verify_merge(A_COPY_path, '2', '3',
-                                       sbox.repo_url + \
-                                       '/A',
+                                       sbox.repo_url + '/A', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4876,12 +5236,14 @@
   expected_skip = wc.State(omega_COPY_path, { })
   # run_and_verify_merge doesn't support merging to a file WCPATH
   # so use run_and_verify_svn.
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[6]],
-                                       'U    ' + omega_COPY_path + '\n'),
-                                     [], 'merge', '-c6',
-                                     sbox.repo_url + '/A/D/H/omega',
-                                     omega_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[6]],
+                          ['U    ' + omega_COPY_path + '\n',
+                           ' G   ' + omega_COPY_path + '\n']),
+    [], 'merge', '-c6',
+    sbox.repo_url + '/A/D/H/omega',
+    omega_COPY_path)
 
   # Check that mergeinfo was properly set on A_COPY/D/H/omega
   svntest.actions.run_and_verify_svn(None,
@@ -4938,6 +5300,11 @@
   # '/A:3' so this empty mergeinfo is needed to override that.
   expected_output = wc.State(other_wc,
                              {'beta' : Item(status='U ')})
+  expected_mergeinfo_output = wc.State(other_wc, {
+    '' : Item(status=' G')
+    })
+  expected_elision_output = wc.State(other_wc, {
+    })
   expected_status = wc.State(other_wc, {
     ''      : Item(status=' M', wc_rev=7),
     'alpha' : Item(status='  ', wc_rev=7),
@@ -4951,9 +5318,10 @@
   expected_skip = wc.State(other_wc, { })
 
   svntest.actions.run_and_verify_merge(other_wc, '5', '4',
-                                       sbox.repo_url + \
-                                       '/A/B/E',
+                                       sbox.repo_url + '/A/B/E', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -4985,12 +5353,14 @@
 
   # run_and_verify_merge doesn't support merging to a file WCPATH
   # so use run_and_verify_svn.
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[5]],
-                                       'U    ' + beta_COPY_path + '\n'),
-                                     [], 'merge', '-c5',
-                                     sbox.repo_url + '/A/B/E/beta',
-                                     beta_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[5]],
+                          ['U    ' + beta_COPY_path + '\n',
+                           ' U   ' + beta_COPY_path + '\n']),
+    [], 'merge', '-c5',
+    sbox.repo_url + '/A/B/E/beta',
+    beta_COPY_path)
 
   # Check beta's status and props.
   expected_status = wc.State(beta_COPY_path, {
@@ -5022,6 +5392,11 @@
   expected_output = wc.State(G_COPY_path, {
     'rho' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(G_COPY_path, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(G_COPY_path, {
+    })
   expected_status = wc.State(G_COPY_path, {
     ''    : Item(status=' M', wc_rev=7),
     'pi'  : Item(status='  ', wc_rev=7),
@@ -5037,9 +5412,10 @@
   expected_skip = wc.State(G_COPY_path, { })
 
   svntest.actions.run_and_verify_merge(G_COPY_path, '3', '4',
-                                       sbox.repo_url + \
-                                       '/A/D/G',
+                                       sbox.repo_url + '/A/D/G', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -5051,6 +5427,11 @@
   expected_output = wc.State(A_COPY_path, {
     'D/H/omega' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_path, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(A_COPY_path, {
+    })
   expected_status = wc.State(A_COPY_path, {
     ''          : Item(status=' M', wc_rev=7),
     'B'         : Item(status='  ', wc_rev=7),
@@ -5096,9 +5477,10 @@
     })
   expected_skip = wc.State(A_COPY_path, { })
   svntest.actions.run_and_verify_merge(A_COPY_path, '3', '6',
-                                       sbox.repo_url + \
-                                       '/A',
+                                       sbox.repo_url + '/A', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -5115,13 +5497,25 @@
 
   # to A_COPY.
   expected_output = wc.State(A_COPY_path, {})
+  expected_mergeinfo_output = wc.State(A_COPY_path, {
+    ''         : Item(status=' G'),
+    'D/G'      : Item(status=' G'),
+    'B/E/beta' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(A_COPY_path, {
+    })
+  expected_elision_output = wc.State(A_COPY_path, {
+    'B/E/beta' : Item(status=' U'),
+    'D/G'      : Item(status=' U'),
+    })
   expected_status.tweak('B/E/beta', status=' M')
   expected_status.tweak('D/G', status='  ')
   expected_disk.tweak('B/E/beta', 'D/G', props={})
   svntest.actions.run_and_verify_merge(A_COPY_path, '3', '6',
-                                       sbox.repo_url + \
-                                       '/A',
+                                       sbox.repo_url + '/A', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -5135,12 +5529,14 @@
 
   # run_and_verify_merge doesn't support merging to a file WCPATH
   # so use run_and_verify_svn.
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[-5]],
-                                       'U    ' + beta_COPY_path + '\n'),
-                                     [], 'merge', '-c-5',
-                                     sbox.repo_url + '/A/B/E/beta',
-                                     beta_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[-5]],
+                          ['U    ' + beta_COPY_path + '\n',
+                           ' G   ' + beta_COPY_path + '\n']),
+    [], 'merge', '-c-5',
+    sbox.repo_url + '/A/B/E/beta',
+    beta_COPY_path)
 
   # Check beta's status and props.
   expected_status = wc.State(beta_COPY_path, {
@@ -5157,12 +5553,16 @@
   # mergeinfo (A_COPY) and so the former should elide.
   # run_and_verify_merge doesn't support merging to a file WCPATH
   # so use run_and_verify_svn.
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[5]],
-                                      'G    ' + beta_COPY_path + '\n'),
-                                     [], 'merge', '-c5',
-                                     sbox.repo_url + '/A/B/E/beta',
-                                     beta_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[5]],
+                          ['G    ' + beta_COPY_path + '\n',
+                           ' G   ' + beta_COPY_path + '\n',   # Update mergeinfo
+                           ' U   ' + beta_COPY_path + '\n',], # Elide mereginfo,
+                          elides=True),
+    [], 'merge', '-c5',
+    sbox.repo_url + '/A/B/E/beta',
+    beta_COPY_path)
 
   # Check beta's status and props.
   expected_status = wc.State(beta_COPY_path, {
@@ -5201,10 +5601,12 @@
   saved_cwd = os.getcwd()
 
   os.chdir(A_COPY_path)
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[4]], 'U    ' +
-                                       os.path.join("D", "G", "rho") + '\n'),
-                                     [], 'merge', '-c4', A_url)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[4]],
+                          ['U    ' + os.path.join("D", "G", "rho") + '\n',
+                           ' U   .\n']),
+    [], 'merge', '-c4', A_url)
   os.chdir(saved_cwd)
 
   # Check the results of the merge.
@@ -5224,6 +5626,11 @@
     'H/psi'   : Item(status='U '),
     'H/omega' : Item(status='U '),
     })
+  expected_mergeinfo_output = wc.State(D_COPY_path, {
+    '' : Item(status=' G'),
+    })
+  expected_elision_output = wc.State(D_COPY_path, {
+    })
   expected_status = wc.State(D_COPY_path, {
     ''        : Item(status=' M', wc_rev=2),
     'G'       : Item(status='  ', wc_rev=2),
@@ -5251,8 +5658,10 @@
   expected_skip = wc.State(D_COPY_path, { })
 
   svntest.actions.run_and_verify_merge(D_COPY_path, '2', '6',
-                                       sbox.repo_url + '/A/D',
+                                       sbox.repo_url + '/A/D', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -5318,18 +5727,24 @@
                                         None, None, 1)
 
   # Merge r4 into A_COPY/D/G/rho_copy.
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[4]],
-                                       'U    ' + rho_COPY_COPY_path +
-                                       '\n'),
-                                     [], 'merge', '-c4',
-                                     sbox.repo_url + '/A/D/G/rho',
-                                     rho_COPY_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[4]],
+                          ['U    ' + rho_COPY_COPY_path + '\n',
+                           ' U   ' + rho_COPY_COPY_path + '\n']),
+    [], 'merge', '-c4',
+    sbox.repo_url + '/A/D/G/rho',
+    rho_COPY_COPY_path)
 
   # Merge r3:5 into A_COPY/D/G.
   expected_output = wc.State(G_COPY_path, {
     'rho' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(G_COPY_path, {
+    ''         : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(G_COPY_path, {
+    })
   expected_status = wc.State(G_COPY_path, {
     ''         : Item(status=' M', wc_rev=7),
     'pi'       : Item(status='  ', wc_rev=7),
@@ -5347,9 +5762,10 @@
     })
   expected_skip = wc.State(G_COPY_path, { })
   svntest.actions.run_and_verify_merge(G_COPY_path, '3', '5',
-                                       sbox.repo_url + \
-                                       '/A/D/G',
+                                       sbox.repo_url + '/A/D/G', None,
                                        expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
                                        expected_disk,
                                        expected_status,
                                        expected_skip,
@@ -5446,6 +5862,11 @@
   expected_output = wc.State(A_COPY_D_G_path, {
     'rho' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_D_G_path, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(A_COPY_D_G_path, {
+    })
   # Note: A_COPY/D/G won't show as switched.
   expected_status = wc.State(A_COPY_D_G_path, {
     ''         : Item(status=' M', wc_rev=8),
@@ -5463,8 +5884,11 @@
   expected_skip = wc.State(A_COPY_D_G_path, { })
 
   svntest.actions.run_and_verify_merge(A_COPY_D_G_path, '7', '8',
-                                       sbox.repo_url + '/A/D/G_COPY',
-                                       expected_output, expected_disk,
+                                       sbox.repo_url + '/A/D/G_COPY', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
                                        expected_status, expected_skip,
                                        None, None, None, None, None, 1)
 
@@ -5493,12 +5917,15 @@
                                       "' set on '" + A_COPY_D_path+ "'" +
                                       "\n"], [], 'ps', SVN_PROP_MERGEINFO,
                                      '/A/D:4', A_COPY_D_path)
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[-4]],
-                                       'U    ' + A_COPY_D_G_rho_path + '\n'),
-                                     [], 'merge', '-c-4',
-                                     sbox.repo_url + '/A/D/G_COPY',
-                                     A_COPY_D_G_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[-4]],
+                          ['U    ' + A_COPY_D_G_rho_path + '\n',
+                           ' U   ' + A_COPY_D_G_path + '\n'],
+                          elides=True),
+    [], 'merge', '-c-4',
+    sbox.repo_url + '/A/D/G_COPY',
+    A_COPY_D_G_path)
   wc_status.tweak("A_COPY/D", status=' M')
   wc_status.tweak("A_COPY/D/G/rho", status='M ')
   wc_status.tweak(wc_rev=8)
@@ -5605,7 +6032,13 @@
   # by the merge but won't inherit r8 from A_COPY/D/H, so it needs its
   # own mergeinfo.
   expected_output = wc.State(A_COPY_H_path, {
-    'omega' : Item(status='U ')
+    'omega' : Item(status='U '),
+    })
+  expected_mergeinfo_output = wc.State(A_COPY_H_path, {
+    ''      : Item(status=' U'),
+    'omega' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(A_COPY_H_path, {
     })
   expected_status = wc.State(A_COPY_H_path, {
     ''      : Item(status=' M', wc_rev=8),
@@ -5623,8 +6056,11 @@
   expected_skip = wc.State(A_COPY_H_path, { })
 
   svntest.actions.run_and_verify_merge(A_COPY_H_path, '7', '8',
-                                       sbox.repo_url + '/A/D/H',
-                                       expected_output, expected_disk,
+                                       sbox.repo_url + '/A/D/H', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
                                        expected_status, expected_skip,
                                        None, None, None, None, None, 1)
 
@@ -5637,6 +6073,13 @@
   expected_output = wc.State(A_COPY_D_path, {
     'G/rho' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_D_path, {
+    ''      : Item(status=' U'),
+    'G'     : Item(status=' U'),
+    'G/rho' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(A_COPY_D_path, {
+    })
   expected_status_D = wc.State(A_COPY_D_path, {
     ''        : Item(status=' M', wc_rev=8),
     'H'       : Item(status=' M', wc_rev=8),
@@ -5665,8 +6108,11 @@
     })
   expected_skip_D = wc.State(A_COPY_D_path, { })
   svntest.actions.run_and_verify_merge(A_COPY_D_path, '5', '6',
-                                       sbox.repo_url + '/A/D',
-                                       expected_output, expected_disk_D,
+                                       sbox.repo_url + '/A/D', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk_D,
                                        expected_status_D, expected_skip_D,
                                        None, None, None, None, None, 1)
 
@@ -5678,25 +6124,38 @@
   # A_COPY/D/H/psi is added because that path is switched.
   expected_output = wc.State(A_COPY_D_path, {
     'H/psi' : Item(status='U ')})
+  expected_mergeinfo_output = wc.State(A_COPY_D_path, {
+    ''      : Item(status=' G'),
+    'H'     : Item(status=' G'),
+    'H/psi' : Item(status=' G')
+    })
+  expected_elision_output = wc.State(A_COPY_D_path, {
+    })
   expected_disk_D.tweak('', props={SVN_PROP_MERGEINFO : '/A/D:5-6*'})
   expected_disk_D.tweak('H', props={SVN_PROP_MERGEINFO : '/A/D/H:5*,8*'})
   expected_disk_D.tweak('H/psi', contents="New content",
                         props={SVN_PROP_MERGEINFO :'/A/D/H/psi:5'})
   expected_status_D.tweak('H/psi', status='MM')
   svntest.actions.run_and_verify_merge(A_COPY_D_path, '4', '5',
-                                       sbox.repo_url + '/A/D',
-                                       expected_output, expected_disk_D,
+                                       sbox.repo_url + '/A/D', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk_D,
                                        expected_status_D, expected_skip_D,
                                        None, None, None, None, None, 1)
 
-  # Finally, merge r4:8 into A_COPY.  A_COPY gets r5-8 added and every path
-  # under it with with explicit mergeinfo gets r5,7 added (they all have r6,8
-  # already).  Again there is no elision, since the only possibilities, e.g.
-  # A_COPY/D/H's '/A/D/H:1,5-8*' to A_COPY/D's '/A/D:1,5-8*', involve
-  # non-inheritable mergeinfo one ond side or the other.
+  # Finally, merge r4:8 into A_COPY.  A_COPY gets mergeinfo for r5-8 added but
+  # since none of A_COPY's subtrees with mergeinfo are affected, none of them
+  # get any mergeinfo changes.
   expected_output = wc.State(A_COPY_path, {
     'B/E/beta' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_path, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(A_COPY_path, {
+    })
   expected_status = wc.State(A_COPY_path, {
     ''          : Item(status=' M', wc_rev=8),
     'B'         : Item(status='  ', wc_rev=8),
@@ -5744,8 +6203,11 @@
     })
   expected_skip = wc.State(A_COPY_path, { })
   svntest.actions.run_and_verify_merge(A_COPY_path, '4', '8',
-                                       sbox.repo_url + '/A',
-                                       expected_output, expected_disk,
+                                       sbox.repo_url + '/A', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
                                        expected_status, expected_skip,
                                        None, None, None, None, None, 1)
 
@@ -5808,6 +6270,13 @@
   expected_output = wc.State(A_COPY_H_path, {
     'psi' : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_H_path, {
+    ''    : Item(status=' U'),
+    'psi' : Item(status=' G')
+    })
+  expected_elision_output = wc.State(A_COPY_H_path, {
+    'psi' : Item(status=' U')
+    })
   expected_status = wc.State(A_COPY_H_path, {
     ''      : Item(status=' M', wc_rev=9),
     'psi'   : Item(status='M ', wc_rev=9),
@@ -5823,8 +6292,11 @@
     })
   expected_skip = wc.State(A_COPY_H_path, { })
   svntest.actions.run_and_verify_merge(A_COPY_H_path, '4', '8',
-                                       sbox.repo_url + '/A/D/H',
-                                       expected_output, expected_disk,
+                                       sbox.repo_url + '/A/D/H', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
                                        expected_status, expected_skip,
                                        None, None, None, None, None, 1)
 
@@ -5851,6 +6323,11 @@
   expected_output = wc.State(A_COPY_D_path, {
     '' : Item(status=' U')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_D_path, {
+    '' : Item(status=' U')
+    })
+  expected_elision_output = wc.State(A_COPY_D_path, {
+    })
   # Reuse expected status and disk from last merge to A_COPY/D
   expected_status_D.tweak(status='  ')
   expected_status_D.tweak('', status=' M', wc_rev=9)
@@ -5868,15 +6345,26 @@
                         props={SVN_PROP_MERGEINFO : '/A/D/H/omega:8'})
   expected_disk_D.tweak('H/psi', contents="New content", props={})
   svntest.actions.run_and_verify_merge(A_COPY_D_path, '9', '10',
-                                       sbox.repo_url + '/A/D',
-                                       expected_output, expected_disk_D,
+                                       sbox.repo_url + '/A/D', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk_D,
                                        expected_status_D, expected_skip_D,
                                        None, None, None, None, None, 1)
-  # Repeated merge is a no-op.
+  # Repeated merge is a no-op, though we still see the notification reporting
+  # the mergeinfo describing the merge has been recorded, though this time it
+  # is a ' G' notification because there is a local mergeinfo change.
   expected_output = wc.State(A_COPY_D_path, {})
+  expected_mergeinfo_output = wc.State(A_COPY_D_path, {
+    '' : Item(status=' G')
+    })
   svntest.actions.run_and_verify_merge(A_COPY_D_path, '9', '10',
-                                       sbox.repo_url + '/A/D',
-                                       expected_output, expected_disk_D,
+                                       sbox.repo_url + '/A/D', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk_D,
                                        expected_status_D, expected_skip_D,
                                        None, None, None, None, None, 1)
 
@@ -5905,6 +6393,22 @@
     'D/H/omega' : Item(status='U '),
     'D/H/psi'   : Item(status='U ')
     })
+  expected_mergeinfo_output = wc.State(A_COPY_path, {
+    ''          : Item(status=' U'),
+    'D'         : Item(status=' U'),
+    'D/G'       : Item(status=' U'),
+    'D/G/rho'   : Item(status=' U'),
+    'D/H'       : Item(status=' U'),
+    'D/H/omega' : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(A_COPY_path, {
+    ''          : Item(status=' U'),
+    'D'         : Item(status=' U'),
+    'D/G'       : Item(status=' U'),
+    'D/G/rho'   : Item(status=' U'),
+    'D/H'       : Item(status=' U'),
+    'D/H/omega' : Item(status=' U'),
+    })
   expected_status = wc.State(A_COPY_path, {
     ''          : Item(status=' M', wc_rev=10),
     'B'         : Item(status='  ', wc_rev=10),
@@ -5927,7 +6431,6 @@
     'D/H/omega' : Item(status='MM', wc_rev=10),
     })
   expected_disk = wc.State('', {
-#    ''          : Item(),
     'B'         : Item(),

[... 3578 lines stripped ...]