Code

git-gui: Fix diff parsing for lines starting with "--" or "++"
authorShawn O. Pearce <spearce@spearce.org>
Fri, 5 Sep 2008 04:46:56 +0000 (21:46 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Fri, 5 Sep 2008 04:52:56 +0000 (21:52 -0700)
Languages like Lua and SQL use "--" to mark a line as commented out.
If this appears at column 0 and is part of the pre-image we may see
"--- foo" in the diff, indicating that the line whose content is
 "-- foo" has been removed from the new version.

git-gui was incorrectly parsing "--- foo" as the old file name
in the file header, causing it to generate a bad patch file when
the user tried to stage or unstage a hunk or the selected line.
We need to keep track of where we are in the parsing so that we do
not misread a deletion or addition record as part of the header.

Reported-by: Alexander Gladysh <agladysh@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
lib/diff.tcl

index 4a7138be9c0a860d7b4a9820a6d796fa3cabc700..1970b601e1ce34af120cfc3ee16e1b2c26c6b19d 100644 (file)
@@ -192,6 +192,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
                return
        }
 
+       set ::current_diff_inheader 1
        fconfigure $fd \
                -blocking 0 \
                -encoding binary \
@@ -207,18 +208,21 @@ proc read_diff {fd scroll_pos} {
        while {[gets $fd line] >= 0} {
                # -- Cleanup uninteresting diff header lines.
                #
-               if {   [string match {diff --git *}      $line]
-                       || [string match {diff --cc *}       $line]
-                       || [string match {diff --combined *} $line]
-                       || [string match {--- *}             $line]
-                       || [string match {+++ *}             $line]} {
-                       append current_diff_header $line "\n"
-                       continue
+               if {$::current_diff_inheader} {
+                       if {   [string match {diff --git *}      $line]
+                           || [string match {diff --cc *}       $line]
+                           || [string match {diff --combined *} $line]
+                           || [string match {--- *}             $line]
+                           || [string match {+++ *}             $line]} {
+                               append current_diff_header $line "\n"
+                               continue
+                       }
                }
                if {[string match {index *} $line]} continue
                if {$line eq {deleted file mode 120000}} {
                        set line "deleted symlink"
                }
+               set ::current_diff_inheader 0
 
                # -- Automatically detect if this is a 3 way diff.
                #