subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r931162 - in /subversion/trunk: ./ subversion/libsvn_diff/parse-diff.c subversion/tests/cmdline/patch_tests.py
Date Tue, 06 Apr 2010 14:20:21 GMT
Author: stsp
Date: Tue Apr  6 14:20:21 2010
New Revision: 931162

URL: http://svn.apache.org/viewvc?rev=931162&view=rev
Log:
Cherry-pick r929288 and r931140 from the svn-patch-improvements branch
to trunk, fixing the problem reported in:

  Date: Wed, 3 Mar 2010 15:52:59 +0100
  From: Stefan Sperling
  To: dev@subversion.apache.org
  Subject: svn patch fails on this diff
  Message-ID: <20100303145259.GF8176@noel.stsp.name>
  http://svn.haxx.se/dev/archive-2010-03/0097.shtml
  http://svn.haxx.se/dev/archive-2010-03/0098.shtml (attachment)

Log messages of those revisions were:

------------------------------------------------------------------------
r929288 | dannas | 2010-03-30 23:11:15 +0200 (Tue, 30 Mar 2010) | 16 lines

Fix bug with 'svn patch' not recognizing diff headers when parsing
patches without the 'Index' line and the '======' line. The old code
just assumed that the first line after the hunk would not be a '-'. But
it can be so we must handle it.

* subversion/libsvn_diff/parse-diff.c
  (parse_next_hunk): Check that we have not read all the lines, that the
    hunk header said, the hunk should consist of. We need to check for
    both nr of modified and original lines since we can do a reverse
    parsing. That means treating '+' as '-' and the other way around.

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


------------------------------------------------------------------------
r931140 | stsp | 2010-04-06 15:08:19 +0200 (Tue, 06 Apr 2010) | 4 lines

On the svn-patch-improvements branch:
* subversion/libsvn_diff/parse-diff.c
  (parse_next_hunk): Make sure we never overflow modified_lines.

------------------------------------------------------------------------

Modified:
    subversion/trunk/   (props changed)
    subversion/trunk/subversion/libsvn_diff/parse-diff.c
    subversion/trunk/subversion/tests/cmdline/patch_tests.py

Propchange: subversion/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr  6 14:20:21 2010
@@ -24,6 +24,7 @@
 /subversion/branches/reintegrate-improvements:873853-874164
 /subversion/branches/subtree-mergeinfo:876734-878766
 /subversion/branches/svn-mergeinfo-enhancements:870119-870195,870197-870288
+/subversion/branches/svn-patch-improvements:929288,931140
 /subversion/branches/svnpatch-diff:865738-876477
 /subversion/branches/svnraisetc:874709-875149
 /subversion/branches/svnserve-logging:869828-870893

Modified: subversion/trunk/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/parse-diff.c?rev=931162&r1=931161&r2=931162&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/trunk/subversion/libsvn_diff/parse-diff.c Tue Apr  6 14:20:21 2010
@@ -281,6 +281,7 @@ parse_next_hunk(svn_hunk_t **hunk,
   svn_stream_t *original_text;
   svn_stream_t *modified_text;
   svn_linenum_t original_lines;
+  svn_linenum_t modified_lines;
   svn_linenum_t leading_context;
   svn_linenum_t trailing_context;
   svn_boolean_t changed_line_seen;
@@ -354,16 +355,18 @@ parse_next_hunk(svn_hunk_t **hunk,
 
           c = line->data[0];
           /* Tolerate chopped leading spaces on empty lines. */
-          if (original_lines > 0 && (c == ' ' || (! eof && line->len
== 0)))
+          if (original_lines > 0 && modified_lines > 0 &&
+              (c == ' ' || (! eof && line->len == 0)))
             {
               hunk_seen = TRUE;
               original_lines--;
+              modified_lines--;
               if (changed_line_seen)
                 trailing_context++;
               else
                 leading_context++;
             }
-          else if (c == add || c == del)
+          else if (original_lines > 0 && c == del)
             {
               hunk_seen = TRUE;
               changed_line_seen = TRUE;
@@ -373,8 +376,19 @@ parse_next_hunk(svn_hunk_t **hunk,
               if (trailing_context > 0)
                 trailing_context = 0;
 
-              if (original_lines > 0 && c == del)
-                original_lines--;
+              original_lines--;
+            }
+          else if (modified_lines > 0 && c == add)
+            {
+              hunk_seen = TRUE;
+              changed_line_seen = TRUE;
+
+              /* A hunk may have context in the middle. We only want the
+                 last lines of context. */
+              if (trailing_context > 0)
+                trailing_context = 0;
+
+              modified_lines--;
             }
           else
             {
@@ -395,7 +409,10 @@ parse_next_hunk(svn_hunk_t **hunk,
               in_hunk = parse_hunk_header(line->data, *hunk, reverse,
                                           iterpool);
               if (in_hunk)
-                original_lines = (*hunk)->original_length;
+                {
+                  original_lines = (*hunk)->original_length;
+                  modified_lines = (*hunk)->modified_length;
+                }
             }
           else if (starts_with(line->data, minus))
             /* This could be a header of another patch. Bail out. */

Modified: subversion/trunk/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/patch_tests.py?rev=931162&r1=931161&r2=931162&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/patch_tests.py Tue Apr  6 14:20:21 2010
@@ -841,6 +841,92 @@ def patch_strip1(sbox):
                                        1, # dry-run
                                        '-p1')
 
+def patch_no_index_line(sbox):
+  "patch with no index lines"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1]
+  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  iota_path = os.path.join(wc_dir, 'iota')
+
+  gamma_contents = [
+    "\n",
+    "Another line before\n",
+    "A third line before\n",
+    "This is the file 'gamma'.\n",
+    "A line after\n",
+    "Another line after\n",
+    "A third line after\n",
+  ]
+
+  svntest.main.file_write(gamma_path, ''.join(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)
+  unidiff_patch = [
+    "--- A/D/gamma\t(revision 1)\n",
+    "+++ A/D/gamma\t(working copy)\n",
+    "@@ -1,7 +1,7 @@\n",
+    " \n",
+    " Another line before\n",
+    " A third line before\n",
+    "-This is the file 'gamma'.\n",
+    "+It is the file 'gamma'.\n",
+    " A line after\n",
+    " Another line after\n",
+    " A third line after\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",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  gamma_contents = [
+    "\n",
+    "Another line before\n",
+    "A third line before\n",
+    "It is the file 'gamma'.\n",
+    "A line after\n",
+    "Another line after\n",
+    "A third line after\n",
+  ]
+  iota_contents = [
+    "This is the file 'iota'.\n",
+    "Some more bytes\n",
+  ]
+  expected_output = [
+    'U         %s\n' % os.path.join(wc_dir, 'A', 'D', 'gamma'),
+    'U         %s\n' % os.path.join(wc_dir, 'iota'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/D/gamma', contents=''.join(gamma_contents))
+  expected_disk.tweak('iota', contents=''.join(iota_contents))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/D/gamma', status='M ', wc_rev=2)
+  expected_status.tweak('iota', 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
+
 def patch_add_new_dir(sbox):
   "patch with missing dirs"
 
@@ -2187,6 +2273,7 @@ test_list = [ None,
               patch_offset,
               patch_chopped_leading_spaces,
               patch_strip1,
+              patch_no_index_line,
               patch_add_new_dir,
               patch_reject,
               patch_keywords,



Mime
View raw message