git-gui: rework handling of diff header
authorBert Wesarg <bert.wesarg@googlemail.com>
Thu, 9 Dec 2010 20:47:52 +0000 (21:47 +0100)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Fri, 28 Jan 2011 09:01:17 +0000 (09:01 +0000)
The fix in ca53c3f (Fix diff parsing for lines starting with "--" or "++",
2008-09-05) got a bug report from Johannes Sixt, that new files in the
index now looks like:

new file mode 100644
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo

The introduced problem was that the 'in-diff-header'-flag was unconditially
disabled. Now it is only disabled when a hunk line is detected. And also
re-enabled when we encounter a new diff header.

The second part solves also the issue reported by me for diffs with file
type changes (i.e. the ''error: Unhandled 2 way diff marker: {d}"', which
comes from the second 'diff --git' line).

Reported-by: Johannes Sixt <j.sixt@viscovery.net>
Reported-by: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
lib/diff.tcl
index 9d0dc07d7bb5e73d9de778604d9e2dc1df6f4f3e..dae6ca6831a3ed13e7cc97cdce661ed0f1ce5386 100644 (file)
@@ -382,23 +382,35 @@ proc read_diff {fd conflict_size cont_info} {
                foreach {line markup} [parse_color_line $line] break
                set line [string map {\033 ^} $line]
 
                foreach {line markup} [parse_color_line $line] break
                set line [string map {\033 ^} $line]
 
-               # -- Cleanup uninteresting diff header lines.
+               # -- Check for start of diff header.
+               if {   [string match {diff --git *}      $line]
+                   || [string match {diff --cc *}       $line]
+                   || [string match {diff --combined *} $line]} {
+                       set ::current_diff_inheader 1
+               }
+
+               # -- Check for end of diff header (any hunk line will do this).
                #
                #
+               if {[regexp {^@@+ } $line]} {set ::current_diff_inheader 0}
+
                if {$::current_diff_inheader} {
                if {$::current_diff_inheader} {
+                       append current_diff_header $line "\n"
+
+                       # -- 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]} {
                        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
                        }
                }
                                continue
                        }
                }
+
                if {[string match {index *} $line]} continue
                if {$line eq {deleted file mode 120000}} {
                        set line "deleted symlink"
                }
                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.
                #
 
                # -- Automatically detect if this is a 3 way diff.
                #