You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/05/26 21:31:22 UTC

svn commit: r948550 - in /subversion/trunk/subversion: libsvn_client/patch.c tests/cmdline/patch_tests.py

Author: dannas
Date: Wed May 26 19:31:22 2010
New Revision: 948550

URL: http://svn.apache.org/viewvc?rev=948550&view=rev
Log:
Fix #3643 - 'svn_client_patch() problem with "no newline at eof"'.

When seeking past the target's version of the hunk, we assumed that
there would always be newline at the end of each hunk. For a file
with no eol at the end that would not be the case.

* subversion/libsvn_client/patch.c
  (apply_hunk): Check to see if we've reached eof in the target 
    before declaring the hunk rejected.

* subversion/tests/cmdline/patch_tests.py
  (patch_no_eol_at_eof): New regression test.
  (test_list): Add the test.

Modified:
    subversion/trunk/subversion/libsvn_client/patch.c
    subversion/trunk/subversion/tests/cmdline/patch_tests.py

Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=948550&r1=948549&r2=948550&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Wed May 26 19:31:22 2010
@@ -947,7 +947,7 @@ apply_hunk(patch_target_t *target, hunk_
        * Don't skip trailing lines which matched with fuzz. */
       line = target->current_line + hi->hunk->original_length - (2 * hi->fuzz);
       SVN_ERR(seek_to_line(target, line, pool));
-      if (target->current_line != line)
+      if (target->current_line != line && ! target->eof)
         {
           /* Seek failed, reject this hunk. */
           hi->rejected = TRUE;

Modified: subversion/trunk/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/patch_tests.py?rev=948550&r1=948549&r2=948550&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/patch_tests.py Wed May 26 19:31:22 2010
@@ -2088,7 +2088,79 @@ def patch_replace_locally_deleted_file(s
                                        None, # expected err
                                        1, # check-props
                                        1) # dry-run
-
+# Regression test for #3643
+def patch_no_eol_at_eof(sbox):
+  "patch with no eol at eof"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = make_patch_path(sbox)
+  iota_path = os.path.join(wc_dir, 'iota')
+
+  iota_contents = [
+    "One line\n",
+    "Another line\n",
+    "A third line \n",
+    "This is the file 'iota'.\n",
+    "A line after\n",
+    "Another line after\n",
+    "The last line with missing eol",
+  ]
+
+  svntest.main.file_write(iota_path, ''.join(iota_contents))
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota'  : Item(verb='Sending'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', wc_rev=2)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+  unidiff_patch = [
+    "--- iota\t(revision 1)\n",
+    "+++ iota\t(working copy)\n",
+    "@@ -1,7 +1,7 @@\n",
+    " One line\n",
+    " Another line\n",
+    " A third line \n",
+    "-This is the file 'iota'.\n",
+    "+It is the file 'iota'.\n",
+    " A line after\n",
+    " Another line after\n",
+    " The last line with missing eol\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  iota_contents = [
+    "One line\n",
+    "Another line\n",
+    "A third line \n",
+    "It is the file 'iota'.\n",
+    "A line after\n",
+    "Another line after\n",
+    "The last line with missing eol\n",
+  ]
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', contents=''.join(iota_contents))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', 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
 
 ########################################################################
 #Run the tests
@@ -2112,6 +2184,7 @@ test_list = [ None,
               patch_with_svn_eol_style_uncommitted,
               patch_with_ignore_whitespace,
               patch_replace_locally_deleted_file,
+              patch_no_eol_at_eof,
             ]
 
 if __name__ == '__main__':