emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

diff-sanity-check-hunk fails on "unterminated" hunks


From: Bob Rogers
Subject: diff-sanity-check-hunk fails on "unterminated" hunks
Date: Tue, 11 Sep 2007 21:57:54 -0400

   To reproduce the problem (in Emacs 22 or trunk):

   1.  Put the first attachment (unterminated-hunk-test.patch) in the
top directory of your Emacs working copy.

   2.  Do "emacs -Q unterminated-hunk-test.patch" to bring it up in
diff-mode.

   3.  Move point into the first hunk and type C-c C-c; it should move
to that hunk in the source, but instead it gives the error "Hunk
seriously messed up".  Doing the same thing in the second hunk should
find the source (with the message "Hunk already applied").

   Note that this patch was produced in a slightly unusual way.  Instead
of doing 

        address@hidden> diff -ur lisp/url.old lisp/url

to get all differing files at once (as any reasonable person would), I
produced the diffs separately and concatenated them:

        address@hidden> diff -u lisp/url.old/url-dav.el lisp/url/url-dav.el > 
unterminated-hunk-test.patch
        address@hidden> diff -u lisp/url.old/url-ftp.el lisp/url/url-ftp.el >> 
unterminated-hunk-test.patch

For this reason, the usual "diff -ur file1 file2" line that precedes
each file in a normal multifile diff is missing.  The start of the
second file therefore comes right after the last hunk of the first file,
and because it's a unidiff, it looks like this:

        --- lisp/url.old/url-ftp.el     2007-09-11 20:42:21.000000000 -0400
        +++ lisp/url/url-ftp.el 2007-08-13 19:47:02.000000000 -0400
        @@ -24,12 +24,12 @@

So diff-sanity-check-hunk sees one more "-" line and one more "+" line
than it should, and barfs when it comes to the "@@" for the first hunk
of the second file.

   The second attachment
(fix-diff-sanity-check-hunk-for-unterminated-hunk.patch) fixes the
problem by doing the normal exit test (exit when both line counters get
to zero) before checking the BOL character.  (It's actually just a small
change but with a lot of whitespace adjustment.)

   One could argue that this is an artificial problem caused by an
eccentric application of "diff".  However, I would argue that unidiff
hunks *are* unterminated, except by counting lines as the original code
does, so the revision strikes me as cleaner and more robust.  Also, the
concatenation of two syntactically valid patch files should also be
considered a syntactically valid patch file (modulo issues with relative
file names), so Emacs ought to deal with such files gracefully.
Finally, the issue came up naturally enough for me, so it may not be all
that rare; I ran vc-diff repeatedly on a list of changed file names,
concatenating the output into a diff-mode buffer.

   WDOT?

                                        -- Bob Rogers
                                           http://rgrjr.dyndns.org/

--- lisp/url.old/url-dav.el     2007-09-11 20:42:46.000000000 -0400
+++ lisp/url/url-dav.el 2007-08-13 19:47:02.000000000 -0400
@@ -23,7 +23,7 @@
 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 ;; Boston, MA 02110-1301, USA.
 
-    ;; DAV is in RFC 2518.
+;; DAV is in RFC 2518.
 
 ;;; Commentary:
 
--- lisp/url.old/url-ftp.el     2007-09-11 20:42:21.000000000 -0400
+++ lisp/url/url-ftp.el 2007-08-13 19:47:02.000000000 -0400
@@ -24,12 +24,12 @@
 
 ;;; Commentary:
 
-    ;; We knew not what we did when we overloaded 'file' to mean 'file'
-    ;; and 'ftp' back in the dark ages of the web.
-    ;;
-    ;; This stub file is just here to please the auto-scheme-loading code
-    ;; in url-methods.el and just maps everything onto the code in
-    ;; url-file.
+;; We knew not what we did when we overloaded 'file' to mean 'file'
+;; and 'ftp' back in the dark ages of the web.
+;;
+;; This stub file is just here to please the auto-scheme-loading code
+;; in url-methods.el and just maps everything onto the code in
+;; url-file.
 
 ;;; Code:
 
Index: lisp/diff-mode.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/diff-mode.el,v
retrieving revision 1.113
diff -c -r1.113 diff-mode.el
*** lisp/diff-mode.el   11 Sep 2007 06:59:13 -0000      1.113
--- lisp/diff-mode.el   12 Sep 2007 01:32:24 -0000
***************
*** 1243,1264 ****
                  (after (if (match-string 2) (string-to-number (match-string 
2)) 1)))
              (forward-line)
              (while
!                 (case (char-after)
!                   (?\s (decf before) (decf after) t)
!                   (?- (decf before) t)
!                   (?+ (decf after) t)
!                   (t
!                    (cond
!                     ((and (zerop before) (zerop after)) nil)
!                     ((or (< before 0) (< after 0))
!                      (error (if (or (zerop before) (zerop after))
!                                 "End of hunk ambiguously marked"
!                               "Hunk seriously messed up")))
!                     ((not (y-or-n-p "Try to auto-fix whitespace loss and 
word-wrap damage? "))
!                      (error "Abort!"))
!                     ((eolp) (insert " ") (forward-line -1) t)
!                     (t (insert " ")
!                        (delete-region (- (point) 2) (- (point) 1)) t))))
                (forward-line)))))
  
         ;; A plain diff.
--- 1243,1262 ----
                  (after (if (match-string 2) (string-to-number (match-string 
2)) 1)))
              (forward-line)
              (while
!               (cond ((and (zerop before) (zerop after)) nil)
!                     ((case (char-after)
!                        (?\s (decf before) (decf after) t)
!                        (?- (decf before) t)
!                        (?+ (decf after) t)))
!                     ((or (< before 0) (< after 0))
!                      (error (if (or (zerop before) (zerop after))
!                                 "End of hunk ambiguously marked"
!                                 "Hunk seriously messed up")))
!                     ((not (y-or-n-p "Try to auto-fix whitespace loss and 
word-wrap damage? "))
!                      (error "Abort!"))
!                     ((eolp) (insert " ") (forward-line -1) t)
!                     (t (insert " ")
!                        (delete-region (- (point) 2) (- (point) 1)) t))
                (forward-line)))))
  
         ;; A plain diff.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]