Author: rhuijben
Date: Mon Jan 21 19:57:38 2013
New Revision: 1436580

URL: http://svn.apache.org/viewvc?rev=1436580&view=rev
Log:
* subversion/libsvn_client/patch.c
  (readline): Add assertion.
  (get_hunk_info): Allow matching the empty file with a hunk referring to an
    empty (or not existing) file.

* subversion/tests/cmdline/patch_tests.py
  (patch_empty_file): Extend test to also cover some related cases: no file
    and a single newline file. Update current status.

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=1436580&r1=1436579&r2=1436580&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Mon Jan 21 19:57:38 2013
@@ -1205,6 +1205,8 @@ readline(target_content_t *content,
   if ((line_raw && line_raw->len > 0) || eol_str)
     content->current_line++;
 
+  SVN_ERR_ASSERT(content->current_line > 0);
+
   return SVN_NO_ERROR;
 }
 
@@ -1536,26 +1538,45 @@ get_hunk_info(hunk_info_t **hi, patch_ta
    * the hunk applies at line 1. If the file already exists, the hunk
    * is rejected, unless the file is versioned and its content matches
    * the file the patch wants to create.  */
-  if (original_start == 0 && ! is_prop_hunk)
+  if (original_start == 0 && fuzz > 0)
+    {
+      matched_line = 0; /* reject any fuzz for new files */
+    }
+  else if (original_start == 0 && ! is_prop_hunk)
     {
       if (target->kind_on_disk == svn_node_file)
         {
-          if (target->db_kind == svn_node_file)
+          svn_io_dirent2_t *dirent;
+          SVN_ERR(svn_io_stat_dirent2(&dirent, target->local_abspath, FALSE,
+                                      TRUE, scratch_pool, scratch_pool));
+
+          if (dirent->kind == svn_node_file
+              && !dirent->special
+              && dirent->filesize == 0)
+            {
+              matched_line = 1; /* Matched an on-disk empty file */
+            }
+          else
             {
-              svn_boolean_t file_matches;
+              if (target->db_kind == svn_node_file)
+                {
+                  svn_boolean_t file_matches;
 
-              SVN_ERR(match_existing_target(&file_matches, content, hunk,
+                  /* ### I can't reproduce anything but a no-match here.
+                         The content is already at eof, so any hunk fails */
+                  SVN_ERR(match_existing_target(&file_matches, content, hunk,
                                             scratch_pool));
-              if (file_matches)
-                {
-                  matched_line = 1;
-                  already_applied = TRUE;
+                  if (file_matches)
+                    {
+                      matched_line = 1;
+                      already_applied = TRUE;
+                    }
+                  else
+                    matched_line = 0; /* reject */
                 }
               else
                 matched_line = 0; /* reject */
             }
-          else
-            matched_line = 0; /* reject */
         }
       else
         matched_line = 1;

Modified: subversion/trunk/subversion/tests/cmdline/patch_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/patch_tests.py?rev=1436580&r1=1436579&r2=1436580&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/patch_tests.py Mon Jan 21 
19:57:38 2013
@@ -4405,25 +4405,43 @@ def patch_empty_file(sbox):
 
   patch_file_path = make_patch_path(sbox)
   svntest.main.file_write(patch_file_path, ''.join([
-    "Index: file1.txt\n",
+  # patch a file containing just '\n' to 'replacement\n'
+    "Index: lf.txt\n",
     "===================================================================\n",
-    "--- file1.txt\t(revision 20)\n",
-    "+++ file1.txt\t(working copy)\n",
+    "--- lf.txt\t(revision 2)\n",
+    "+++ lf.txt\t(working copy)\n",
+    "@@ -1 +1 @@\n",
+    "\n"
+    "+replacement\n",
+
+  # patch a new file 'new.txt\n'
+    "Index: new.txt\n",
+    "===================================================================\n",
+    "--- new.txt\t(revision 0)\n",
+    "+++ new.txt\t(working copy)\n",
+    "@@ -0,0 +1 @@\n",
+    "+new file\n",
+
+  # patch a file containing 0 bytes to 'replacement\n'
+    "Index: empty.txt\n",
+    "===================================================================\n",
+    "--- empty.txt\t(revision 2)\n",
+    "+++ empty.txt\t(working copy)\n",
     "@@ -0,0 +1 @@\n",
-    "+vhjhgf\n",
-    "\\ No newline at end of file\n",
+    "+replacement\n",
   ]))
 
-  # Add a 0-byte file 'file1.txt'
-  sbox.simple_add_text('', 'file1.txt')
+  sbox.simple_add_text('', 'empty.txt')
+  sbox.simple_add_text('\n', 'lf.txt')
   sbox.simple_commit()
 
-  # And now this patch should fail, as 'line' doesn't equal 'foo'
-  # But yet it shows up as deleted instead of conflicted
   expected_output = [
-    'U         %s\n' % sbox.ospath('file1.txt'),
+    'U         %s\n' % sbox.ospath('lf.txt'),
+    'A         %s\n' % sbox.ospath('new.txt'),
+    'U         %s\n' % sbox.ospath('empty.txt'),
   ]
 
+  # Current result: lf.txt patched ok, new created, empty succeeds with offset.
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'patch', patch_file_path, wc_dir)
 


Reply via email to