You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/10 20:06:33 UTC

svn commit: r984153 [35/39] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/ build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hu...

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/mergeinfo_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/mergeinfo_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/mergeinfo_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/mergeinfo_tests.py Tue Aug 10 18:06:17 2010
@@ -3,7 +3,7 @@
 #  mergeinfo_tests.py:  testing Merge Tracking reporting
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -172,18 +172,20 @@ def non_inheritable_mergeinfo(sbox):
   svntest.actions.run_and_verify_svn(None, ["At revision 6.\n"], [], 'up',
                                      wc_dir)
   expected_status.tweak(wc_rev=6)
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[4]], 'U    ' +
-                                                           rho_COPY_path +
-                                                           '\n'),
-                                     [], 'merge', '-c4',
-                                     sbox.repo_url + '/A',
-                                     A_COPY_path)
-  svntest.actions.run_and_verify_svn(None,
-                                     [], # Noop due to shallow depth
-                                     [], 'merge', '-c6',
-                                     sbox.repo_url + '/A',
-                                     A_COPY_path, '--depth', 'empty')
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[4]],
+                          ['U    ' + rho_COPY_path + '\n',
+                           ' U   ' + A_COPY_path + '\n',]),
+    [], 'merge', '-c4',
+    sbox.repo_url + '/A',
+    A_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[6]], ' G   ' + A_COPY_path + '\n'),
+    [], 'merge', '-c6',
+    sbox.repo_url + '/A',
+    A_COPY_path, '--depth', 'empty')
   expected_output = wc.State(wc_dir, {
     'A_COPY'         : Item(verb='Sending'),
     'A_COPY/D/G/rho' : Item(verb='Sending'),
@@ -229,6 +231,7 @@ def recursive_mergeinfo(sbox):
   # Some paths we'll care about
   A_path          = os.path.join(wc_dir, "A")
   A_COPY_path     = os.path.join(wc_dir, "A_COPY")
+  B_COPY_path     = os.path.join(wc_dir, "A_COPY", "B")
   C_COPY_path     = os.path.join(wc_dir, "A_COPY", "C")
   rho_COPY_path   = os.path.join(wc_dir, "A_COPY", "D", "G", "rho")
   H_COPY_path     = os.path.join(wc_dir, "A_COPY", "D", "H")
@@ -259,45 +262,54 @@ def recursive_mergeinfo(sbox):
   # Merge r4 from A2 to A_COPY at depth empty
   svntest.actions.run_and_verify_svn(None, ["At revision 8.\n"], [], 'up',
                                      wc_dir)
-  svntest.actions.run_and_verify_svn(None,
-                                     #expected_merge_output([[4]], 'U    ' +
-                                     #                      rho_COPY_path +
-                                     #                      '\n'),
-                                     [], [], 'merge', '-c4', '--depth', 'empty',
-                                     sbox.repo_url + '/A2',
-                                     A_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[4]], ' U   ' + A_COPY_path + '\n'),
+    [], 'merge', '-c4', '--depth', 'empty',
+    sbox.repo_url + '/A2',
+    A_COPY_path)
 
   # Merge r6 from A2/D/H to A_COPY/D/H
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[6]], 'U    ' +
-                                                           omega_COPY_path +
-                                                           '\n'),
-                                     [], 'merge', '-c6',
-                                     sbox.repo_url + '/A2/D/H',
-                                     H_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[6]],
+                          ['U    ' + omega_COPY_path + '\n',
+                           ' G   ' + H_COPY_path + '\n']),
+    [], 'merge', '-c6',
+    sbox.repo_url + '/A2/D/H',
+    H_COPY_path)
 
   # Merge r5 from A2 to A_COPY
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[5]], 'U    ' +
-                                                           beta_COPY_path +
-                                                           '\n'),
-                                     [], 'merge', '-c5',
-                                     sbox.repo_url + '/A2',
-                                     A_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[5]],
+                          ['U    ' + beta_COPY_path + '\n',
+                           ' G   ' + A_COPY_path + '\n',
+                           ' G   ' + B_COPY_path + '\n',
+                           ' U   ' + B_COPY_path + '\n',], # Elision
+                          elides=True),
+    [], 'merge', '-c5',
+    sbox.repo_url + '/A2',
+    A_COPY_path)
 
   # Reverse merge -r5 from A2/C to A_COPY/C leaving empty mergeinfo on
   # A_COPY/C.
-  svntest.actions.run_and_verify_svn(None, [], [], 'merge', '-c-5',
-                                     sbox.repo_url + '/A2/C', C_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[-5]],
+                          ' G   ' + C_COPY_path + '\n'),
+    [], 'merge', '-c-5',
+    sbox.repo_url + '/A2/C', C_COPY_path)
 
   # Merge r8 from A2/B/F to A_COPY/B/F
-  svntest.actions.run_and_verify_svn(None,
-                                     expected_merge_output([[8]], 'A    ' +
-                                                           nu_COPY_path +
-                                                           '\n'),
-                                     [], 'merge', '-c8',
-                                     sbox.repo_url + '/A2/B/F',
-                                     F_COPY_path)
+  svntest.actions.run_and_verify_svn(
+    None,
+    expected_merge_output([[8]],
+                          ['A    ' + nu_COPY_path + '\n',
+                           ' G   ' + F_COPY_path + '\n']),
+    [], 'merge', '-c8',
+    sbox.repo_url + '/A2/B/F',
+    F_COPY_path)
 
   # Commit everything this far as r9
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -359,7 +371,7 @@ def mergeinfo_on_pegged_wc_path(sbox):
   psi_COPY_path   = os.path.join(wc_dir, "A_COPY", "D", "H", "psi")
   omega_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "H", "omega")
   beta_COPY_path  = os.path.join(wc_dir, "A_COPY", "B", "E", "beta")
- 
+
   # Do a couple merges
   #
   # r7 - Merge -c3,6 from A to A_COPY.
@@ -367,7 +379,9 @@ def mergeinfo_on_pegged_wc_path(sbox):
     None,
     expected_merge_output([[3],[6]],
                           ['U    ' + psi_COPY_path + '\n',
-                           'U    ' + omega_COPY_path + '\n']),
+                           'U    ' + omega_COPY_path + '\n',
+                           ' U   ' + A_COPY_path + '\n',
+                           ' G   ' + A_COPY_path + '\n',]),
     [], 'merge', '-c3,6', sbox.repo_url + '/A', A_COPY_path)
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'ci', wc_dir,
@@ -377,7 +391,8 @@ def mergeinfo_on_pegged_wc_path(sbox):
   svntest.actions.run_and_verify_svn(
     None,
     expected_merge_output([[5]],
-                          'U    ' + beta_COPY_path + '\n'),
+                          ['U    ' + beta_COPY_path + '\n',
+                           ' U   ' + A_COPY_path + '\n']),
     [], 'merge', '-c5', sbox.repo_url + '/A', A_COPY_path)
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'ci', wc_dir,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/obliterate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/obliterate_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/obliterate_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/obliterate_tests.py Tue Aug 10 18:06:17 2010
@@ -3,7 +3,7 @@
 #  obliterate_tests.py:  testing Obliterate
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -42,9 +42,10 @@ SkipUnless = svntest.testcase.SkipUnless
 # Test utilities
 #
 
-obliteration_dirs = ['f-mod', 'f-add', 'f-del', 'f-rpl', 'f-mov']
+#obliteration_dirs = ['f-mod', 'f-add', 'f-del', 'f-rpl', 'f-mov']
+obliteration_dirs = ['f-mod']
 
-def create_dd1_scenarios(wc):
+def create_dd1_scenarios(wc, repo):
   """Create, in the initially empty repository of the SvnWC WC, the
      obliteration test scenarios depicted in each "Example 1" in
      <notes/obliterate/fspec-dd1/dd1-file-ops.svg>."""
@@ -52,38 +53,63 @@ def create_dd1_scenarios(wc):
   # r1: base directories
   for dir in obliteration_dirs:
     wc.svn_mkdir(dir)
-  rev = wc.svn_commit()
+  wc.svn_commit()
 
   # r2 to r8 inclusive, just so that the obliteration rev is a round and
   # consistent number (10), no matter what complexity of history we have.
-  while rev < 8:
-    wc.svn_set_props('', { 'this-is-rev': str(rev + 1) })
-    rev = wc.svn_commit()
+  while repo.head_rev < 8:
+    repo.svn_mkdirs('tmp/' + str(repo.head_rev + 1))
+  wc.svn_update()
 
   # r9: add the files used in the scenarios
-  wc.svn_file_create_add('f-mod/F', "Pear\n")
-  wc.svn_file_create_add('f-del/F', "Pear\n")
-  wc.svn_file_create_add('f-rpl/F', "Pear\n")
-  wc.svn_file_create_add('f-mov/E', "Pear\n")  # 'E' will be moved to 'F'
+  if 'f-mod' in obliteration_dirs:
+    wc.svn_file_create_add('f-mod/F', "Pear\n")
+  if 'f-add' in obliteration_dirs:
+    pass  # nothing needed
+  if 'f-del' in obliteration_dirs:
+    wc.svn_file_create_add('f-del/F', "Pear\n")
+  if 'f-rpl' in obliteration_dirs:
+    wc.svn_file_create_add('f-rpl/F', "Pear\n")
+  if 'f-mov' in obliteration_dirs:
+    wc.svn_file_create_add('f-mov/E', "Pear\n")  # 'E' will be moved to 'F'
   wc.svn_commit()
 
   # r10: the rev in which files named 'F' are to be obliterated
-  wc.file_modify('f-mod/F', 'Apple\n')
-  wc.svn_file_create_add('f-add/F', 'Apple\n')
-  wc.svn_delete('f-del/F')
-  wc.svn_delete('f-rpl/F')
-  wc.svn_file_create_add('f-rpl/F', 'Apple\n')
-  wc.svn_move('f-mov/E', 'f-mov/F')
-  wc.file_modify('f-mov/F', 'Apple\n')
-  rev = wc.svn_commit(log='Rev to be obliterated')
+  if 'f-mod' in obliteration_dirs:
+    wc.file_modify('f-mod/F', 'Apple\n')
+  if 'f-add' in obliteration_dirs:
+    wc.svn_file_create_add('f-add/F', 'Apple\n')
+  if 'f-del' in obliteration_dirs:
+    wc.svn_delete('f-del/F')
+  if 'f-rpl' in obliteration_dirs:
+    wc.svn_delete('f-rpl/F')
+    wc.svn_file_create_add('f-rpl/F', 'Apple\n')
+  if 'f-mov' in obliteration_dirs:
+    wc.svn_move('f-mov/E', 'f-mov/F')
+    wc.file_modify('f-mov/F', 'Apple\n')
+  wc.svn_commit(log='Rev to be obliterated')
 
   # r11: some more recent history that refers to the revision we changed
   # (We are not ready to test this yet.)
-  #for dir in ['f-mod', 'f-add', 'f-rpl', 'f-mov']:
-  #  wc.file_modify(dir + '/F', 'Orange\n')
+  #for dir in obliteration_dirs:
+  #  if not dir == 'f-del':
+  #    wc.file_modify(dir + '/F', 'Orange\n')
   #wc.svn_commit()
 
-  return rev
+  return 10
+
+def hook_enable(repo):
+  """Make a pre-obliterate hook in REPO (an svntest.objects.SvnRepository)
+  that allows the user 'jrandom' to do any obliteration."""
+
+  hook_path = os.path.join(repo.repo_absdir, 'hooks', 'pre-obliterate')
+  # Embed the text carefully: it might include characters like "%" and "'".
+  main.create_python_hook_script(hook_path, 'import sys\n'
+    'repos = sys.argv[1]\n'
+    'user = sys.argv[2]\n'
+    'if user == "jrandom":\n'
+    '  sys.exit(0)\n'
+    'sys.exit(1)\n')
 
 ######################################################################
 # Tests
@@ -103,13 +129,13 @@ def obliterate_1(sbox):
                                   expected_disk)
 
   # Create test utility objects
-  wc = objects.SvnWC(sbox.wc_dir)
   repo = objects.SvnRepository(sbox.repo_url, sbox.repo_dir)
+  wc = objects.SvnWC(sbox.wc_dir, repo)
 
   os.chdir(sbox.wc_dir)
 
   # Create scenarios ready for obliteration
-  apple_rev = create_dd1_scenarios(wc)
+  apple_rev = create_dd1_scenarios(wc, repo)
 
   # Dump the repository state, if possible, for debugging
   try:
@@ -117,6 +143,8 @@ def obliterate_1(sbox):
   except:
     pass
 
+  hook_enable(repo)
+
   # Obliterate a file in the revision where the file content was 'Apple'
   for dir in obliteration_dirs:
     repo.obliterate_node_rev(dir + '/F', apple_rev)
@@ -127,15 +155,58 @@ def obliterate_1(sbox):
   except:
     pass
 
+def pre_obliterate_hook(sbox):
+  "test the pre-obliterate hook"
+
+  # Create empty repos and WC
+  actions.guarantee_empty_repository(sbox.repo_dir)
+  expected_out = svntest.wc.State(sbox.wc_dir, {})
+  expected_disk = svntest.wc.State(sbox.wc_dir, {})
+  actions.run_and_verify_checkout(sbox.repo_url, sbox.wc_dir, expected_out,
+                                  expected_disk)
+
+  # Create test utility objects
+  repo = objects.SvnRepository(sbox.repo_url, sbox.repo_dir)
+  wc = objects.SvnWC(sbox.wc_dir, repo)
+
+  os.chdir(sbox.wc_dir)
+
+  # Create scenarios ready for obliteration
+  apple_rev = create_dd1_scenarios(wc, repo)
+  dir = obliteration_dirs[0]
+
+  hook_path = os.path.join(repo.repo_absdir, 'hooks', 'pre-obliterate')
+
+  # Try an obliterate that should be forbidden as no hook is installed
+  exp_err = 'svn: Repository has not been enabled to accept obliteration\n'
+  repo.obliterate_node_rev(dir + '/F', apple_rev,
+                           exp_out=[], exp_err=exp_err, exp_exit=1)
+
+  # Try an obliterate that should be forbidden by the hook
+  main.create_python_hook_script(hook_path, 'import sys\n'
+    'sys.stderr.write("Pre-oblit, %s, %s" %\n'
+    '                 (sys.argv[1], sys.argv[2]))\n'
+    'sys.exit(1)\n')
+  exp_err = 'svn: Obliteration blocked by pre-obliterate hook (exit code 1) with output:|' + \
+            'Pre-oblit, /.*, jrandom'
+  repo.obliterate_node_rev(dir + '/F', apple_rev,
+                           exp_out=[], exp_err=exp_err, exp_exit=1)
+
+  # Try an obliterate that should be allowed by the hook
+  hook_enable(repo)
+  repo.obliterate_node_rev(dir + '/F', apple_rev)
+
 
 ########################################################################
 # Run the tests
 
+def supports_obliterate():
+  return svntest.main.is_ra_type_file() and not svntest.main.is_fs_type_fsfs()
+
 # list all tests here, starting with None:
 test_list = [ None,
-              SkipUnless(obliterate_1, lambda:
-                         svntest.main.is_ra_type_file() and
-                         not svntest.main.is_fs_type_fsfs()),
+              SkipUnless(obliterate_1, supports_obliterate),
+              SkipUnless(pre_obliterate_hook, supports_obliterate),
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/patch_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/patch_tests.py Tue Aug 10 18:06:17 2010
@@ -4,7 +4,7 @@
 #  patch_tests.py:  some basic patch tests
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -49,8 +49,8 @@ XFail = svntest.testcase.XFail
 ########################################################################
 #Tests
 
-def patch_unidiff(sbox):
-  "apply a unidiff patch"
+def patch(sbox):
+  "basic patch"
 
   sbox.build()
   wc_dir = sbox.wc_dir
@@ -186,11 +186,11 @@ def patch_unidiff(sbox):
   ]
 
   expected_output = [
-    'U    %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
-    'U    %s\n' % os.path.join(wc_dir, 'iota'),
-    'A    %s\n' % os.path.join(wc_dir, 'new'),
-    'U    %s\n' % os.path.join(wc_dir, 'A', 'mu'),
-    'D    %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+    'A         %s\n' % os.path.join(wc_dir, 'new'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+    'D         %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
   ]
 
   expected_disk = svntest.main.greek_state.copy()
@@ -219,8 +219,8 @@ def patch_unidiff(sbox):
                                        1) # dry-run
 
 
-def patch_unidiff_absolute_paths(sbox):
-  "apply a unidiff patch containing absolute paths"
+def patch_absolute_paths(sbox):
+  "patch containing absolute paths"
 
   sbox.build()
   wc_dir = sbox.wc_dir
@@ -256,7 +256,7 @@ def patch_unidiff_absolute_paths(sbox):
 
   lambda_path = os.path.join(os.path.sep, 'A', 'B', 'lambda')
   expected_output = [
-    'U    %s\n' % os.path.join('A', 'B', 'E', 'alpha'),
+    'U         %s\n' % os.path.join('A', 'B', 'E', 'alpha'),
     'Skipped \'%s\'\n' % lambda_path,
     'Summary of conflicts:\n',
     '  Skipped paths: 1\n'
@@ -283,8 +283,8 @@ def patch_unidiff_absolute_paths(sbox):
                                        1, # check-props
                                        1) # dry-run
 
-def patch_unidiff_offset(sbox):
-  "apply a unidiff patch with offset searching"
+def patch_offset(sbox):
+  "patch with offset searching"
 
   sbox.build()
   wc_dir = sbox.wc_dir
@@ -470,8 +470,11 @@ def patch_unidiff_offset(sbox):
   os.chdir(wc_dir)
 
   expected_output = [
-    'U    %s\n' % os.path.join('A', 'mu'),
-    'U    iota\n'
+    'U         %s\n' % os.path.join('A', 'mu'),
+    '>         applied hunk @@ -6,6 +6,9 @@ with offset -1\n',
+    '>         applied hunk @@ -14,11 +17,8 @@ with offset 4\n',
+    'U         iota\n',
+    '>         applied hunk @@ -5,6 +5,7 @@ with offset -3\n',
   ]
 
   expected_disk = svntest.main.greek_state.copy()
@@ -494,7 +497,7 @@ def patch_unidiff_offset(sbox):
                                        1) # dry-run
 
 def patch_chopped_leading_spaces(sbox):
-  "apply a unidiff patch with chopped leading spaces"
+  "patch with chopped leading spaces"
 
   sbox.build()
   wc_dir = sbox.wc_dir
@@ -630,11 +633,11 @@ def patch_chopped_leading_spaces(sbox):
   ]
 
   expected_output = [
-    'U    %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
-    'U    %s\n' % os.path.join(wc_dir, 'iota'),
-    'A    %s\n' % os.path.join(wc_dir, 'new'),
-    'U    %s\n' % os.path.join(wc_dir, 'A', 'mu'),
-    'D    %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+    'A         %s\n' % os.path.join(wc_dir, 'new'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+    'D         %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
   ]
 
   expected_disk = svntest.main.greek_state.copy()
@@ -663,8 +666,8 @@ def patch_chopped_leading_spaces(sbox):
                                        1) # dry-run
 
 
-def patch_unidiff_strip1(sbox):
-  "apply a unidiff patch with -p1"
+def patch_strip1(sbox):
+  "patch with -p1"
 
   sbox.build()
   wc_dir = sbox.wc_dir
@@ -800,11 +803,11 @@ def patch_unidiff_strip1(sbox):
   ]
 
   expected_output = [
-    'U    %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
-    'U    %s\n' % os.path.join(wc_dir, 'iota'),
-    'A    %s\n' % os.path.join(wc_dir, 'new'),
-    'U    %s\n' % os.path.join(wc_dir, 'A', 'mu'),
-    'D    %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+    'A         %s\n' % os.path.join(wc_dir, 'new'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+    'D         %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
   ]
 
   expected_disk = svntest.main.greek_state.copy()
@@ -833,17 +836,1352 @@ def patch_unidiff_strip1(sbox):
                                        1, # dry-run
                                        '-p1')
 
+def patch_add_new_dir(sbox):
+  "patch with missing dirs"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+
+  # The first diff is adding 'new' with two missing dirs. The second is
+  # adding 'new' with one missing dir to a 'A' that is locally deleted
+  # (should be skipped). The third is adding 'new' with a directory that
+  # is unversioned (should be skipped as well).
+  unidiff_patch = [
+    "Index: new\n",
+    "===================================================================\n",
+    "--- X/Y/new\t(revision 0)\n",
+    "+++ X/Y/new\t(revision 0)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new\n",
+    "Index: new\n",
+    "===================================================================\n",
+    "--- A/C/Y/new\t(revision 0)\n",
+    "+++ A/C/Y/new\t(revision 0)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new\n",
+    "Index: new\n",
+    "===================================================================\n",
+    "--- A/Z/new\t(revision 0)\n",
+    "+++ A/Z/new\t(revision 0)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new\n",
+  ]
+
+  C_path = os.path.join(wc_dir, 'A', 'C')
+  svntest.actions.run_and_verify_svn("Deleting C failed", None, [],
+                                     'rm', C_path)
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  A_C_Y_new_path = os.path.join(wc_dir, 'A', 'C', 'Y', 'new')
+  A_Z_new_path = os.path.join(wc_dir, 'A', 'Z', 'new')
+  expected_output = [
+    'A         %s\n' % os.path.join(wc_dir, 'X'),
+    'A         %s\n' % os.path.join(wc_dir, 'X', 'Y'),
+    'A         %s\n' % os.path.join(wc_dir, 'X', 'Y', 'new'),
+    'Skipped \'%s\'\n' % A_C_Y_new_path,
+    'Skipped \'%s\'\n' % A_Z_new_path,
+    'Summary of conflicts:\n',
+    '  Skipped paths: 2\n',
+  ]
+
+  # Create the unversioned obstructing directory
+  os.mkdir(os.path.dirname(A_Z_new_path))
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({'X/Y/new': Item(contents='new\n')})
+  expected_disk.add({'A/Z': Item()})
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.add({'X' : Item(status='A ', wc_rev=0)})
+  expected_status.add({'X/Y' : Item(status='A ', wc_rev=0)})
+  expected_status.add({'X/Y/new' : Item(status='A ', wc_rev=0)})
+  expected_status.add({'A/C' : Item(status='D ', wc_rev=1)})
+
+  expected_skip = wc.State('', {A_C_Y_new_path : Item(),
+                                A_Z_new_path : Item() })
+
+  svntest.actions.run_and_verify_patch(wc_dir,
+                                       os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+def patch_reject(sbox):
+  "patch which is rejected"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Set gamma contents
+  gamma_contents = "Hello there! I'm the file 'gamma'.\n"
+  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  svntest.main.file_write(gamma_path, gamma_contents)
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/D/gamma'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/D/gamma', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: A/D/gamma\n",
+    "===================================================================\n",
+    "--- A/D/gamma\t(revision 1)\n",
+    "+++ A/D/gamma\t(working copy)\n",
+    "@@ -1 +1 @@\n",
+    "-This is really the file 'gamma'.\n",
+    "+It is really the file 'gamma'.\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'C         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+    '>         rejected hunk @@ -1,1 +1,1 @@\n',
+    'Summary of conflicts:\n',
+    '  Text conflicts: 1\n',
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/D/gamma', contents=gamma_contents)
+
+  reject_file_contents = [
+    "--- A/D/gamma\n",
+    "+++ A/D/gamma\n",
+    "@@ -1,1 +1,1 @@\n",
+    "-This is really the file 'gamma'.\n",
+    "+It is really the file 'gamma'.\n",
+  ]
+  expected_disk.add({'A/D/gamma.svnpatch.rej' :
+                     Item(contents=''.join(reject_file_contents))})
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/D/gamma', wc_rev=2)
+  # ### not yet
+  #expected_status.tweak('A/D/gamma', status='C ')
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+def patch_keywords(sbox):
+  "patch containing keywords"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Set gamma contents
+  gamma_contents = "$Rev$\nHello there! I'm the file 'gamma'.\n"
+  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  svntest.main.file_write(gamma_path, gamma_contents)
+  # Expand the keyword
+  svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Rev',
+                       os.path.join(wc_dir, 'A', 'D', 'gamma'))
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/D/gamma'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/D/gamma', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+
+  # Apply patch
+
+  unidiff_patch = [
+   "Index: gamma\n",
+   "===================================================================\n",
+   "--- A/D/gamma	(revision 3)\n",
+   "+++ A/D/gamma	(working copy)\n",
+   "@@ -1,2 +1,3 @@\n",
+   " $Rev$\n",
+   " Hello there! I'm the file 'gamma'.\n",
+   "+booo\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  gamma_contents = "$Rev: 2 $\nHello there! I'm the file 'gamma'.\nbooo\n"
+  expected_disk.tweak('A/D/gamma', contents=gamma_contents,
+                      props={'svn:keywords' : 'Rev'})
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/D/gamma', status='M ', wc_rev=2)
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+def patch_with_fuzz(sbox):
+  "patch with fuzz"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  # We have replaced a couple of lines to cause fuzz. Those lines contains
+  # the word fuzz
+  mu_contents = [
+    "Line replaced for fuzz = 1\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "Line replaced for fuzz = 2 with only the second context line changed\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 13th June. 2009\n",
+    "\n",
+    "This line is inserted to cause an offset of +1\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+    "\n",
+    "Line replaced for fuzz = 2\n",
+    "Line replaced for fuzz = 2\n",
+  ]
+
+  # Set mu contents
+  svntest.main.file_write(mu_path, ''.join(mu_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                      expected_status, None, wc_dir)
+
+  unidiff_patch = [
+    "Index: mu\n",
+    "===================================================================\n",
+    "--- A/mu\t(revision 0)\n",
+    "+++ A/mu\t(revision 0)\n",
+    "@@ -1,6 +1,7 @@\n",
+    " Dear internet user,\n",
+    " \n",
+    " We wish to congratulate you over your email success in our computer\n",
+    "+A new line here\n",
+    " Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    " in which email addresses were used. All participants were selected\n",
+    " through a computer ballot system drawn from over 100,000 company\n",
+    "@@ -7,7 +8,9 @@\n",
+    " and 50,000,000 individual email addresses from all over the world.\n",
+    " \n",
+    " Your email address drew and have won the sum of  750,000 Euros\n",
+    "+Another new line\n",
+    " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "+A third new line\n",
+    " file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "@@ -19,6 +20,7 @@\n",
+    " To claim your winning prize, you are to contact the appointed\n",
+    " agent below as soon as possible for the immediate release of your\n",
+    " winnings with the below details.\n",
+    "+A fourth new line\n",
+    " \n",
+    " Again, we wish to congratulate you over your email success in our\n"
+    " computer Balloting. [No trailing newline here]"
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  mu_contents = [
+    "Line replaced for fuzz = 1\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "A new line here\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "Line replaced for fuzz = 2 with only the second context line changed\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "Another new line\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "A third new line\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 13th June. 2009\n",
+    "\n",
+    "This line is inserted to cause an offset of +1\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+    "A fourth new line\n",
+    "\n",
+    "Line replaced for fuzz = 2\n",
+    "Line replaced for fuzz = 2\n",
+  ]
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+    '>         applied hunk @@ -1,6 +1,7 @@ with fuzz 1\n',
+    '>         applied hunk @@ -7,7 +8,9 @@ with fuzz 2\n',
+    '>         applied hunk @@ -19,6 +20,7 @@ with offset 1 and fuzz 2\n',
+  ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=''.join(mu_contents))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+def patch_reverse(sbox):
+  "patch in reverse"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 13th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+    "\n",
+    "Again, we wish to congratulate you over your email success in our\n"
+    "computer Balloting.\n"
+  ]
+
+  # Set mu contents
+  svntest.main.file_write(mu_path, ''.join(mu_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: A/D/gamma\n",
+    "===================================================================\n",
+    "--- A/D/gamma\t(revision 1)\n",
+    "+++ A/D/gamma\t(working copy)\n",
+    "@@ -1 +1 @@\n",
+    "+This is the file 'gamma'.\n",
+    "-It is the file 'gamma'.\n",
+    "Index: iota\n",
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    "@@ -1,2 +1 @@\n",
+    " This is the file 'iota'.\n",
+    "-Some more bytes\n",
+    "\n",
+    "Index: new\n",
+    "===================================================================\n",
+    "--- new	(revision 0)\n",
+    "+++ new	(revision 0)\n",
+    "@@ -1 +0,0 @@\n",
+    "-new\n",
+    "\n",
+    "--- A/mu	2009-06-24 15:23:55.000000000 +0100\n",
+    "+++ A/mu.orig	2009-06-24 15:21:23.000000000 +0100\n",
+    "@@ -6,9 +6,6 @@\n",
+    " through a computer ballot system drawn from over 100,000 company\n",
+    " and 50,000,000 individual email addresses from all over the world.\n",
+    " \n",
+    "-It is a promotional program aimed at encouraging internet users;\n",
+    "-therefore you do not need to buy ticket to enter for it.\n",
+    "-\n",
+    " Your email address drew and have won the sum of  750,000 Euros\n",
+    " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    " file with\n",
+    "@@ -17,8 +14,11 @@\n",
+    "     BATCH NUMBERS :\n",
+    "     EULO/1007/444/606/08;\n",
+    "     SERIAL NUMBER: 45327\n",
+    "+and PROMOTION DATE: 13th June. 2009\n",
+    "-and PROMOTION DATE: 14th June. 2009\n",
+    " \n",
+    " To claim your winning prize, you are to contact the appointed\n",
+    " agent below as soon as possible for the immediate release of your\n",
+    " winnings with the below details.\n",
+    "+\n",
+    "+Again, we wish to congratulate you over your email success in our\n",
+    "+computer Balloting.\n",
+    "Index: A/B/E/beta\n",
+    "===================================================================\n",
+    "--- A/B/E/beta	(working copy)\n",
+    "+++ A/B/E/beta	(revision 1)\n",
+    "@@ -0,0 +1 @@\n",
+    "+This is the file 'beta'.\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  gamma_contents = "It is the file 'gamma'.\n"
+  iota_contents = "This is the file 'iota'.\nSome more bytes\n"
+  new_contents = "new\n"
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "It is a promotional program aimed at encouraging internet users;\n",
+    "therefore you do not need to buy ticket to enter for it.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 14th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+  ]
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+    'A         %s\n' % os.path.join(wc_dir, 'new'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+    'D         %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/D/gamma', contents=gamma_contents)
+  expected_disk.tweak('iota', contents=iota_contents)
+  expected_disk.add({'new' : Item(contents=new_contents)})
+  expected_disk.tweak('A/mu', contents=''.join(mu_contents))
+  expected_disk.remove('A/B/E/beta')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/D/gamma', status='M ')
+  expected_status.tweak('iota', status='M ')
+  expected_status.add({'new' : Item(status='A ', wc_rev=0)})
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_status.tweak('A/B/E/beta', status='D ')
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1, # dry-run
+                                       '--reverse-diff')
+
+def patch_no_svn_eol_style(sbox):
+  "patch target with no svn:eol-style"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  if os.name == 'nt':
+    crlf = '\n'
+  else:
+    crlf = '\r\n'
+  eols = [crlf, '\015', '\n', '\012']
+
+  for target_eol in eols:
+    for patch_eol in eols:
+      mu_contents = [
+        "We wish to congratulate you over your email success in our computer",
+        target_eol,
+        "Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        target_eol,
+        "in which email addresses were used. All participants were selected",
+        target_eol,
+        "through a computer ballot system drawn from over 100,000 company",
+        target_eol,
+        "and 50,000,000 individual email addresses from all over the world.",
+        target_eol,
+        "It is a promotional program aimed at encouraging internet users;",
+        target_eol,
+      ]
+
+      # Set mu contents
+      svntest.main.file_write(mu_path, ''.join(mu_contents))
+
+      unidiff_patch = [
+        "Index: mu",
+        patch_eol,
+        "===================================================================",
+        patch_eol,
+        "--- A/mu\t(revision 0)",
+        patch_eol,
+        "+++ A/mu\t(revision 0)",
+        patch_eol,
+        "@@ -1,5 +1,6 @@",
+        patch_eol,
+        " We wish to congratulate you over your email success in our computer",
+        patch_eol,
+        " Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        patch_eol,
+        "+A new line here",
+        patch_eol,
+        " in which email addresses were used. All participants were selected",
+        patch_eol,
+        " through a computer ballot system drawn from over 100,000 company",
+        patch_eol,
+        " and 50,000,000 individual email addresses from all over the world.",
+        patch_eol,
+      ]
+
+      mu_contents = [
+        "We wish to congratulate you over your email success in our computer",
+        patch_eol,
+        "Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        patch_eol,
+        "A new line here",
+        patch_eol,
+        "in which email addresses were used. All participants were selected",
+        patch_eol,
+        "through a computer ballot system drawn from over 100,000 company",
+        patch_eol,
+        "and 50,000,000 individual email addresses from all over the world.",
+        patch_eol,
+        "It is a promotional program aimed at encouraging internet users;",
+        target_eol,
+      ]
+
+      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+      expected_output = [
+        'G         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+      ]
+      expected_disk = svntest.main.greek_state.copy()
+      expected_disk.tweak('A/mu', contents=''.join(mu_contents))
+
+      expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+      expected_status.tweak('A/mu', status='M ', wc_rev=1)
+
+      expected_skip = wc.State('', { })
+
+      svntest.actions.run_and_verify_patch(wc_dir,
+                                           os.path.abspath(patch_file_path),
+                                           expected_output,
+                                           expected_disk,
+                                           expected_status,
+                                           expected_skip,
+                                           None, # expected err
+                                           1, # check-props
+                                           1) # dry-run
+
+      expected_output = ["Reverted '" + mu_path + "'\n"]
+      svntest.actions.run_and_verify_svn(None, expected_output, [], 'revert', '-R', wc_dir)
+
+def patch_with_svn_eol_style(sbox):
+  "patch target with svn:eol-style"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+
+  if os.name == 'nt':
+    crlf = '\n'
+  else:
+    crlf = '\r\n'
+
+  eols = [crlf, '\015', '\n', '\012']
+  eol_styles = ['CRLF', 'CR', 'native', 'LF']
+  rev = 1
+  for target_eol, target_eol_style in zip(eols, eol_styles):
+    for patch_eol in eols:
+      mu_contents = [
+        "We wish to congratulate you over your email success in our computer",
+        target_eol,
+        "Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        target_eol,
+        "in which email addresses were used. All participants were selected",
+        target_eol,
+        "through a computer ballot system drawn from over 100,000 company",
+        target_eol,
+        "and 50,000,000 individual email addresses from all over the world.",
+        target_eol,
+        "It is a promotional program aimed at encouraging internet users;",
+        target_eol,
+      ]
+
+      # Set mu contents
+      svntest.main.run_svn(None, 'rm', mu_path)
+      svntest.main.run_svn(None, 'commit', '-m', 'delete mu', mu_path)
+      svntest.main.file_write(mu_path, ''.join(mu_contents))
+      svntest.main.run_svn(None, 'add', mu_path)
+      svntest.main.run_svn(None, 'propset', 'svn:eol-style', target_eol_style,
+                           mu_path)
+      svntest.main.run_svn(None, 'commit', '-m', 'set eol-style', mu_path)
+
+      unidiff_patch = [
+        "Index: mu",
+        patch_eol,
+        "===================================================================",
+        patch_eol,
+        "--- A/mu\t(revision 0)",
+        patch_eol,
+        "+++ A/mu\t(revision 0)",
+        patch_eol,
+        "@@ -1,5 +1,6 @@",
+        patch_eol,
+        " We wish to congratulate you over your email success in our computer",
+        patch_eol,
+        " Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        patch_eol,
+        "+A new line here",
+        patch_eol,
+        " in which email addresses were used. All participants were selected",
+        patch_eol,
+        " through a computer ballot system drawn from over 100,000 company",
+        patch_eol,
+        " and 50,000,000 individual email addresses from all over the world.",
+        patch_eol,
+      ]
+
+      mu_contents = [
+        "We wish to congratulate you over your email success in our computer",
+        target_eol,
+        "Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        target_eol,
+        "A new line here",
+        target_eol,
+        "in which email addresses were used. All participants were selected",
+        target_eol,
+        "through a computer ballot system drawn from over 100,000 company",
+        target_eol,
+        "and 50,000,000 individual email addresses from all over the world.",
+        target_eol,
+        "It is a promotional program aimed at encouraging internet users;",
+        target_eol,
+      ]
+
+      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+      expected_output = [
+        'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+      ]
+      expected_disk = svntest.main.greek_state.copy()
+      expected_disk.tweak('A/mu', contents=''.join(mu_contents),
+                          props={'svn:eol-style' : target_eol_style})
+
+      expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+      rev += 2
+      expected_status.tweak('A/mu', status='M ', wc_rev=rev)
+
+      expected_skip = wc.State('', { })
+
+      svntest.actions.run_and_verify_patch(wc_dir,
+                                           os.path.abspath(patch_file_path),
+                                           expected_output,
+                                           expected_disk,
+                                           expected_status,
+                                           expected_skip,
+                                           None, # expected err
+                                           1, # check-props
+                                           1) # dry-run
+
+      expected_output = ["Reverted '" + mu_path + "'\n"]
+      svntest.actions.run_and_verify_svn(None, expected_output, [], 'revert', '-R', wc_dir)
+
+def patch_with_svn_eol_style_uncommitted(sbox):
+  "patch target with uncommitted svn:eol-style"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+
+  if os.name == 'nt':
+    crlf = '\n'
+  else:
+    crlf = '\r\n'
+
+  eols = [crlf, '\015', '\n', '\012']
+  eol_styles = ['CRLF', 'CR', 'native', 'LF']
+  for target_eol, target_eol_style in zip(eols, eol_styles):
+    for patch_eol in eols:
+      mu_contents = [
+        "We wish to congratulate you over your email success in our computer",
+        '\n',
+        "Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        '\n',
+        "in which email addresses were used. All participants were selected",
+        '\n',
+        "through a computer ballot system drawn from over 100,000 company",
+        '\n',
+        "and 50,000,000 individual email addresses from all over the world.",
+        '\n',
+        "It is a promotional program aimed at encouraging internet users;",
+        '\n',
+      ]
+
+      # Set mu contents
+      svntest.main.file_write(mu_path, ''.join(mu_contents))
+      svntest.main.run_svn(None, 'propset', 'svn:eol-style', target_eol_style,
+                           mu_path)
+
+      unidiff_patch = [
+        "Index: mu",
+        patch_eol,
+        "===================================================================",
+        patch_eol,
+        "--- A/mu\t(revision 0)",
+        patch_eol,
+        "+++ A/mu\t(revision 0)",
+        patch_eol,
+        "@@ -1,5 +1,6 @@",
+        patch_eol,
+        " We wish to congratulate you over your email success in our computer",
+        patch_eol,
+        " Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        patch_eol,
+        "+A new line here",
+        patch_eol,
+        " in which email addresses were used. All participants were selected",
+        patch_eol,
+        " through a computer ballot system drawn from over 100,000 company",
+        patch_eol,
+        " and 50,000,000 individual email addresses from all over the world.",
+        patch_eol,
+      ]
+
+      mu_contents = [
+        "We wish to congratulate you over your email success in our computer",
+        target_eol,
+        "Balloting. This is a Millennium Scientific Electronic Computer Draw",
+        target_eol,
+        "A new line here",
+        target_eol,
+        "in which email addresses were used. All participants were selected",
+        target_eol,
+        "through a computer ballot system drawn from over 100,000 company",
+        target_eol,
+        "and 50,000,000 individual email addresses from all over the world.",
+        target_eol,
+        "It is a promotional program aimed at encouraging internet users;",
+        target_eol,
+      ]
+
+      svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+      expected_output = [
+        'G         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+      ]
+      expected_disk = svntest.main.greek_state.copy()
+      expected_disk.tweak('A/mu', contents=''.join(mu_contents),
+                          props={'svn:eol-style' : target_eol_style})
+
+      expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+      expected_status.tweak('A/mu', status='MM', wc_rev=1)
+
+      expected_skip = wc.State('', { })
+
+      svntest.actions.run_and_verify_patch(wc_dir,
+                                           os.path.abspath(patch_file_path),
+                                           expected_output,
+                                           expected_disk,
+                                           expected_status,
+                                           expected_skip,
+                                           None, # expected err
+                                           1, # check-props
+                                           1) # dry-run
+
+      expected_output = ["Reverted '" + mu_path + "'\n"]
+      svntest.actions.run_and_verify_svn(None, expected_output, [], 'revert', '-R', wc_dir)
+
+def patch_with_include_patterns(sbox):
+  "patch with include-patterns"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 13th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+    "\n",
+    "Again, we wish to congratulate you over your email success in our\n"
+    "computer Balloting.\n"
+  ]
+
+  # Set mu contents
+  svntest.main.file_write(mu_path, ''.join(mu_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: A/D/gamma\n",
+    "===================================================================\n",
+    "--- A/D/gamma\t(revision 1)\n",
+    "+++ A/D/gamma\t(working copy)\n",
+    "@@ -1 +1 @@\n",
+    "-This is the file 'gamma'.\n",
+    "+It is the file 'gamma'.\n",
+    "Index: iota\n",
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Some more bytes\n",
+    "\n",
+    "Index: new\n",
+    "===================================================================\n",
+    "--- new	(revision 0)\n",
+    "+++ new	(revision 0)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new\n",
+    "\n",
+    "--- A/mu.orig	2009-06-24 15:23:55.000000000 +0100\n",
+    "+++ A/mu	2009-06-24 15:21:23.000000000 +0100\n",
+    "@@ -6,6 +6,9 @@\n",
+    " through a computer ballot system drawn from over 100,000 company\n",
+    " and 50,000,000 individual email addresses from all over the world.\n",
+    " \n",
+    "+It is a promotional program aimed at encouraging internet users;\n",
+    "+therefore you do not need to buy ticket to enter for it.\n",
+    "+\n",
+    " Your email address drew and have won the sum of  750,000 Euros\n",
+    " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    " file with\n",
+    "@@ -14,11 +17,8 @@\n",
+    "     BATCH NUMBERS :\n",
+    "     EULO/1007/444/606/08;\n",
+    "     SERIAL NUMBER: 45327\n",
+    "-and PROMOTION DATE: 13th June. 2009\n",
+    "+and PROMOTION DATE: 14th June. 2009\n",
+    " \n",
+    " To claim your winning prize, you are to contact the appointed\n",
+    " agent below as soon as possible for the immediate release of your\n",
+    " winnings with the below details.\n",
+    "-\n",
+    "-Again, we wish to congratulate you over your email success in our\n",
+    "-computer Balloting.\n",
+    "Index: A/B/E/beta\n",
+    "===================================================================\n",
+    "--- A/B/E/beta	(revision 1)\n",
+    "+++ A/B/E/beta	(working copy)\n",
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'beta'.\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  gamma_contents = "It is the file 'gamma'.\n"
+  iota_contents = "This is the file 'iota'.\nSome more bytes\n"
+  new_contents = "new\n"
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "It is a promotional program aimed at encouraging internet users;\n",
+    "therefore you do not need to buy ticket to enter for it.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 14th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+  ]
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=''.join(mu_contents))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1, # dry-run
+                                       "--include-pattern", "A/mu")
+
+def patch_with_exclude_patterns(sbox):
+  "patch with exclude-patterns"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 13th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+    "\n",
+    "Again, we wish to congratulate you over your email success in our\n"
+    "computer Balloting.\n"
+  ]
+
+  # Set mu contents
+  svntest.main.file_write(mu_path, ''.join(mu_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: A/D/gamma\n",
+    "===================================================================\n",
+    "--- A/D/gamma\t(revision 1)\n",
+    "+++ A/D/gamma\t(working copy)\n",
+    "@@ -1 +1 @@\n",
+    "-This is the file 'gamma'.\n",
+    "+It is the file 'gamma'.\n",
+    "Index: iota\n",
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Some more bytes\n",
+    "\n",
+    "Index: new\n",
+    "===================================================================\n",
+    "--- new	(revision 0)\n",
+    "+++ new	(revision 0)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new\n",
+    "\n",
+    "--- A/mu.orig	2009-06-24 15:23:55.000000000 +0100\n",
+    "+++ A/mu	2009-06-24 15:21:23.000000000 +0100\n",
+    "@@ -6,6 +6,9 @@\n",
+    " through a computer ballot system drawn from over 100,000 company\n",
+    " and 50,000,000 individual email addresses from all over the world.\n",
+    " \n",
+    "+It is a promotional program aimed at encouraging internet users;\n",
+    "+therefore you do not need to buy ticket to enter for it.\n",
+    "+\n",
+    " Your email address drew and have won the sum of  750,000 Euros\n",
+    " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    " file with\n",
+    "@@ -14,11 +17,8 @@\n",
+    "     BATCH NUMBERS :\n",
+    "     EULO/1007/444/606/08;\n",
+    "     SERIAL NUMBER: 45327\n",
+    "-and PROMOTION DATE: 13th June. 2009\n",
+    "+and PROMOTION DATE: 14th June. 2009\n",
+    " \n",
+    " To claim your winning prize, you are to contact the appointed\n",
+    " agent below as soon as possible for the immediate release of your\n",
+    " winnings with the below details.\n",
+    "-\n",
+    "-Again, we wish to congratulate you over your email success in our\n",
+    "-computer Balloting.\n",
+    "Index: A/B/E/beta\n",
+    "===================================================================\n",
+    "--- A/B/E/beta	(revision 1)\n",
+    "+++ A/B/E/beta	(working copy)\n",
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'beta'.\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  gamma_contents = "It is the file 'gamma'.\n"
+  iota_contents = "This is the file 'iota'.\nSome more bytes\n"
+  new_contents = "new\n"
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "It is a promotional program aimed at encouraging internet users;\n",
+    "therefore you do not need to buy ticket to enter for it.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 14th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+  ]
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=''.join(mu_contents))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1, # dry-run
+                                       "--exclude-pattern", "A/*/gamma",
+                                       "--exclude-pattern", "new",
+                                       "--exclude-pattern", "*a")
+
+def patch_with_include_exclude_patterns(sbox):
+  "patch with include-patterns and exclude-patterns"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 13th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+    "\n",
+    "Again, we wish to congratulate you over your email success in our\n"
+    "computer Balloting.\n"
+  ]
+
+  # Set mu contents
+  svntest.main.file_write(mu_path, ''.join(mu_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu'       : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: A/D/gamma\n",
+    "===================================================================\n",
+    "--- A/D/gamma\t(revision 1)\n",
+    "+++ A/D/gamma\t(working copy)\n",
+    "@@ -1 +1 @@\n",
+    "-This is the file 'gamma'.\n",
+    "+It is the file 'gamma'.\n",
+    "Index: iota\n",
+    "===================================================================\n",
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Some more bytes\n",
+    "\n",
+    "Index: new\n",
+    "===================================================================\n",
+    "--- new	(revision 0)\n",
+    "+++ new	(revision 0)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new\n",
+    "\n",
+    "--- A/mu.orig	2009-06-24 15:23:55.000000000 +0100\n",
+    "+++ A/mu	2009-06-24 15:21:23.000000000 +0100\n",
+    "@@ -6,6 +6,9 @@\n",
+    " through a computer ballot system drawn from over 100,000 company\n",
+    " and 50,000,000 individual email addresses from all over the world.\n",
+    " \n",
+    "+It is a promotional program aimed at encouraging internet users;\n",
+    "+therefore you do not need to buy ticket to enter for it.\n",
+    "+\n",
+    " Your email address drew and have won the sum of  750,000 Euros\n",
+    " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    " file with\n",
+    "@@ -14,11 +17,8 @@\n",
+    "     BATCH NUMBERS :\n",
+    "     EULO/1007/444/606/08;\n",
+    "     SERIAL NUMBER: 45327\n",
+    "-and PROMOTION DATE: 13th June. 2009\n",
+    "+and PROMOTION DATE: 14th June. 2009\n",
+    " \n",
+    " To claim your winning prize, you are to contact the appointed\n",
+    " agent below as soon as possible for the immediate release of your\n",
+    " winnings with the below details.\n",
+    "-\n",
+    "-Again, we wish to congratulate you over your email success in our\n",
+    "-computer Balloting.\n",
+    "Index: A/B/E/beta\n",
+    "===================================================================\n",
+    "--- A/B/E/beta	(revision 1)\n",
+    "+++ A/B/E/beta	(working copy)\n",
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'beta'.\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  gamma_contents = "It is the file 'gamma'.\n"
+  iota_contents = "This is the file 'iota'.\nSome more bytes\n"
+  new_contents = "new\n"
+  mu_contents = [
+    "Dear internet user,\n",
+    "\n",
+    "We wish to congratulate you over your email success in our computer\n",
+    "Balloting. This is a Millennium Scientific Electronic Computer Draw\n",
+    "in which email addresses were used. All participants were selected\n",
+    "through a computer ballot system drawn from over 100,000 company\n",
+    "and 50,000,000 individual email addresses from all over the world.\n",
+    "\n",
+    "It is a promotional program aimed at encouraging internet users;\n",
+    "therefore you do not need to buy ticket to enter for it.\n",
+    "\n",
+    "Your email address drew and have won the sum of  750,000 Euros\n",
+    "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n",
+    "file with\n",
+    "    REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n",
+    "    WINNING NUMBER : 14-17-24-34-37-45-16\n",
+    "    BATCH NUMBERS :\n",
+    "    EULO/1007/444/606/08;\n",
+    "    SERIAL NUMBER: 45327\n",
+    "and PROMOTION DATE: 14th June. 2009\n",
+    "\n",
+    "To claim your winning prize, you are to contact the appointed\n",
+    "agent below as soon as possible for the immediate release of your\n",
+    "winnings with the below details.\n",
+  ]
+
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'mu'),
+    'D         %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/mu', contents=''.join(mu_contents))
+  expected_disk.tweak('iota', contents=''.join(iota_contents))
+  expected_disk.remove('A/B/E/beta')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', wc_rev=2)
+  expected_status.tweak('iota', status='M ')
+  expected_status.tweak('A/B/E/beta', status='D ')
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1, # dry-run
+                                       "--include-pattern", "A/mu",
+                                       "--include-pattern", "*a",
+                                       "--exclude-pattern", "A/*/gamma")
 
 ########################################################################
 #Run the tests
 
 # list all tests here, starting with None:
 test_list = [ None,
-              patch_unidiff,
-              patch_unidiff_absolute_paths,
-              patch_unidiff_offset,
+              patch,
+              patch_absolute_paths,
+              patch_offset,
               patch_chopped_leading_spaces,
-              patch_unidiff_strip1,
+              patch_strip1,
+              patch_add_new_dir,
+              patch_reject,
+              patch_keywords,
+              patch_with_fuzz,
+              patch_reverse,
+              patch_no_svn_eol_style,
+              patch_with_svn_eol_style,
+              patch_with_svn_eol_style_uncommitted,
+              patch_with_include_patterns,
+              patch_with_exclude_patterns,
+              patch_with_include_exclude_patterns,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/prop_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/prop_tests.py Tue Aug 10 18:06:17 2010
@@ -3,7 +3,7 @@
 #  prop_tests.py:  testing versioned properties
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -1734,6 +1734,51 @@ def post_revprop_change_hook(sbox):
                                      'ps', '--revprop', '-r0', 'p', 'v',
                                      wc_dir)
 
+def rm_of_replaced_file(sbox):
+  """properties after a removal of a replaced file"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Add some properties to iota and mu
+  iota_path = os.path.join(wc_dir, 'iota')
+  svntest.main.run_svn(None, 'propset', 'red', 'rojo', iota_path)
+  svntest.main.run_svn(None, 'propset', 'blue', 'lagoon', iota_path)
+
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  svntest.main.run_svn(None, 'propset', 'yellow', 'submarine', mu_path)
+  svntest.main.run_svn(None, 'propset', 'orange', 'toothpick', mu_path)
+
+  svntest.main.run_svn(None, 'ci', '-m', 'log message', wc_dir)
+
+  # Copy iota over the top of mu
+  svntest.main.run_svn(None, 'rm', mu_path)
+  svntest.main.run_svn(None, 'cp', iota_path, mu_path)
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', props={'red': 'rojo', 'blue': 'lagoon'})
+  expected_disk.tweak('A/mu', props={'red': 'rojo', 'blue': 'lagoon'},
+                      contents="This is the file 'iota'.\n")
+  actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
+  svntest.tree.compare_trees("disk", actual_disk_tree,
+                             expected_disk.old_tree())
+
+  # Remove the copy. Properties should go back to mu's original props.
+  svntest.main.run_svn(None, 'rm', '--force', mu_path)
+
+  exit_code, output, errput = svntest.main.run_svn(None,
+                                                   'proplist', '-v', mu_path)
+  expected_output = svntest.verify.UnorderedRegexOutput([
+      'Properties on',
+      '  yellow',
+      '    submarine',
+      '  orange',
+      '    toothpick',
+      ])
+  svntest.verify.compare_and_display_lines('message', 'label',
+                                           expected_output, output)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
+
 
 ########################################################################
 # Run the tests
@@ -1775,6 +1820,7 @@ test_list = [ None,
               added_moved_file,
               delete_nonexistent_property,
               XFail(post_revprop_change_hook, svntest.main.is_ra_type_dav),
+              rm_of_replaced_file,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolve_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolve_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolve_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolve_tests.py Tue Aug 10 18:06:17 2010
@@ -3,7 +3,7 @@
 #  resolve_tests.py:  testing 'svn resolve'
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -64,14 +64,17 @@ def automatic_conflict_resolution(sbox):
   def do_text_conflicting_merge():
     svntest.actions.run_and_verify_svn(None, None, [],
                                        'revert', '--recursive', A_COPY_path)
-    svntest.actions.run_and_verify_svn(None,
-                                       "(--- Merging r3 into .*A_COPY':\n)|"
-                                       "(C    .*psi\n)|"
-                                       "(Summary of conflicts:\n)|"
-                                       "(  Text conflicts: 1\n)",
-                                       [], 'merge', '-c3',
-                                       sbox.repo_url + '/A',
-                                       A_COPY_path)
+    svntest.actions.run_and_verify_svn(
+      None,
+      "(--- Merging r3 into .*A_COPY':\n)|"
+      "(C    .*psi\n)|"
+      "(--- Recording mergeinfo for merge of r3 into .*A_COPY':\n)|"
+      "( U   .*A_COPY\n)|"
+      "(Summary of conflicts:\n)|"
+      "(  Text conflicts: 1\n)",
+      [], 'merge', '-c3',
+      sbox.repo_url + '/A',
+      A_COPY_path)
 
   # Test 'svn resolve -R --accept base'
   do_text_conflicting_merge()

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolved_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolved_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolved_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/resolved_tests.py Tue Aug 10 18:06:17 2010
@@ -3,7 +3,7 @@
 #  resolved_tests.py:  testing "resolved" cases.
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -274,7 +274,11 @@ def resolved_on_deleted_item(sbox):
       'B'                 : Item(status='  ', treeconflict='C'),
       'D/gamma'           : Item(status='  ', treeconflict='C'),
     })
-
+  expected_mergeinfo_output = svntest.wc.State(A2, {
+      '' : Item(status=' U')
+    })
+  expected_elision_output = svntest.wc.State(A2, {
+    })
   expected_disk = svntest.wc.State('', {
       'mu'                : Item(contents="This is the file 'mu'.\n"),
       'D'                 : Item(),
@@ -310,11 +314,12 @@ def resolved_on_deleted_item(sbox):
     'C'                 : Item(status='  ', wc_rev='2'),
   })
 
-  svntest.actions.run_and_verify_merge(
-                       A2, None, None, A_url,
-                       expected_output, expected_disk, None, expected_skip,
-                       None,
-                       dry_run = False)
+  svntest.actions.run_and_verify_merge(A2, None, None, A_url, None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk, None, expected_skip,
+                                       None, dry_run = False)
   svntest.actions.run_and_verify_unquiet_status(A2, expected_status)
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/revert_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/revert_tests.py Tue Aug 10 18:06:17 2010
@@ -3,7 +3,7 @@
 #  revert_tests.py:  testing 'svn revert'.
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one
@@ -29,7 +29,8 @@ import re, os
 
 # Our testing module
 import svntest
-from svntest import wc
+from svntest import wc, main, actions
+from svntest.actions import run_and_verify_svn
 
 
 # (abbreviation)
@@ -434,12 +435,20 @@ def revert_file_merge_replace_with_histo
   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 = svntest.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)
@@ -672,14 +681,22 @@ def revert_replaced_with_history_file_1(
     'A/mu': Item(status='R '),
     'iota': Item(status='A ')
     })
+  expected_mergeinfo_output = svntest.wc.State(wc_dir, {
+    '': Item(status=' U'),
+    })
+  expected_elision_output = svntest.wc.State(wc_dir, {
+    '': Item(status=' U'),
+    })
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   expected_status.tweak('A/mu', status='R ', copied='+', wc_rev='-')
   expected_status.tweak('iota', status='A ', copied='+', wc_rev='-')
   expected_skip = wc.State(wc_dir, { })
   expected_disk = svntest.main.greek_state.copy()
   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)
@@ -785,6 +802,12 @@ def status_of_missing_dir_after_revert_r
     'A/D/G/pi': Item(status='A '),
     'A/D/G/tau': Item(status='A '),
     })
+  expected_mergeinfo_output = svntest.wc.State(wc_dir, {
+    '': Item(status=' U'),
+    })
+  expected_elision_output = svntest.wc.State(wc_dir, {
+    '': Item(status=' U'),
+    })
   expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
   expected_status.tweak('A/D/G', status='R ', copied='+', wc_rev='-')
   expected_status.tweak('A/D/G/rho',
@@ -799,8 +822,10 @@ def status_of_missing_dir_after_revert_r
   expected_skip = wc.State(wc_dir, { })
   expected_disk   = svntest.main.greek_state.copy()
   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,
@@ -928,6 +953,26 @@ def revert_tree_conflicts_in_updated_fil
   svntest.actions.run_and_verify_status(wc_dir_2, expected_status)
   svntest.actions.verify_disk(wc_dir_2, expected_disk)
 
+def revert_add_over_not_present_dir(sbox):
+  "reverting an add over not present directory"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  main.run_svn(None, 'rm', os.path.join(wc_dir, 'A/C'))
+  main.run_svn(None, 'ci', wc_dir, '-m', 'Deleted dir')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.remove('A/C')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  
+  main.run_svn(None, 'mkdir', os.path.join(wc_dir, 'A/C'))
+  
+  # This fails in the current WC-NG state (r927318).
+  main.run_svn(None, 'revert', os.path.join(wc_dir, 'A/C'))
+  
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
 
 ########################################################################
 # Run the tests
@@ -955,6 +1000,7 @@ test_list = [ None,
                    status_of_missing_dir_after_revert_replaced_with_history_dir),
               revert_replaced_with_history_file_2,
               revert_tree_conflicts_in_updated_files,
+              XFail(revert_add_over_not_present_dir),
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/schedule_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/schedule_tests.py?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/schedule_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/schedule_tests.py Tue Aug 10 18:06:17 2010
@@ -4,7 +4,7 @@
 #                      (adds, deletes, reversion)
 #
 #  Subversion is a tool for revision control.
-#  See http://subversion.tigris.org for more information.
+#  See http://subversion.apache.org for more information.
 #
 # ====================================================================
 #    Licensed to the Apache Software Foundation (ASF) under one