You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2011/10/11 21:52:46 UTC

svn commit: r1182053 [26/30] - in /subversion/branches/svn_mutex: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/hook-scripts/enforcer/ contrib/server-side/ notes/ notes/merge-t...

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/diff_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/diff_tests.py Tue Oct 11 19:52:34 2011
@@ -83,66 +83,99 @@ def make_git_diff_header(target_path, re
   else:
     dst_label = ''
 
+  output = [
+    "Index: " + path_as_shown + "\n",
+    "===================================================================\n"
+  ]
   if add:
-    output = [
-      "Index: " + path_as_shown + "\n",
-      "===================================================================\n",
+    output.extend([
       "diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
       "new file mode 10644\n",
-    ]
+    ])
     if text_changes:
       output.extend([
         "--- /dev/null\t(" + old_tag + ")\n",
         "+++ b/" + repos_relpath + dst_label + "\t(" + new_tag + ")\n"
       ])
   elif delete:
-    output = [
-      "Index: " + path_as_shown + "\n",
-      "===================================================================\n",
+    output.extend([
       "diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
       "deleted file mode 10644\n",
-    ]
+    ])
     if text_changes:
       output.extend([
         "--- a/" + repos_relpath + src_label + "\t(" + old_tag + ")\n",
         "+++ /dev/null\t(" + new_tag + ")\n"
       ])
   elif cp:
-    output = [
-      "Index: " + path_as_shown + "\n",
-      "===================================================================\n",
+    output.extend([
       "diff --git a/" + copyfrom_path + " b/" + repos_relpath + "\n",
       "copy from " + copyfrom_path + "\n",
       "copy to " + repos_relpath + "\n",
-    ]
+    ])
     if text_changes:
       output.extend([
         "--- a/" + copyfrom_path + src_label + "\t(" + old_tag + ")\n",
         "+++ b/" + repos_relpath + "\t(" + new_tag + ")\n"
       ])
   elif mv:
-    return [
-      "Index: " + path_as_shown + "\n",
-      "===================================================================\n",
+    output.extend([
       "diff --git a/" + copyfrom_path + " b/" + path_as_shown + "\n",
       "rename from " + copyfrom_path + "\n",
       "rename to " + repos_relpath + "\n",
-    ]
+    ])
     if text_changes:
       output.extend([
         "--- a/" + copyfrom_path + src_label + "\t(" + old_tag + ")\n",
         "+++ b/" + repos_relpath + "\t(" + new_tag + ")\n"
       ])
   else:
-    output = [
-      "Index: " + path_as_shown + "\n",
-      "===================================================================\n",
+    output.extend([
       "diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
       "--- a/" + repos_relpath + src_label + "\t(" + old_tag + ")\n",
       "+++ b/" + repos_relpath + dst_label + "\t(" + new_tag + ")\n",
-    ]
+    ])
   return output
 
+def make_diff_prop_header(path):
+  """Return a property diff sub-header, as a list of newline-terminated
+     strings."""
+  return [
+    "\n",
+    "Property changes on: " + path.replace('\\', '/') + "\n",
+    "___________________________________________________________________\n"
+  ]
+
+def make_diff_prop_deleted(pname, pval):
+  """Return a property diff for deletion of property PNAME, old value PVAL.
+     PVAL is a single string with no embedded newlines.  Return the result
+     as a list of newline-terminated strings."""
+  return [
+    "Deleted: " + pname + "\n",
+    "## -1 +0,0 ##\n",
+    "-" + pval + "\n"
+  ]
+
+def make_diff_prop_added(pname, pval):
+  """Return a property diff for addition of property PNAME, new value PVAL.
+     PVAL is a single string with no embedded newlines.  Return the result
+     as a list of newline-terminated strings."""
+  return [
+    "Added: " + pname + "\n",
+    "## -0,0 +1 ##\n",
+    "+" + pval + "\n"
+  ]
+
+def make_diff_prop_modified(pname, pval1, pval2):
+  """Return a property diff for modification of property PNAME, old value
+     PVAL1, new value PVAL2.  PVAL is a single string with no embedded
+     newlines.  Return the result as a list of newline-terminated strings."""
+  return [
+    "Modified: " + pname + "\n",
+    "## -1 +1 ##\n",
+    "-" + pval1 + "\n",
+    "+" + pval2 + "\n"
+  ]
 
 ######################################################################
 # Diff output checker
@@ -734,29 +767,20 @@ def diff_only_property_change(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  expected_output = [
-    "Index: iota\n",
-    "===================================================================\n",
-    "--- iota\t(revision 1)\n",
-    "+++ iota\t(revision 2)\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Added: svn:eol-style\n",
-    "## -0,0 +1 ##\n",
-    "+native\n" ]
-
-  expected_reverse_output = list(expected_output)
-  expected_reverse_output[2] = expected_reverse_output[2].replace("1", "2")
-  expected_reverse_output[3] = expected_reverse_output[3].replace("2", "1")
-  expected_reverse_output[7] = expected_reverse_output[7].replace("Added",
-                                                                  "Deleted")
-  expected_reverse_output[8] = "## -1 +0,0 ##\n"
-  expected_reverse_output[9] = "-native\n"
-
-  expected_rev1_output = list(expected_output)
-  expected_rev1_output[3] = expected_rev1_output[3].replace("revision 2",
-                                                            "working copy")
+  expected_output = \
+    make_diff_header("iota", "revision 1", "revision 2") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("svn:eol-style", "native")
+
+  expected_reverse_output = \
+    make_diff_header("iota", "revision 2", "revision 1") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_deleted("svn:eol-style", "native")
+
+  expected_rev1_output = \
+    make_diff_header("iota", "revision 1", "working copy") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("svn:eol-style", "native")
 
   os.chdir(sbox.wc_dir)
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -2025,33 +2049,17 @@ def diff_property_changes_to_base(sbox):
   wc_dir = sbox.wc_dir
 
 
-  add_diff = [
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Added: dirprop\n",
-    "## -0,0 +1 ##\n",
-    "+r2value\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Added: fileprop\n",
-    "## -0,0 +1 ##\n",
-    "+r2value\n"]
-
-  del_diff = [
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Deleted: dirprop\n",
-    "## -1 +0,0 ##\n",
-    "-r2value\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Deleted: fileprop\n",
-    "## -1 +0,0 ##\n",
-    "-r2value\n"]
+  add_diff = \
+    make_diff_prop_header("A") + \
+    make_diff_prop_added("dirprop", "r2value") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("fileprop", "r2value")
+
+  del_diff = \
+    make_diff_prop_header("A") + \
+    make_diff_prop_deleted("dirprop", "r2value") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_deleted("fileprop", "r2value")
 
 
   expected_output_r1_r2 = list(make_diff_header('A', 'revision 1', 'revision 2')
@@ -2287,35 +2295,15 @@ def diff_prop_change_local_propmod(sbox)
 
   sbox.build()
 
-  expected_output_r2_wc = [
-    "Index: A\n",
-    "===================================================================\n",
-    "--- A\t(revision 2)\n",
-    "+++ A\t(working copy)\n",
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Modified: dirprop\n",
-    "## -1 +1 ##\n",
-    "-r2value\n",
-    "+workingvalue\n",
-    "Added: newdirprop\n",
-    "## -0,0 +1 ##\n",
-    "+newworkingvalue\n",
-    "Index: iota\n",
-    "===================================================================\n",
-    "--- iota\t(revision 2)\n",
-    "+++ iota\t(working copy)\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Modified: fileprop\n",
-    "## -1 +1 ##\n",
-    "-r2value\n",
-    "+workingvalue\n",
-    "Added: newfileprop\n",
-    "## -0,0 +1 ##\n",
-    "+newworkingvalue\n" ]
+  expected_output_r2_wc = \
+    make_diff_header("A", "revision 2", "working copy") + \
+    make_diff_prop_header("A") + \
+    make_diff_prop_modified("dirprop", "r2value", "workingvalue") + \
+    make_diff_prop_added("newdirprop", "newworkingvalue") + \
+    make_diff_header("iota", "revision 2", "working copy") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_modified("fileprop", "r2value", "workingvalue") + \
+    make_diff_prop_added("newfileprop", "newworkingvalue")
 
   os.chdir(sbox.wc_dir)
 
@@ -2378,31 +2366,16 @@ def diff_repos_wc_add_with_props(sbox):
   diff_foo = [
     "@@ -0,0 +1 @@\n",
     "+content\n",
-    "\n",
-    "Property changes on: foo\n",
-    "___________________________________________________________________\n",
-    "Added: propname\n",
-    "## -0,0 +1 ##\n",
-    "+propvalue\n",
-    ]
-  diff_X = [
-    "\n",
-    "Property changes on: X\n",
-    "___________________________________________________________________\n",
-    "Added: propname\n",
-    "## -0,0 +1 ##\n",
-    "+propvalue\n",
-    ]
+    ] + make_diff_prop_header("foo") + \
+    make_diff_prop_added("propname", "propvalue")
+  diff_X = \
+    make_diff_prop_header("X") + \
+    make_diff_prop_added("propname", "propvalue")
   diff_X_bar = [
     "@@ -0,0 +1 @@\n",
     "+content\n",
-    "\n",
-    "Property changes on: X/bar\n",
-    "___________________________________________________________________\n",
-    "Added: propname\n",
-    "## -0,0 +1 ##\n",
-    "+propvalue\n",
-    ]
+    ] + make_diff_prop_header("X/bar") + \
+    make_diff_prop_added("propname", "propvalue")
 
   diff_X_r1_base = make_diff_header("X", "revision 1",
                                          "working copy") + diff_X
@@ -2876,31 +2849,14 @@ def diff_with_depth(sbox):
   sbox.build()
   B_path = os.path.join('A', 'B')
 
-  diff = [
-    "\n",
-    "Property changes on: .\n",
-    "___________________________________________________________________\n",
-    "Added: foo1\n",
-    "## -0,0 +1 ##\n",
-    "+bar1\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Added: foo2\n",
-    "## -0,0 +1 ##\n",
-    "+bar2\n",
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Added: foo3\n",
-    "## -0,0 +1 ##\n",
-    "+bar3\n",
-    "\n",
-    "Property changes on: A/B\n",
-    "___________________________________________________________________\n",
-    "Added: foo4\n",
-    "## -0,0 +1 ##\n",
-    "+bar4\n"]
+  diff = make_diff_prop_header(".") + \
+         make_diff_prop_added("foo1", "bar1") + \
+         make_diff_prop_header("iota") + \
+         make_diff_prop_added("foo2", "bar2") + \
+         make_diff_prop_header("A") + \
+         make_diff_prop_added("foo3", "bar3") + \
+         make_diff_prop_header("A/B") + \
+         make_diff_prop_added("foo4", "bar4")
 
   dot_header = make_diff_header(".", "revision 1", "working copy")
   iota_header = make_diff_header('iota', "revision 1", "working copy")
@@ -2977,61 +2933,26 @@ def diff_with_depth(sbox):
   svntest.actions.run_and_verify_svn(None, expected_infinity, [],
                                      'diff', '-c2', '--depth', 'infinity')
 
-  diff_wc_repos = [
-    "Index: A/B\n",
-    "===================================================================\n",
-    "--- A/B\t(revision 2)\n",
-    "+++ A/B\t(working copy)\n",
-    "\n",
-    "Property changes on: A/B\n",
-    "___________________________________________________________________\n",
-    "Modified: foo4\n",
-    "## -1 +1 ##\n",
-    "-bar4\n",
-    "+baz4\n",
-    "Index: A\n",
-    "===================================================================\n",
-    "--- A\t(revision 2)\n",
-    "+++ A\t(working copy)\n",
-    "\n",
-    "Property changes on: A\n",
-    "___________________________________________________________________\n",
-    "Modified: foo3\n",
-    "## -1 +1 ##\n",
-    "-bar3\n",
-    "+baz3\n",
-    "Index: A/mu\n",
-    "===================================================================\n",
-    "--- A/mu\t(revision 1)\n",
-    "+++ A/mu\t(working copy)\n",
+  diff_wc_repos = \
+    make_diff_header("A/B", "revision 2", "working copy") + \
+    make_diff_prop_header("A/B") + \
+    make_diff_prop_modified("foo4", "bar4", "baz4") + \
+    make_diff_header("A", "revision 2", "working copy") + \
+    make_diff_prop_header("A") + \
+    make_diff_prop_modified("foo3", "bar3", "baz3") + \
+    make_diff_header("A/mu", "revision 1", "working copy") + [
     "@@ -1 +1,2 @@\n",
     " This is the file 'mu'.\n",
     "+new text\n",
-    "Index: iota\n",
-    "===================================================================\n",
-    "--- iota\t(revision 2)\n",
-    "+++ iota\t(working copy)\n",
+    ] + make_diff_header("iota", "revision 2", "working copy") + [
     "@@ -1 +1,2 @@\n",
     " This is the file 'iota'.\n",
     "+new text\n",
-    "\n",
-    "Property changes on: iota\n",
-    "___________________________________________________________________\n",
-    "Modified: foo2\n",
-    "## -1 +1 ##\n",
-    "-bar2\n",
-    "+baz2\n",
-    "Index: .\n",
-    "===================================================================\n",
-    "--- .\t(revision 2)\n",
-    "+++ .\t(working copy)\n",
-    "\n",
-    "Property changes on: .\n",
-    "___________________________________________________________________\n",
-    "Modified: foo1\n",
-    "## -1 +1 ##\n",
-    "-bar1\n",
-    "+baz1\n" ]
+    ] + make_diff_prop_header("iota") + \
+    make_diff_prop_modified("foo2", "bar2", "baz2") + \
+    make_diff_header(".", "revision 2", "working copy") + \
+    make_diff_prop_header(".") + \
+    make_diff_prop_modified("foo1", "bar1", "baz1")
 
   expected_empty = svntest.verify.UnorderedOutput(diff_wc_repos[43:])
   expected_files = svntest.verify.UnorderedOutput(diff_wc_repos[29:])
@@ -3184,6 +3105,16 @@ def diff_summarize_xml(sbox):
                         wc_rev=2)
   expected_status.remove("A/B/lambda")
 
+  # 3) Test working copy summarize
+  paths = ['A/mu', 'iota', 'A/D/G/tau', 'newfile', 'A/B/lambda',
+           'newdir',]
+  items = ['modified', 'none', 'modified', 'added', 'deleted', 'added',]
+  kinds = ['file','file','file','file','file', 'dir',]
+  props = ['none', 'modified', 'modified', 'none', 'none', 'none',]
+
+  svntest.actions.run_and_verify_diff_summarize_xml(
+    [], wc_dir, paths, items, props, kinds, wc_dir)
+
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
 
@@ -3197,38 +3128,21 @@ def diff_summarize_xml(sbox):
     ".*No such revision 5555555",
     None, wc_dir, None, None, None, '-r0:5555555', wc_dir)
 
-  # 3) Test working copy summarize
-  svntest.actions.run_and_verify_diff_summarize_xml(
-    ".*Summarizing diff can only compare repository to repository",
-    None, wc_dir, None, None, wc_dir)
-
   # 4) Test --summarize --xml on -c2
-  paths = ['iota',]
-  items = ['none',]
-  kinds = ['file',]
-  props = ['modified',]
+  paths_iota = ['iota',]
+  items_iota = ['none',]
+  kinds_iota = ['file',]
+  props_iota = ['modified',]
 
   svntest.actions.run_and_verify_diff_summarize_xml(
-    [], wc_dir, paths, items, props, kinds, '-c2',
+    [], wc_dir, paths_iota, items_iota, props_iota, kinds_iota, '-c2',
     os.path.join(wc_dir, 'iota'))
 
   # 5) Test --summarize --xml on -r1:2
-  paths = ['A/mu', 'iota', 'A/D/G/tau', 'newfile', 'A/B/lambda',
-           'newdir',]
-  items = ['modified', 'none', 'modified', 'added', 'deleted', 'added',]
-  kinds = ['file','file','file','file','file', 'dir',]
-  props = ['none', 'modified', 'modified', 'none', 'none', 'none',]
-
   svntest.actions.run_and_verify_diff_summarize_xml(
     [], wc_dir, paths, items, props, kinds, '-r1:2', wc_dir)
 
   # 6) Same as test #5 but ran against a URL instead of a WC path
-  paths = ['A/mu', 'iota', 'A/D/G/tau', 'newfile', 'A/B/lambda',
-           'newdir',]
-  items = ['modified', 'none', 'modified', 'added', 'deleted', 'added',]
-  kinds = ['file','file','file','file','file', 'dir',]
-  props = ['none', 'modified', 'modified', 'none', 'none', 'none',]
-
   svntest.actions.run_and_verify_diff_summarize_xml(
     [], sbox.repo_url, paths, items, props, kinds, '-r1:2', sbox.repo_url)
 
@@ -3549,10 +3463,8 @@ def diff_prop_missing_context(sbox):
   svntest.main.run_svn(None,
                        "propset", "prop", prop_val, iota_path)
   expected_output = make_diff_header(iota_path, 'revision 2',
-                                     'working copy') + [
-    "\n",
-    "Property changes on: %s\n" % iota_path.replace('\\', '/'),
-    "___________________________________________________________________\n",
+                                     'working copy') + \
+                    make_diff_prop_header(iota_path) + [
     "Modified: prop\n",
     "## -1,7 +1,4 ##\n",
     "-line 1\n",
@@ -3619,10 +3531,8 @@ def diff_prop_multiple_hunks(sbox):
   svntest.main.run_svn(None,
                        "propset", "prop", prop_val, iota_path)
   expected_output = make_diff_header(iota_path, 'revision 2',
-                                     'working copy') + [
-    "\n",
-    "Property changes on: %s\n" % iota_path.replace('\\', '/'),
-    "___________________________________________________________________\n",
+                                     'working copy') + \
+                    make_diff_prop_header(iota_path) + [
     "Modified: prop\n",
     "## -1,6 +1,7 ##\n",
     " line 1\n",
@@ -3704,28 +3614,59 @@ def diff_git_with_props(sbox):
   svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', new_path)
   svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Id', iota_path)
 
-  expected_output = make_git_diff_header(new_path, "new", "revision 0",
-                                         "working copy",
-                                         add=True, text_changes=False) + [
-      "\n",
-      "Property changes on: new\n",
-      "___________________________________________________________________\n",
-      "Added: svn:eol-style\n",
-      "## -0,0 +1 ##\n",
-      "+native\n",
-  ] + make_git_diff_header(iota_path, "iota", "revision 1", "working copy",
-                           text_changes=False) + [
-      "\n",
-      "Property changes on: iota\n",
-      "___________________________________________________________________\n",
-      "Added: svn:keywords\n",
-      "## -0,0 +1 ##\n",
-      "+Id\n",
-  ]
+  expected_output = make_git_diff_header(new_path, "new",
+                                         "revision 0", "working copy",
+                                         add=True, text_changes=False) + \
+                    make_diff_prop_header("new") + \
+                    make_diff_prop_added("svn:eol-style", "native") + \
+                    make_git_diff_header(iota_path, "iota",
+                                         "revision 1", "working copy",
+                                         text_changes=False) + \
+                    make_diff_prop_header("iota") + \
+                    make_diff_prop_added("svn:keywords", "Id")
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
+                                     '--git', wc_dir)
+
+@XFail()
+@Issue(4010)
+def diff_correct_wc_base_revnum(sbox):
+  "diff WC-WC shows the correct base rev num"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  iota_path = os.path.join(wc_dir, 'iota')
+  svntest.main.file_write(iota_path, "")
+
+  # Commit a local mod, creating rev 2.
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.add({
+    'iota' : Item(status='  ', wc_rev=2),
+    })
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  # Child's base is now 2; parent's is still 1.
+  # Make a local mod.
+  svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Id', iota_path)
+
+  expected_output = make_git_diff_header(iota_path, "iota",
+                                         "revision 2", "working copy") + \
+                    make_diff_prop_header("iota") + \
+                    make_diff_prop_added("svn:keywords", "Id")
 
+  # Diff the parent.
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '--git', wc_dir)
 
+  # The same again, but specifying the target explicity. This should
+  # give the same output.
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
+                                     '--git', iota_path)
+
 def diff_git_with_props_on_dir(sbox):
   "diff in git format showing prop changes on dir"
   sbox.build()
@@ -3749,14 +3690,9 @@ def diff_git_with_props_on_dir(sbox):
   os.chdir(wc_dir)
   expected_output = make_git_diff_header(".", "", "revision 1",
                                          "revision 2",
-                                         add=False, text_changes=False) + [
-      "\n",
-      "Property changes on: \n",
-      "___________________________________________________________________\n",
-      "Added: a\n",
-      "## -0,0 +1 ##\n",
-      "+b\n",
-  ]
+                                         add=False, text_changes=False) + \
+                    make_diff_prop_header("") + \
+                    make_diff_prop_added("a", "b")
 
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '-c2', '--git')
@@ -3880,6 +3816,7 @@ test_list = [ None,
               diff_git_with_props_on_dir,
               diff_abs_localpath_from_wc_folder,
               no_spurious_conflict,
+              diff_correct_wc_base_revnum,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/externals_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/externals_tests.py Tue Oct 11 19:52:34 2011
@@ -28,7 +28,7 @@
 import sys
 import os
 import re
-import tempfile
+import shutil
 
 # Our testing module
 import svntest
@@ -214,25 +214,18 @@ def externals_test_setup(sbox):
 def change_external(path, new_val, commit=True):
   """Change the value of the externals property on PATH to NEW_VAL,
   and commit the change unless COMMIT is False."""
-  (fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
-  svntest.main.file_append(tmp_f, new_val)
-  svntest.actions.run_and_verify_svn(None, None, [], 'pset',
-                                     '-F', tmp_f, 'svn:externals', path)
+
+  svntest.actions.set_prop('svn:externals', new_val, path)
   if commit:
     svntest.actions.run_and_verify_svn(None, None, [], 'ci',
                                        '-m', 'log msg', '--quiet', path)
-  os.close(fd)
-  os.remove(tmp_f)
 
 def change_external_expect_error(path, new_val, expected_err):
   """Try to change the value of the externals property on PATH to NEW_VAL,
   but expect to get an error message that matches EXPECTED_ERR."""
-  (fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
-  svntest.main.file_append(tmp_f, new_val)
-  svntest.actions.run_and_verify_svn(None, None, expected_err, 'pset',
-                                     '-F', tmp_f, 'svn:externals', path)
-  os.close(fd)
-  os.remove(tmp_f)
+
+  svntest.actions.set_prop('svn:externals', new_val, path,
+                           expected_err=expected_err)
 
 
 def probe_paths_exist(paths):
@@ -1884,6 +1877,228 @@ def exclude_externals(sbox):
                                         None, None, None, None, False,
                                         '--set-depth', 'infinity', wc_dir)
 
+def file_externals_different_repos(sbox):
+  "update file externals via different url"
+
+  sbox.build()
+
+  wc_dir = sbox.wc_dir
+  r1_url = sbox.repo_url
+
+  r2_dir, r2_url = sbox.add_repo_path('2')
+  svntest.main.copy_repos(sbox.repo_dir, r2_dir, 1, 0)
+
+
+  sbox.simple_propset('svn:externals',
+                      'r1-e-1   ' + r1_url + '/iota\n' +
+                      r1_url + '/iota  r1-e-2\n' +
+                      'r2-e-1   ' + r2_url + '/iota\n' +
+                      r2_url + '/iota  r2-e-2\n' +
+                      '^/iota  rr-e-1\n', '')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'r1-e-1'            : Item(status='A '),
+    'r1-e-2'            : Item(status='A '),
+    'rr-e-1'            : Item(status='A '),
+  })
+
+  # The externals from r2 should fail, but currently pass.
+  # This creates a wc.db inconsistency
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, None, None,
+                                        'svn: warning: W200007: Unsupported.*')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'relocate', r1_url, r2_url, wc_dir)
+
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'r2-e-1'            : Item(status='A '),
+    'r2-e-2'            : Item(status='A '),
+  })
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, None, None,
+                                        'svn: warning: W200007: Unsupported.*')
+
+def file_external_in_unversioned(sbox):
+  "file external in unversioned dir"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_propset('svn:externals', '^/A/mu X/mu', 'A')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/X/mu' : Item(status='A '),
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None, None)
+
+  # At one point this failed with SVN_DEBUG wcng consistency checks enabled
+  svntest.actions.run_and_verify_svn(None, None, [], 'cleanup', wc_dir)
+
+
+from svntest import verify, actions, main
+
+@Issue(3589, 4000)
+def copy_file_externals(sbox):
+  "a WC->WC copy should exclude file externals"
+
+  #  svntest.factory.make(sbox,"""
+  #  svn mkdir X
+  #  ### manual edit: add '\n ^/A/mu xmu' to externals definition:
+  #  svn ps svn:externals "^/iota xiota" X
+  #  """)
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  X = os.path.join(wc_dir, 'X')
+
+  # svn mkdir X
+  expected_stdout = ['A         ' + X + '\n']
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'mkdir', X)
+
+  # svn ps svn:externals "^/iota xiota" X
+  expected_stdout = ["property 'svn:externals' set on '" + X + "'\n"]
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+    'svn:externals', '''
+    ^/iota xiota
+    ^/A/mu xmu
+    ''', X)
+
+  #  svntest.factory.make(sbox, '''
+  #  svn ci
+  #  svn up
+  #  # have a commit on one of the files
+  #  echo mod >> X/xmu
+  #  svn ci X/xmu
+  #  svn up
+  #  # now perform the WC->WC copy
+  #  svn cp X X_copy
+  #  ### manual edit: add a verify_disk(check_props=True) here
+  #  svn ci
+  #  ### manual edit: add check_props=True to below update
+  #  svn up
+  #  ''')
+
+  X = os.path.join(wc_dir, 'X')
+  X_copy = os.path.join(wc_dir, 'X_copy')
+  X_xmu = os.path.join(wc_dir, 'X', 'xmu')
+
+  # svn ci
+  expected_output = svntest.wc.State(wc_dir, {
+    'X'                 : Item(verb='Adding'),
+  })
+
+  expected_status = actions.get_virginal_state(wc_dir, 1)
+  expected_status.add({
+    'X'                 : Item(status='  ', wc_rev='2'),
+  })
+
+  actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+    None, wc_dir)
+
+  # svn up
+  expected_output = svntest.wc.State(wc_dir, {
+    'X/xmu'             : Item(status='A '),
+    'X/xiota'           : Item(status='A '),
+  })
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+    'X'                 : Item(),
+    'X/xiota'           : Item(contents="This is the file 'iota'.\n"),
+    'X/xmu'             : Item(contents="This is the file 'mu'.\n"),
+  })
+
+  expected_status.add({
+    'X/xiota'           : Item(status='  ', wc_rev='2', switched='X'),
+    'X/xmu'             : Item(status='  ', wc_rev='2', switched='X'),
+  })
+  expected_status.tweak(wc_rev='2')
+
+  actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+    expected_status, None, None, None, None, None, False, wc_dir)
+
+  # have a commit on one of the files
+  # echo mod >> X/xmu
+  main.file_append(X_xmu, 'mod\n')
+
+  # svn ci X/xmu
+  expected_output = svntest.wc.State(wc_dir, {
+    'X/xmu'             : Item(verb='Sending'),
+  })
+
+  expected_status.tweak('X/xmu', wc_rev='3')
+
+  actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+    None, X_xmu)
+
+  # svn up
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu'              : Item(status='U '),
+  })
+
+  expected_disk.tweak('A/mu', 'X/xmu',
+    contents="This is the file 'mu'.\nmod\n")
+
+  expected_status.tweak(wc_rev='3')
+
+  actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+    expected_status, None, None, None, None, None, False, wc_dir)
+
+  # now perform the WC->WC copy
+  # svn cp X X_copy
+  expected_stdout = ['A         ' + X_copy + '\n']
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'cp', X,
+    X_copy)
+
+  # svn ci
+  expected_output = svntest.wc.State(wc_dir, {
+    'X_copy'            : Item(verb='Adding'),
+  })
+
+  expected_status.add({
+    'X_copy'            : Item(status='  ', wc_rev='4'),
+  })
+
+  actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+    None, wc_dir)
+
+  # verify disk state, also verifying props
+  expected_disk.add({
+    'X_copy'            : Item(),
+  })
+  expected_disk.tweak('X', 'X_copy',
+    props={'svn:externals' : '\n    ^/iota xiota\n    ^/A/mu xmu\n    \n'})
+
+  actions.verify_disk(wc_dir, expected_disk, True)
+
+  # svn up
+  expected_output = svntest.wc.State(wc_dir, {
+    'X_copy/xmu'        : Item(status='A '),
+    'X_copy/xiota'      : Item(status='A '),
+  })
+
+  expected_disk.add({
+    'X_copy/xmu'        : Item(contents="This is the file 'mu'.\nmod\n"),
+    'X_copy/xiota'      : Item(contents="This is the file 'iota'.\n"),
+  })
+
+  expected_status.add({
+    'X_copy/xmu'        : Item(status='  ', wc_rev='4', switched='X'),
+    'X_copy/xiota'      : Item(status='  ', wc_rev='4', switched='X'),
+  })
+  expected_status.tweak(wc_rev='4')
+
+  actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+    expected_status, None, None, None, None, None, True, wc_dir)
+
+
 ########################################################################
 # Run the tests
 
@@ -1922,6 +2137,9 @@ test_list = [ None,
               incoming_file_on_file_external,
               incoming_file_external_on_file,
               exclude_externals,
+              file_externals_different_repos,
+              file_external_in_unversioned,
+              copy_file_externals,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Tue Oct 11 19:52:34 2011
@@ -87,8 +87,9 @@ Global options:
   --password ARG           : specify a password ARG
   --no-auth-cache          : do not cache authentication tokens
   --non-interactive        : do no interactive prompting
-  --trust-server-cert      : accept unknown SSL server certificates without
-                             prompting (but only with '--non-interactive')
+  --trust-server-cert      : accept SSL server certificates from unknown
+                             certificate authorities without prompting (but only
+                             with '--non-interactive')
   --config-dir ARG         : read user configuration files from directory ARG
   --config-option ARG      : set user configuration option in the format:
                                  FILE:SECTION:OPTION=[VALUE]
@@ -165,8 +166,9 @@ Global options:
   --password ARG           : specify a password ARG
   --no-auth-cache          : do not cache authentication tokens
   --non-interactive        : do no interactive prompting
-  --trust-server-cert      : accept unknown SSL server certificates without
-                             prompting (but only with '--non-interactive')
+  --trust-server-cert      : accept SSL server certificates from unknown
+                             certificate authorities without prompting (but only
+                             with '--non-interactive')
   --config-dir ARG         : read user configuration files from directory ARG
   --config-option ARG      : set user configuration option in the format:
                                  FILE:SECTION:OPTION=[VALUE]

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/import_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/import_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/import_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/import_tests.py Tue Oct 11 19:52:34 2011
@@ -370,6 +370,21 @@ enable-auto-props = yes
                                      '--config-dir', config_dir)
 
 #----------------------------------------------------------------------
+@Issue(3983)
+def import_into_foreign_repo(sbox):
+  "import into a foreign repo"
+
+  sbox.build(read_only=True)
+
+  other_repo_dir, other_repo_url = sbox.add_repo_path('other')
+  svntest.main.safe_rmtree(other_repo_dir, 1)
+  svntest.main.create_repos(other_repo_dir)
+
+  svntest.actions.run_and_verify_svn(None, None, [], 'import',
+                                     '-m', 'Log message for new import',
+                                     sbox.ospath('A/mu'), other_repo_url + '/f')
+
+#----------------------------------------------------------------------
 ########################################################################
 # Run the tests
 
@@ -381,6 +396,7 @@ test_list = [ None,
               import_avoid_empty_revision,
               import_no_ignores,
               import_eol_style,
+              import_into_foreign_repo,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/info_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/info_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/info_tests.py Tue Oct 11 19:52:34 2011
@@ -412,6 +412,111 @@ def info_repos_root_url(sbox):
   svntest.actions.run_and_verify_info(expected_info, sbox.repo_url,
                                       '--depth', 'files')
 
+@Issue(3787)
+def info_show_exclude(sbox):
+  "tests 'info --depth' variants on excluded node"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  A_path = os.path.join(wc_dir, 'A')
+  iota = os.path.join(wc_dir, 'iota')
+  svntest.main.run_svn(None, 'up', '--set-depth', 'exclude', A_path)
+  wc_uuid = svntest.actions.get_wc_uuid(wc_dir)
+
+  expected_info = [{
+      'Path' : re.escape(wc_dir),
+      'Repository Root' : sbox.repo_url,
+      'Repository UUID' : wc_uuid,
+  }]
+
+  svntest.actions.run_and_verify_info(expected_info, '--depth', 'empty',
+                                      wc_dir)
+
+  expected_info = [{
+      'Path' : '.*%sA' % re.escape(os.sep),
+      'Repository Root' : sbox.repo_url,
+      'Repository UUID' : wc_uuid,
+      'Depth' : 'exclude',
+  }]
+
+  svntest.actions.run_and_verify_info(expected_info, '--depth',
+                                      'empty', A_path)
+  svntest.actions.run_and_verify_info(expected_info, '--depth',
+                                      'infinity', A_path)
+  svntest.actions.run_and_verify_info(expected_info, '--depth',
+                                      'immediates', A_path)
+
+  expected_info = [{
+      'Path' : '.*%siota' % re.escape(os.sep),
+      'Repository Root' : sbox.repo_url,
+      'Repository UUID' : wc_uuid,
+  }]
+  svntest.main.run_svn(None, 'up', '--set-depth', 'exclude', iota)
+  svntest.actions.run_and_verify_info(expected_info, iota)
+
+  # And now get iota back, to allow testing other states
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(status='A '),
+    })
+
+  expected_status = svntest.wc.State(iota, {
+    '' : Item(status='  ', wc_rev='1')
+  })
+
+  svntest.actions.run_and_verify_update(iota,
+                                        expected_output, None, expected_status)
+
+  sbox.simple_rm('iota')
+  sbox.simple_commit()
+  
+  expected_error = 'svn: E200009: Could not display info for all targets.*'
+
+  # Expect error on iota (status = not-present)
+  svntest.actions.run_and_verify_svn(None, [], expected_error, 'info', iota)
+
+  sbox.simple_update()
+
+  # Expect error on iota (unversioned)
+  svntest.actions.run_and_verify_svn(None, [], expected_error, 'info', iota)
+
+@Issue(3998)
+def binary_tree_conflict(sbox):
+  "svn info shouldn't crash on conflict"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_propset('svn:mime-type', 'binary/octet-stream', 'iota')
+  sbox.simple_commit()
+
+  iota = sbox.ospath('iota')
+
+  svntest.main.file_write(iota, 'something-else')
+  sbox.simple_commit()
+
+  svntest.main.file_write(iota, 'third')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(status='C '),
+    })
+  expected_status = svntest.wc.State(iota, {
+    '' : Item(status='C ', wc_rev='2')
+  })
+  svntest.actions.run_and_verify_update(iota,
+                                        expected_output, None, expected_status,
+                                        None, None, None, None, None, False,
+                                        iota, '-r', '2')
+
+  expected_info = [{
+      'Path' : '%s' % re.escape(iota),
+      'Conflict Previous Base File' : re.escape(iota + '.r3'),
+      'Conflict Current Base File' : re.escape(iota + '.r2'),
+  }]
+  svntest.actions.run_and_verify_info(expected_info, iota)
+
+
+
+
 ########################################################################
 # Run the tests
 
@@ -424,6 +529,8 @@ test_list = [ None,
               info_url_special_characters,
               info_multiple_targets,
               info_repos_root_url,
+              info_show_exclude,
+              binary_tree_conflict,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/input_validation_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/input_validation_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/input_validation_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/input_validation_tests.py Tue Oct 11 19:52:34 2011
@@ -120,9 +120,6 @@ def invalid_diff_targets(sbox):
   for (target1, target2) in [("iota", "^/"), ("file://", "iota")]:
     run_and_verify_svn_in_wc(sbox, "svn: E205000: Cannot mix repository and working "
                              "copy targets", 'diff', target1, target2)
-  run_and_verify_svn_in_wc(sbox, "svn: E200007: Summarizing diff can only compare "
-                           "repository to repository",
-                           'diff', '--summarize', "iota", "A")
 
 def invalid_export_targets(sbox):
   "invalid targets for 'export'"

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/lock_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/lock_tests.py Tue Oct 11 19:52:34 2011
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+# encoding=utf-8
 #
 #  lock_tests.py:  testing versioned properties
 #
@@ -90,7 +91,7 @@ def lock_file(sbox):
 
   # --- Meanwhile, in our other working copy... ---
   err_re = "(svn\: E195022\: File '.*iota' is locked in another)|" + \
-           "(svn\: E160039: User 'jconstant' does not own lock on path.*iota')"
+           "(svn\: E160039: User '?jconstant'? does not own lock on path.*iota')"
 
   svntest.main.run_svn(None, 'update', wc_b)
   # -- Try to change a file --
@@ -111,7 +112,7 @@ def lock_file(sbox):
   svntest.main.run_svn(None, 'propset', 'sneakyuser', 'Sally', file_path_b)
 
   err_re = "(svn\: E195022\: File '.*iota' is locked in another)|" + \
-           "(svn\: E160039\: User 'jconstant' does not own lock on path)"
+           "(svn\: E160039\: User '?jconstant'? does not own lock on path)"
 
   # attempt (and fail) to commit as user Sally
   svntest.actions.run_and_verify_commit(wc_b, None, None, err_re,
@@ -1334,7 +1335,7 @@ def unlock_wrong_token(sbox):
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                      file_path)
 
-  # Steal the lock as the same author, but using an URL to keep the old token
+  # Steal the lock as the same author, but using a URL to keep the old token
   # in the WC.
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                     "--force", file_url)
@@ -1498,9 +1499,9 @@ def lock_path_not_in_head(sbox):
   svntest.actions.run_and_verify_svn(None, None, [], 'commit',
                                      '-m', 'Some deletions', wc_dir)
   svntest.actions.run_and_verify_svn(None, None, [], 'up', '-r1', wc_dir)
-  expected_lock_fail_err_re = "svn: warning:.*" \
+  expected_lock_fail_err_re = "svn: warning: W160042: " \
   "((Path .* doesn't exist in HEAD revision)" \
-  "|(Lock request failed: 405 Method Not Allowed))"
+  "|(L(ock|OCK) request (on '.*' )?failed: 405 Method Not Allowed))"
   # Issue #3524 These lock attemtps were triggering an assert over ra_serf:
   #
   # working_copies\lock_tests-37>svn lock A\D
@@ -1720,6 +1721,27 @@ def block_unlock_if_pre_unlock_hook_fail
                                       1, 'unlock', pi_path)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+#----------------------------------------------------------------------
+def lock_invalid_token(sbox):
+  "verify pre-lock hook returning invalid token"
+
+  sbox.build()
+
+  hook_path = os.path.join(sbox.repo_dir, 'hooks', 'pre-lock')
+  svntest.main.create_python_hook_script(hook_path,
+    '# encoding=utf-8\n'
+    'import sys\n'
+    'sys.stdout.write("тест")\n'
+    'sys.exit(0)\n')
+
+  fname = 'iota'
+  file_path = os.path.join(sbox.wc_dir, fname)
+
+  svntest.actions.run_and_verify_svn2(None, None,
+                                      "svn: warning: W160037: " \
+                                      ".*scheme.*'opaquelocktoken'", 0,
+                                      'lock', '-m', '', file_path)
+
 
 ########################################################################
 # Run the tests
@@ -1768,6 +1790,7 @@ test_list = [ None,
               cp_isnt_ro,
               update_locked_deleted,
               block_unlock_if_pre_unlock_hook_fails,
+              lock_invalid_token,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/log_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/log_tests.py Tue Oct 11 19:52:34 2011
@@ -1975,7 +1975,6 @@ def merge_sensitive_log_ignores_cyclic_m
 
 #----------------------------------------------------------------------
 @Issue(3931,3936)
-@XFail(svntest.main.is_ra_type_dav_serf)
 def log_with_unrelated_peg_and_operative_revs(sbox):
   "log with unrelated peg and operative rev targets"
 
@@ -1983,12 +1982,8 @@ def log_with_unrelated_peg_and_operative
 
   target = sbox.repo_url + '/A/D/G/rho@2'
 
-  # Currently this test fails because ra_serf returns an SVN_ERR_FS_NOT_FOUND
-  # error from svn_ra_get_locations() that the other RA layers do not
-  # return. The test passes with all other RA layers. See issue #3936.
-
   # log for /A/D/G/rho, deleted in revision 5, recreated in revision 8
-  expected_error = ".*File not found.*"
+  expected_error = ".*(File|path) not found.*"
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'log', '-r', '6:7', target)
   svntest.actions.run_and_verify_svn(None, None, expected_error,
@@ -2008,7 +2003,6 @@ def log_with_unrelated_peg_and_operative
 
 #----------------------------------------------------------------------
 @Issue(3937)
-@XFail(svntest.main.is_ra_type_dav_serf)
 def log_on_nonexistent_path_and_valid_rev(sbox):
   "log on nonexistent path does not error out"
 
@@ -2028,8 +2022,6 @@ def log_on_nonexistent_path_and_valid_re
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'log', '-q', bad_url_bad_rev)
 
-  # Currently this test fails over ra_serf because the following log
-  # commands return empty logs rather than errors.
   expected_error = ".*not found.*"
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'log', '-q', bad_path_real_rev)

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/merge_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/merge_authz_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/merge_authz_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/merge_authz_tests.py Tue Oct 11 19:52:34 2011
@@ -420,7 +420,7 @@ def mergeinfo_and_skipped_paths(sbox):
                    props={SVN_PROP_MERGEINFO : '/A/D/H/omega:8-9'}),
     'chi'   : Item("This is the file 'chi'.\n"),
     'zeta'  : Item("This is the file 'zeta'.\n",
-                   props={SVN_PROP_MERGEINFO : '/A/D/H/zeta:8-9'}),
+                   props={SVN_PROP_MERGEINFO : '/A/D/H/zeta:9'}),
     })
   expected_skip = wc.State(A_COPY_2_H_path, {})
   svntest.actions.run_and_verify_merge(A_COPY_2_H_path, '7', '9',

Modified: subversion/branches/svn_mutex/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/branches/svn_mutex/subversion/tests/cmdline/merge_reintegrate_tests.py Tue Oct 11 19:52:34 2011
@@ -486,22 +486,9 @@ def reintegrate_with_rename(sbox):
     ""             : Item(status=' M', wc_rev=9),
   })
   k_expected_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A_COPY:2-9'})
-
-  # Why do we expect mergeinfo of '/A_COPY/D/G/tauprime:2-9' on
-  # A/D/G/tauprime?  Because this --reintegrate merge is effectively a
-  # two URL merge of %URL%/A@9 %URL%/A_COPY@9 to 'A'.  Since %URL%/A@9 and
-  # %URL%/A_COPY@9 have a common ancestor in %URL%/A@1 we expect this 2-URL
-  # merge to record mergeinfo and a component of that mergeinfo describes
-  # the merge of %URL%/A_COPY@2 to %URL%/A_COPY@9.  We see that above on
-  # A.  But we also get it on A's subtrees with explicit mergeinfo, namely
-  # A/D/G/tauprime.  Now I know what you are thinking, "'A_COPY/D/G/tauprime'
-  # doesn't even exist until r9!", and you are quite right.  But this
-  # inheritance of bogus mergeinfo is a known problem, see
-  # http://subversion.tigris.org/issues/show_bug.cgi?id=3157#desc8,
-  # and is not what this test is about, so we won't fail because of it.
   k_expected_disk.add({
     'D/G/tauprime' : Item(props={SVN_PROP_MERGEINFO :
-                                 '/A/D/G/tau:2-7\n/A_COPY/D/G/tauprime:2-9'},
+                                 '/A/D/G/tau:2-7\n/A_COPY/D/G/tauprime:9'},
                           contents="This is the file 'tau'.\n")
     })
   expected_skip = wc.State(A_path, {})
@@ -1012,7 +999,6 @@ def reintegrate_with_subtree_mergeinfo(s
   expected_status.tweak('A_COPY_3/D/gamma', wc_rev=9)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.tweak('A_COPY_3/D/gamma', contents="New content")
 
   # r10 - Merge r9 from A_COPY_3/D to A/D, creating explicit subtree
   # mergeinfo under A.  For this and every subsequent merge we update the WC
@@ -1032,8 +1018,6 @@ def reintegrate_with_subtree_mergeinfo(s
   expected_status.tweak('A/D', 'A/D/gamma', wc_rev=10)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.tweak('A/D/gamma', contents="New content")
-  expected_disk.tweak('A/D', props={SVN_PROP_MERGEINFO : '/A_COPY_3/D:9'})
 
   # r11 - Make a text change to A_COPY_2/mu
   svntest.main.file_write(mu_COPY_2_path, "New content")
@@ -1041,7 +1025,6 @@ def reintegrate_with_subtree_mergeinfo(s
   expected_status.tweak('A_COPY_2/mu', wc_rev=11)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.tweak('A_COPY_2/mu', contents="New content")
 
   # r12 - Merge r11 from A_COPY_2/mu to A_COPY/mu
   svntest.actions.run_and_verify_svn(None, exp_noop_up_out(11), [], 'up',
@@ -1058,7 +1041,6 @@ def reintegrate_with_subtree_mergeinfo(s
   expected_status.tweak('A_COPY/mu', wc_rev=12)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.tweak('A_COPY/mu', contents="New content")
 
   # r13 - Do a 'synch' cherry harvest merge of all available revisions
   # from A to A_COPY
@@ -1097,16 +1079,6 @@ def reintegrate_with_subtree_mergeinfo(s
                         wc_rev=13)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.tweak('A_COPY/B/E/beta',
-                      'A_COPY/D',
-                      'A_COPY/D/G/rho',
-                      'A_COPY/D/H/omega',
-                      'A_COPY/D/H/psi',
-                      'A_COPY/D/gamma',
-                      contents="New content")
-  expected_disk.tweak('A_COPY',   props={SVN_PROP_MERGEINFO : '/A:2-12'})
-  expected_disk.tweak('A_COPY/D',
-                      props={SVN_PROP_MERGEINFO : '/A/D:2-12\n/A_COPY_3/D:9\n'})
 
   # r14 - Make a text change on A_COPY/B/E/alpha
   svntest.main.file_write(alpha_COPY_path, "New content")
@@ -1114,7 +1086,6 @@ def reintegrate_with_subtree_mergeinfo(s
   expected_status.tweak('A_COPY/B/E/alpha', wc_rev=14)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.tweak('A_COPY/B/E/alpha', contents="New content")
 
   # Now, reintegrate A_COPY to A.  This should succeed.
   svntest.actions.run_and_verify_svn(None, exp_noop_up_out(14), [], 'up',
@@ -1273,11 +1244,6 @@ def reintegrate_with_subtree_mergeinfo(s
                                      '-m', 'REPOS-to-REPOS move'
                                      )
   svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
-  expected_disk.remove('A/D/gamma')
-  expected_disk.add({
-    'A/D/gamma_moved' : Item(props={SVN_PROP_MERGEINFO: '/A_COPY_3/D/gamma:9'},
-                             contents="New content")
-    })
   expected_status.tweak(wc_rev=16)
   expected_status.remove('A/D/gamma')
   expected_status.add({'A/D/gamma_moved' : Item(status='  ', wc_rev=16)})
@@ -1290,7 +1256,8 @@ def reintegrate_with_subtree_mergeinfo(s
                            'A    ' + gamma_moved_COPY_path + '\n',
                            'D    ' + gamma_COPY_path + '\n',
                            ' U   ' + A_COPY_path     + '\n',
-                           ' U   ' + D_COPY_path     + '\n',]),
+                           ' U   ' + D_COPY_path     + '\n',
+                           ' U   ' + gamma_moved_COPY_path + '\n']),
     [], 'merge', sbox.repo_url + '/A',  A_COPY_path)
   expected_output = wc.State(
     wc_dir,
@@ -1310,11 +1277,6 @@ def reintegrate_with_subtree_mergeinfo(s
   expected_status.add({'A_COPY/D/gamma_moved' : Item(status='  ', wc_rev=17)})
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
-  expected_disk.remove('A_COPY/D/gamma')
-  expected_disk.add({
-    'A/D/gamma_moved' : Item(props={SVN_PROP_MERGEINFO: '/A_COPY_3/D/gamma:9'},
-                             contents="New content")
-    })
 
   # r18 - C) Text mod to A/D/gamma_moved
   svntest.main.file_write(gamma_moved_path, "Even newer content")
@@ -1365,7 +1327,7 @@ def reintegrate_with_subtree_mergeinfo(s
     ''              : Item(status=' U'),
     'mu'            : Item(status=' G'),
     'D'             : Item(status=' U'),
-    'D/gamma_moved' : Item(status=' G'),
+    'D/gamma_moved' : Item(status=' U'),
     })
   expected_elision_output = wc.State(A_path, {
     })
@@ -1409,22 +1371,9 @@ def reintegrate_with_subtree_mergeinfo(s
     'D/G/pi'        : Item("This is the file 'pi'.\n"),
     'D/G/rho'       : Item("New content"),
     'D/G/tau'       : Item("This is the file 'tau'.\n"),
-    # Why do we expect mergeinfo of '/A_COPY/D/G/tauprime:2-9' on
-    # A/D/G/tauprime?  Because this --reintegrate merge is effectively a
-    # two URL merge of %URL%/A@9 %URL%/A_COPY@9 to 'A'.  Since %URL%/A@9 and
-    # %URL%/A_COPY@9 have a common ancestor in %URL%/A@1 we expect this 2-URL
-    # merge to record mergeinfo and a component of that mergeinfo describes
-    # the merge of %URL%/A_COPY@2 to %URL%/A_COPY@9.  We see that above on
-    # A.  But we also get it on A's subtrees with explicit mergeinfo, namely
-    # A/D/G/tauprime.  Now I know what you are thinking, "'A_COPY/D/G/tauprime'
-    # doesn't even exist until r9!", and you are quite right.  But this
-    # inheritance of bogus mergeinfo is a known problem, see
-    # http://subversion.tigris.org/issues/show_bug.cgi?id=3157#desc8,
-    # and is not what this test is about, so we won't fail because of it.
     'D/gamma_moved' : Item(
       "Even newer content", props={SVN_PROP_MERGEINFO :
-                                   '/A/D/gamma_moved:2-15\n'
-                                   '/A_COPY/D/gamma_moved:2-19\n'
+                                   '/A_COPY/D/gamma_moved:17-19\n'
                                    '/A_COPY_3/D/gamma:9'}),
     'D/H'           : Item(),
     'D/H/chi'       : Item("This is the file 'chi'.\n"),
@@ -2062,7 +2011,7 @@ def added_subtrees_with_mergeinfo_break_
     'C'         : Item(),
     'C/nu'      : Item("Trunk work on nu.\n",
                        props={SVN_PROP_MERGEINFO :
-                              '/A_COPY/C/nu:16-18\n'
+                              '/A_COPY/C/nu:13,16-18\n'
                               '/A_COPY_2/C/nu:10'}), # <-- From cyclic
                                                      # merge in r11
     'D'         : Item(),
@@ -2252,7 +2201,6 @@ def two_URL_merge_removes_valid_mergeinf
 # Test for issue #3867 'reintegrate merges create mergeinfo for
 # non-existent paths'.
 @Issue(3867)
-@XFail()
 def reintegrate_creates_bogus_mergeinfo(sbox):
   "reintegrate creates bogus mergeinfo"
 
@@ -2281,11 +2229,11 @@ def reintegrate_creates_bogus_mergeinfo(
   svntest.main.run_svn(None, "cp", A_path_1, A_COPY_path)
   svntest.main.run_svn(None, "ci", "-m", "create a branch", wc_dir)
 
-  # Make a text edit on the branch pushing the repo to rev6
+  # Make a text edit on the branch pushing the repo to r5
   svntest.main.file_write(A_COPY_psi_path, "Branch edit.\n")
   svntest.main.run_svn(None, "ci", "-m", "branch edit", wc_dir)
 
-  # Sync the A_COPY with A in preparation for reintegrate
+  # Sync the A_COPY with A in preparation for reintegrate and commit as r6.
   svntest.main.run_svn(None, "up", wc_dir)
   svntest.main.run_svn(None, "merge", sbox.repo_url + "/A", A_COPY_path)
   svntest.main.run_svn(None, "ci", "-m", "sync A_COPY with A", wc_dir)
@@ -2294,11 +2242,7 @@ def reintegrate_creates_bogus_mergeinfo(
   svntest.main.run_svn(None, "up", wc_dir)
 
   # Reintegrate A_COPY to A.  The resulting merginfo on A should be
-  # /A_COPY:4-10
-  #
-  # Currently this test fails because the resulting mergeinfo is /A_COPY:2-6.
-  # But A_COPY didn't exist unitl r4, so /A_COPY:2-3 describes merge source
-  # path-revs which don't exist.
+  # /A_COPY:4-6
   expected_output = wc.State(A_path, {
     'D/H/psi' : Item(status='U '),
     })
@@ -2340,6 +2284,264 @@ def reintegrate_creates_bogus_mergeinfo(
                                        None, None, None, None, None,
                                        1, 1, "--reintegrate", A_path)
 
+
+#----------------------------------------------------------------------
+# Test for regression on 1.6.x branch, merge fails when source without
+# subtree mergeinfo is reintegrated into a target with subtree
+# mergeinfo.  Deliberately written in a style that works with the 1.6
+# testsuite.
+@Issue(3957)
+def no_source_subtree_mergeinfo(sbox):
+  "source without subtree mergeinfo"
+
+  sbox.build()
+  wc_dir=sbox.wc_dir
+
+  svntest.main.file_write(os.path.join(wc_dir, 'A', 'B', 'E', 'alpha'),
+                          'AAA\n' +
+                          'BBB\n' +
+                          'CCC\n')
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Create branch-1
+  svntest.main.run_svn(None, 'copy',
+                       os.path.join(wc_dir, 'A', 'B'),
+                       os.path.join(wc_dir, 'A', 'B1'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+
+  # Create branch-1
+  svntest.main.run_svn(None, 'copy',
+                       os.path.join(wc_dir, 'A', 'B'),
+                       os.path.join(wc_dir, 'A', 'B2'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+
+  # Change on trunk
+  svntest.main.file_write(os.path.join(wc_dir, 'A', 'B', 'E', 'alpha'),
+                          'AAAxx\n' +
+                          'BBB\n' +
+                          'CCC\n')
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+
+  # Change on branch-1
+  svntest.main.file_write(os.path.join(wc_dir, 'A', 'B1', 'E', 'alpha'),
+                          'AAA\n' +
+                          'BBBxx\n' +
+                          'CCC\n')
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+
+  # Change on branch-2
+  svntest.main.file_write(os.path.join(wc_dir, 'A', 'B2', 'E', 'alpha'),
+                          'AAA\n' +
+                          'BBB\n' +
+                          'CCCxx\n')
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Merge trunk to branch-1
+  svntest.main.run_svn(None, 'merge', '^/A/B', os.path.join(wc_dir, 'A', 'B1'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Reintegrate branch-1 subtree to trunk subtree
+  svntest.main.run_svn(None, 'merge', '--reintegrate',
+                       '^/A/B1/E', os.path.join(wc_dir, 'A', 'B', 'E'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Merge trunk to branch-2
+  svntest.main.run_svn(None, 'merge', '^/A/B', os.path.join(wc_dir, 'A', 'B2'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Reverse merge branch-1 subtree to branch-2 subtree, this removes
+  # the subtree mergeinfo from branch 2
+  svntest.main.run_svn(None, 'merge', '-r8:2',
+                       '^/A/B1/E', os.path.join(wc_dir, 'A', 'B2', 'E'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Verify that merge results in no subtree mergeinfo
+  svntest.actions.run_and_verify_svn(None, [], [], 'propget', 'svn:mergeinfo',
+                                     sbox.repo_url + '/A/B2/E')
+
+  # Merge trunk to branch-2
+  svntest.main.run_svn(None, 'merge', '^/A/B', os.path.join(wc_dir, 'A', 'B2'))
+  svntest.main.run_svn(None, 'commit', '-m', 'log message', wc_dir)
+  svntest.main.run_svn(None, 'update', wc_dir)
+
+  # Verify that there is still no subtree mergeinfo
+  svntest.actions.run_and_verify_svn(None, [], [], 'propget', 'svn:mergeinfo',
+                                     sbox.repo_url + '/A/B2/E')
+
+  # Reintegrate branch-2 to trunk, this fails in 1.6.x from 1.6.13.
+  # The error message states revisions /A/B/E:3-11 are missing from
+  # /A/B2/E and yet the mergeinfo on /A/B2 is /A/B:3-11 and /A/B2/E
+  # has no mergeinfo.
+  expected_output = wc.State(os.path.join(wc_dir, 'A', 'B'), {
+      'E'       : Item(status=' U'),
+      'E/alpha' : Item(status='U '),
+      })
+  expected_mergeinfo = wc.State(os.path.join(wc_dir, 'A', 'B'), {
+      '' : Item(status=' U'),
+      })
+  expected_elision = wc.State(os.path.join(wc_dir, 'A', 'B'), {
+      })
+  expected_disk = wc.State('', {
+      ''        : Item(props={SVN_PROP_MERGEINFO : '/A/B2:4-12'}),
+      'E'       : Item(),
+      'E/alpha' : Item("AAA\n" +
+                       "BBB\n" +
+                       "CCCxx\n"),
+      'E/beta'  : Item("This is the file 'beta'.\n"),
+      'F'       : Item(),
+      'lambda'  : Item("This is the file 'lambda'.\n"),
+      })
+  expected_skip = wc.State(os.path.join(wc_dir, 'A', 'B'), {
+      })
+  svntest.actions.run_and_verify_merge(os.path.join(wc_dir, 'A', 'B'),
+                                       None, None, '^/A/B2', None,
+                                       expected_output, expected_mergeinfo,
+                                       expected_elision, expected_disk,
+                                       None, expected_skip,
+                                       None, None, None, None, None,
+                                       1, 1, '--reintegrate',
+                                       os.path.join(wc_dir, 'A', 'B'))
+  # For 1.6 testsuite use:
+  # svntest.actions.run_and_verify_merge(os.path.join(wc_dir, 'A', 'B'),
+  #                                      None, None, '^/A/B2',
+  #                                      expected_output,
+  #                                      expected_disk,
+  #                                      None, expected_skip,
+  #                                      None, None, None, None, None,
+  #                                      1, 1, '--reintegrate')
+
+#----------------------------------------------------------------------
+@SkipUnless(server_has_mergeinfo)
+@Issue(3961)
+def reintegrate_replaced_source(sbox):
+  "reintegrate a replaced source branch"
+
+  # Make A_COPY branch in r2, and do a few more commits to A in r3-6.
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  expected_disk, expected_status = set_up_branch(sbox)
+
+  A_path         = os.path.join(sbox.wc_dir, "A")
+  A_COPY_path    = os.path.join(sbox.wc_dir, "A_COPY")
+  beta_COPY_path = os.path.join(sbox.wc_dir, "A_COPY", "B", "E", "beta")
+  mu_COPY_path   = os.path.join(sbox.wc_dir, "A_COPY", "mu")  
+
+  # Using cherrypick merges, simulate a series of sync merges from A to
+  # A_COPY with a replace of A_COPY along the way.
+  #
+  # r6 - Merge r3 from A to A_COPY
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'merge', sbox.repo_url + '/A', A_COPY_path,
+                       '-c3')
+  svntest.main.run_svn(None, 'ci', '-m', 'Merge r3 from A to A_COPY', wc_dir)
+
+  # r8 - Merge r4 from A to A_COPY
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'merge', sbox.repo_url + '/A', A_COPY_path,
+                       '-c4')
+  svntest.main.run_svn(None, 'ci', '-m', 'Merge r4 from A to A_COPY', wc_dir)
+
+  # r9 - Merge r5 from A to A_COPY. Make an additional edit to
+  # A_COPY/B/E/beta.
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'merge', sbox.repo_url + '/A', A_COPY_path,
+                       '-c5')
+  svntest.main.file_write(beta_COPY_path, "Branch edit mistake.\n")
+  svntest.main.run_svn(None, 'ci', '-m', 'Merge r5 from A to A_COPY', wc_dir)
+
+  # r10 - Delete A_COPY and replace it with A_COPY@8. This removes the edit
+  # we made above in r9 to A_COPY/B/E/beta.
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'delete', A_COPY_path)
+  svntest.main.run_svn(None, 'copy', sbox.repo_url + '/A_COPY@8',
+                       A_COPY_path)
+  svntest.main.run_svn(None, 'ci', '-m', 'Replace A_COPY with A_COPY@8',
+                       wc_dir)
+
+  # r11 - Make an edit on A_COPY/mu.
+  svntest.main.file_write(mu_COPY_path, "Branch edit.\n")
+  svntest.main.run_svn(None, 'ci', '-m', 'Branch edit',
+                       wc_dir)
+
+  # r12 - Do a final sync merge of A to A_COPY in preparation for
+  # reintegration.  
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'merge', sbox.repo_url + '/A', A_COPY_path)
+  svntest.main.run_svn(None, 'ci', '-m', 'Sycn A_COPY with A', wc_dir)
+
+  # Reintegrate A_COPY to A.  The resulting mergeinfo should be
+  # '/A_COPY:2-8,10-12' because of the replacement which removed /A_COPY:9
+  # from the reintegrate source's history.
+  svntest.main.run_svn(None, 'up', wc_dir)
+  expected_output = wc.State(A_path, {
+    'mu' : Item(status='U '),
+    })
+  expected_mergeinfo_output = wc.State(A_path, {
+    ''   : Item(status=' U'),
+    })
+  expected_elision_output = wc.State(A_path, {
+    })
+  expected_status = wc.State(A_path, {
+    ''          : Item(status=' M'),
+    'B'         : Item(status='  '),
+    'mu'        : Item(status='M '),
+    'B/E'       : Item(status='  '),
+    'B/E/alpha' : Item(status='  '),
+    'B/E/beta'  : Item(status='  '),
+    'B/lambda'  : Item(status='  '),
+    'B/F'       : Item(status='  '),
+    'C'         : Item(status='  '),
+    'D'         : Item(status='  '),
+    'D/G'       : Item(status='  '),
+    'D/G/pi'    : Item(status='  '),
+    'D/G/rho'   : Item(status='  '),
+    'D/G/tau'   : Item(status='  '),
+    'D/gamma'   : Item(status='  '),
+    'D/H'       : Item(status='  '),
+    'D/H/chi'   : Item(status='  '),
+    'D/H/psi'   : Item(status='  '),
+    'D/H/omega' : Item(status='  '),
+    })
+  expected_status.tweak(wc_rev=12)
+  expected_disk = wc.State('', {
+    ''          : Item(props={SVN_PROP_MERGEINFO : '/A_COPY:2-8,10-12'}),
+    'B'         : Item(),
+    'mu'        : Item("Branch edit.\n"),
+    'B/E'       : Item(),
+    'B/E/alpha' : Item("This is the file 'alpha'.\n"),
+    'B/E/beta'  : Item("New content"),
+    'B/lambda'  : Item("This is the file 'lambda'.\n"),
+    'B/F'       : Item(),
+    'C'         : Item(),
+    'D'         : Item(),
+    'D/G'       : Item(),
+    'D/G/pi'    : Item("This is the file 'pi'.\n"),
+    'D/G/rho'   : Item("New content"),
+    'D/G/tau'   : Item("This is the file 'tau'.\n"),
+    'D/gamma'   : Item("This is the file 'gamma'.\n"),
+    'D/H'       : Item(),
+    'D/H/chi'   : Item("This is the file 'chi'.\n"),
+    'D/H/psi'   : Item("New content"),
+    'D/H/omega' : Item("New content"),
+    })
+  expected_skip = wc.State(A_path, { })
+  svntest.actions.run_and_verify_merge(A_path, None, None,
+                                       sbox.repo_url + '/A_COPY', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       [], None, None, None, None, True, True,
+                                       '--reintegrate', A_path)
+  
 ########################################################################
 # Run the tests
 
@@ -2361,6 +2563,8 @@ test_list = [ None,
               added_subtrees_with_mergeinfo_break_reintegrate,
               two_URL_merge_removes_valid_mergeinfo_from_target,
               reintegrate_creates_bogus_mergeinfo,
+              no_source_subtree_mergeinfo,
+              reintegrate_replaced_source,
              ]
 
 if __name__ == '__main__':