Improve the merge display when the result differs from all parents.
authorPaul Mackerras <paulus@samba.org>
Fri, 29 Jul 2005 14:23:03 +0000 (09:23 -0500)
committerPaul Mackerras <paulus@samba.org>
Fri, 29 Jul 2005 14:23:03 +0000 (09:23 -0500)
Now we see if the result is quite similar to one of the parents, and
if it is, display the result as a diff from that parent.  If the result
is similar to more than one parent, pick the one that it's most
similar to.

gitk

diff --git a/gitk b/gitk
index dd8f1f1..2aa970d 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -2054,7 +2054,6 @@ proc processgroup {} {
     set pnum 0
     foreach p $parents($id) {
        set startline [expr {$grouplinestart + $diffoffset($p)}]
-       set offset($p) $diffoffset($p)
        set ol $startline
        set nl $grouplinestart
        if {[info exists grouphunks($p)]} {
@@ -2098,9 +2097,8 @@ proc processgroup {} {
     set events [lsort -integer -index 0 $events]
     set nevents [llength $events]
     set nmerge $nparents($diffmergeid)
-    set i 0
     set l $grouplinestart
-    while {$i < $nevents} {
+    for {set i 0} {$i < $nevents} {set i $j} {
        set nl [lindex $events $i 0]
        while {$l < $nl} {
            $ctext insert end " $filelines($id,$f,$l)\n"
@@ -2129,7 +2127,9 @@ proc processgroup {} {
        }
        set nlc [expr {$enl - $l}]
        set ncol mresult
+       set bestpn -1
        if {[llength $active] == $nmerge - 1} {
+           # no diff for one of the parents, i.e. it's identical
            for {set pnum 0} {$pnum < $nmerge} {incr pnum} {
                if {![info exists delta($pnum)]} {
                    if {$pnum < $mergemax} {
@@ -2140,11 +2140,25 @@ proc processgroup {} {
                    break
                }
            }
+       } elseif {[llength $active] == $nmerge} {
+           # all parents are different, see if one is very similar
+           set bestsim 30
+           for {set pnum 0} {$pnum < $nmerge} {incr pnum} {
+               set sim [similarity $pnum $l $nlc $f \
+                            [lrange $events $i [expr {$j-1}]]]
+               if {$sim > $bestsim} {
+                   set bestsim $sim
+                   set bestpn $pnum
+               }
+           }
+           if {$bestpn >= 0} {
+               lappend ncol m$bestpn
+           }
        }
        set pnum -1
        foreach p $parents($id) {
            incr pnum
-           if {![info exists delta($pnum)]} continue
+           if {![info exists delta($pnum)] || $pnum == $bestpn} continue
            set olc [expr {$nlc + $delta($pnum)}]
            set ol [expr {$l + $diffoffset($p)}]
            incr diffoffset($p) $delta($pnum)
@@ -2154,11 +2168,35 @@ proc processgroup {} {
                incr ol
            }
        }
-       for {} {$nlc > 0} {incr nlc -1} {
+       set endl [expr {$l + $nlc}]
+       if {$bestpn >= 0} {
+           # show this pretty much as a normal diff
+           set p [lindex $parents($id) $bestpn]
+           set ol [expr {$l + $diffoffset($p)}]
+           incr diffoffset($p) $delta($bestpn)
+           unset delta($bestpn)
+           for {set k $i} {$k < $j} {incr k} {
+               set e [lindex $events $k]
+               if {[lindex $e 2] != $bestpn} continue
+               set nl [lindex $e 0]
+               set ol [expr {$ol + $nl - $l}]
+               for {} {$l < $nl} {incr l} {
+                   $ctext insert end "+$filelines($id,$f,$l)\n" $ncol
+               }
+               set c [lindex $e 3]
+               for {} {$c > 0} {incr c -1} {
+                   $ctext insert end "-$filelines($p,$f,$ol)\n" m$bestpn
+                   incr ol
+               }
+               set nl [lindex $e 1]
+               for {} {$l < $nl} {incr l} {
+                   $ctext insert end "+$filelines($id,$f,$l)\n" mresult
+               }
+           }
+       }
+       for {} {$l < $endl} {incr l} {
            $ctext insert end "+$filelines($id,$f,$l)\n" $ncol
-           incr l
        }
-       set i $j
     }
     while {$l < $grouplineend} {
        $ctext insert end " $filelines($id,$f,$l)\n"
@@ -2167,6 +2205,45 @@ proc processgroup {} {
     $ctext conf -state disabled
 }
 
+proc similarity {pnum l nlc f events} {
+    global diffmergeid parents diffoffset filelines
+
+    set id $diffmergeid
+    set p [lindex $parents($id) $pnum]
+    set ol [expr {$l + $diffoffset($p)}]
+    set endl [expr {$l + $nlc}]
+    set same 0
+    set diff 0
+    foreach e $events {
+       if {[lindex $e 2] != $pnum} continue
+       set nl [lindex $e 0]
+       set ol [expr {$ol + $nl - $l}]
+       for {} {$l < $nl} {incr l} {
+           incr same [string length $filelines($id,$f,$l)]
+           incr same
+       }
+       set oc [lindex $e 3]
+       for {} {$oc > 0} {incr oc -1} {
+           incr diff [string length $filelines($p,$f,$ol)]
+           incr diff
+           incr ol
+       }
+       set nl [lindex $e 1]
+       for {} {$l < $nl} {incr l} {
+           incr diff [string length $filelines($id,$f,$l)]
+           incr diff
+       }
+    }
+    for {} {$l < $endl} {incr l} {
+       incr same [string length $filelines($id,$f,$l)]
+       incr same
+    }
+    if {$same == 0} {
+       return 0
+    }
+    return [expr {200 * $same / (2 * $same + $diff)}]
+}
+
 proc startdiff {ids} {
     global treediffs diffids treepending diffmergeid