]> git.ipfire.org Git - thirdparty/git.git/blobdiff - gitk
gitk: Get rid of the rowchk array
[thirdparty/git.git] / gitk
diff --git a/gitk b/gitk
index d2f5eeeaaf81483a78a3d60a8f4d13203d4fded4..7726c311c5d40314ec64c219ef7786459ecd2703 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -151,7 +151,7 @@ proc getcommitlines {fd view}  {
     global displayorder commitidx commitrow commitdata
     global parentlist children curview hlview
     global vparentlist vdisporder vcmitlisted
-    global ordertok vnextroot
+    global ordertok vnextroot idpending
 
     set stuff [read $fd 500000]
     # git log doesn't terminate the last commit with a null...
@@ -162,6 +162,23 @@ proc getcommitlines {fd view}  {
        if {![eof $fd]} {
            return 1
        }
+       # Check if we have seen any ids listed as parents that haven't
+       # appeared in the list
+       foreach vid [array names idpending "$view,*"] {
+           # should only get here if git log is buggy
+           set id [lindex [split $vid ","] 1]
+           set commitrow($vid) $commitidx($view)
+           incr commitidx($view)
+           if {$view == $curview} {
+               lappend parentlist {}
+               lappend displayorder $id
+               lappend commitlisted 0
+           } else {
+               lappend vparentlist($view) {}
+               lappend vdisporder($view) $id
+               lappend vcmitlisted($view) 0
+           }
+       }
        global viewname
        unset commfd($view)
        notbusy $view
@@ -242,6 +259,7 @@ proc getcommitlines {fd view}  {
            set ordertok($view,$id) $otok
        } else {
            set otok $ordertok($view,$id)
+           unset idpending($view,$id)
        }
        if {$listed} {
            set olds [lrange $ids 1 end]
@@ -250,6 +268,7 @@ proc getcommitlines {fd view}  {
                lappend children($view,$p) $id
                if {![info exists ordertok($view,$p)]} {
                    set ordertok($view,$p) $ordertok($view,$id)
+                   set idpending($view,$p) 1
                }
            } else {
                set i 0
@@ -259,6 +278,7 @@ proc getcommitlines {fd view}  {
                    }
                    if {![info exists ordertok($view,$p)]} {
                        set ordertok($view,$p) "$otok[strrep $i]]"
+                       set idpending($view,$p) 1
                    }
                    incr i
                }
@@ -328,7 +348,7 @@ proc readcommit {id} {
 }
 
 proc updatecommits {} {
-    global viewdata curview phase displayorder
+    global viewdata curview phase displayorder ordertok idpending
     global children commitrow selectedline thickerline showneartags
 
     if {$phase ne {}} {
@@ -339,6 +359,10 @@ proc updatecommits {} {
     foreach id $displayorder {
        catch {unset children($n,$id)}
        catch {unset commitrow($n,$id)}
+       catch {unset ordertok($n,$id)}
+    }
+    foreach vid [array names idpending "$n,*"] {
+       unset idpending($vid)
     }
     set curview -1
     catch {unset selectedline}
@@ -1927,7 +1951,7 @@ proc showview {n} {
     global curview viewdata viewfiles
     global displayorder parentlist rowidlist
     global colormap rowtextx commitrow nextcolor canvxmax
-    global numcommits rowrangelist commitlisted idrowranges rowchk
+    global numcommits commitlisted
     global selectedline currentid canv canvy0
     global treediffs
     global pending_select phase
@@ -1935,7 +1959,7 @@ proc showview {n} {
     global commfd
     global selectedview selectfirst
     global vparentlist vdisporder vcmitlisted
-    global hlview selectedhlview
+    global hlview selectedhlview commitinterest
 
     if {$n == $curview} return
     set selid {}
@@ -1963,13 +1987,11 @@ proc showview {n} {
        set vcmitlisted($curview) $commitlisted
        if {$phase ne {}} {
            set viewdata($curview) \
-               [list $phase $rowidlist {} $rowrangelist \
-                    [flatten idrowranges] [flatten idinlist] \
-                    $rowlaidout $rowoptim $numcommits]
+               [list $phase $rowidlist $rowlaidout $rowoptim $numcommits]
        } elseif {![info exists viewdata($curview)]
                  || [lindex $viewdata($curview) 0] ne {}} {
            set viewdata($curview) \
-               [list {} $rowidlist {} $rowrangelist]
+               [list {} $rowidlist]
        }
     }
     catch {unset treediffs}
@@ -1978,6 +2000,7 @@ proc showview {n} {
        unset hlview
        set selectedhlview None
     }
+    catch {unset commitinterest}
 
     set curview $n
     set selectedview $n
@@ -1998,17 +2021,12 @@ proc showview {n} {
     set parentlist $vparentlist($n)
     set commitlisted $vcmitlisted($n)
     set rowidlist [lindex $v 1]
-    set rowrangelist [lindex $v 3]
     if {$phase eq {}} {
        set numcommits [llength $displayorder]
-       catch {unset idrowranges}
     } else {
-       unflatten idrowranges [lindex $v 4]
-       unflatten idinlist [lindex $v 5]
-       set rowlaidout [lindex $v 6]
-       set rowoptim [lindex $v 7]
-       set numcommits [lindex $v 8]
-       catch {unset rowchk}
+       set rowlaidout [lindex $v 2]
+       set rowoptim [lindex $v 3]
+       set numcommits [lindex $v 4]
     }
 
     catch {unset colormap}
@@ -2126,7 +2144,7 @@ proc addvhighlight {n} {
     }
     set hlview $n
     if {$n != $curview && ![info exists viewdata($n)]} {
-       set viewdata($n) [list getcommits {{}} {{}} {} {} {} 0 0 0 {}]
+       set viewdata($n) [list getcommits {{}} 0 0 0]
        set vparentlist($n) {}
        set vdisporder($n) {}
        set vcmitlisted($n) {}
@@ -2638,9 +2656,11 @@ proc usedinrange {id l1 l2} {
     }
     set kids $children($curview,$id)
     foreach c $kids {
-       set r $commitrow($curview,$c)
-       if {$l1 <= $r && $r <= $l2} {
-           return [expr {$r - $l1 + 1}]
+       if {[info exists commitrow($curview,$c)]} {
+           set r $commitrow($curview,$c)
+           if {$l1 <= $r && $r <= $l2} {
+               return [expr {$r - $l1 + 1}]
+           }
        }
     }
     return 0
@@ -2670,7 +2690,7 @@ proc idcol {idlist id {i 0}} {
 }
 
 proc makeuparrow {oid y x} {
-    global rowidlist uparrowlen idrowranges displayorder
+    global rowidlist uparrowlen displayorder
 
     for {set i 0} {$i < $uparrowlen && $y > 1} {incr i} {
        incr y -1
@@ -2678,13 +2698,11 @@ proc makeuparrow {oid y x} {
        set x [idcol $idl $oid $x]
        lset rowidlist $y [linsert $idl $x $oid]
     }
-    lappend idrowranges($oid) [lindex $displayorder $y]
 }
 
 proc initlayout {} {
     global rowidlist displayorder commitlisted
     global rowlaidout rowoptim
-    global idinlist rowchk rowrangelist idrowranges
     global numcommits canvxmax canv
     global nextcolor
     global parentlist
@@ -2695,17 +2713,13 @@ proc initlayout {} {
     set displayorder {}
     set commitlisted {}
     set parentlist {}
-    set rowrangelist {}
     set nextcolor 0
     set rowidlist {{}}
-    catch {unset idinlist}
-    catch {unset rowchk}
     set rowlaidout 0
     set rowoptim 0
     set canvxmax [$canv cget -width]
     catch {unset colormap}
     catch {unset rowtextx}
-    catch {unset idrowranges}
     set selectfirst 1
 }
 
@@ -2739,7 +2753,7 @@ proc visiblerows {} {
 
 proc layoutmore {tmax allread} {
     global rowlaidout rowoptim commitidx numcommits optim_delay
-    global uparrowlen curview rowidlist idinlist
+    global uparrowlen curview rowidlist
 
     set showlast 0
     set showdelay $optim_delay
@@ -2769,8 +2783,7 @@ proc layoutmore {tmax allread} {
        } elseif {$allread} {
            set optdelay 0
            set nrows $commitidx($curview)
-           if {[lindex $rowidlist $nrows] ne {} ||
-               [array names idinlist] ne {}} {
+           if {[lindex $rowidlist $nrows] ne {}} {
                layouttail
                set rowlaidout $commitidx($curview)
            } elseif {$rowoptim == $nrows} {
@@ -2948,33 +2961,43 @@ proc readdifffiles {fd serial} {
     return 0
 }
 
+proc nextuse {id row} {
+    global commitrow curview children
+
+    if {[info exists children($curview,$id)]} {
+       foreach kid $children($curview,$id) {
+           if {[info exists commitrow($curview,$kid)] &&
+               $commitrow($curview,$kid) > $row} {
+               return $commitrow($curview,$kid)
+           }
+       }
+    }
+    if {[info exists commitrow($curview,$id)]} {
+       return $commitrow($curview,$id)
+    }
+    return -1
+}
+
 proc layoutrows {row endrow last} {
     global rowidlist displayorder
     global uparrowlen downarrowlen maxwidth mingaplen
     global children parentlist
-    global idrowranges
     global commitidx curview
-    global idinlist rowchk rowrangelist
 
     set idlist [lindex $rowidlist $row]
+    if {!$last && $endrow + $uparrowlen + $mingaplen > $commitidx($curview)} {
+       set endrow [expr {$commitidx($curview) - $uparrowlen - $mingaplen}]
+    }
     while {$row < $endrow} {
        set id [lindex $displayorder $row]
-       if {1} {
-           if {!$last &&
-               $row + $uparrowlen + $mingaplen >= $commitidx($curview)} break
-           for {set x [llength $idlist]} {[incr x -1] >= 0} {} {
-               set i [lindex $idlist $x]
-               if {![info exists rowchk($i)] || $row >= $rowchk($i)} {
-                   set r [usedinrange $i [expr {$row - $downarrowlen}] \
-                              [expr {$row + $uparrowlen + $mingaplen}]]
-                   if {$r == 0} {
-                       set idlist [lreplace $idlist $x $x]
-                       set idinlist($i) 0
-                       set rm1 [expr {$row - 1}]
-                       lappend idrowranges($i) [lindex $displayorder $rm1]
-                       continue
-                   }
-                   set rowchk($i) [expr {$row + $r}]
+       if {$row > $downarrowlen} {
+           set termrow [expr {$row - $downarrowlen - 1}]
+           foreach p [lindex $parentlist $termrow] {
+               set i [lsearch -exact $idlist $p]
+               if {$i < 0} continue
+               set nr [nextuse $p $termrow]
+               if {$nr < 0 || $nr >= $row + $mingaplen + $uparrowlen} {
+                   set idlist [lreplace $idlist $i $i]
                }
            }
            lset rowidlist $row $idlist
@@ -2982,12 +3005,12 @@ proc layoutrows {row endrow last} {
        set oldolds {}
        set newolds {}
        foreach p [lindex $parentlist $row] {
-           if {![info exists idinlist($p)]} {
+           # is id the first child of this parent?
+           if {$id eq [lindex $children($curview,$p) 0]} {
                lappend newolds $p
-           } elseif {!$idinlist($p)} {
+           } elseif {[lsearch -exact $idlist $p] < 0} {
                lappend oldolds $p
            }
-           set idinlist($p) 1
        }
        set col [lsearch -exact $idlist $id]
        if {$col < 0} {
@@ -2995,26 +3018,15 @@ proc layoutrows {row endrow last} {
            set idlist [linsert $idlist $col $id]
            lset rowidlist $row $idlist
            if {$children($curview,$id) ne {}} {
-               unset idinlist($id)
                makeuparrow $id $row $col
            }
-       } else {
-           unset idinlist($id)
-       }
-       set ranges {}
-       if {[info exists idrowranges($id)]} {
-           set ranges $idrowranges($id)
-           lappend ranges $id
-           unset idrowranges($id)
        }
-       lappend rowrangelist $ranges
        incr row
        set idlist [lreplace $idlist $col $col]
        set x $col
        foreach i $newolds {
            set x [idcol $idlist $i $x]
            set idlist [linsert $idlist $x $i]
-           set idrowranges($i) $id
        }
        foreach oid $oldolds {
            set x [idcol $idlist $oid $x]
@@ -3046,8 +3058,7 @@ proc addextraid {id row} {
 }
 
 proc layouttail {} {
-    global rowidlist idinlist commitidx curview
-    global idrowranges rowrangelist
+    global rowidlist commitidx curview
 
     set row $commitidx($curview)
     set idlist [lindex $rowidlist $row]
@@ -3055,26 +3066,10 @@ proc layouttail {} {
        set col [expr {[llength $idlist] - 1}]
        set id [lindex $idlist $col]
        addextraid $id $row
-       catch {unset idinlist($id)}
-       lappend idrowranges($id) $id
-       lappend rowrangelist $idrowranges($id)
-       unset idrowranges($id)
        incr row
        set idlist [lreplace $idlist $col $col]
        lappend rowidlist $idlist
     }
-
-    foreach id [array names idinlist] {
-       unset idinlist($id)
-       addextraid $id $row
-       lset rowidlist $row [list $id]
-       makeuparrow $id $row 0
-       lappend idrowranges($id) $id
-       lappend rowrangelist $idrowranges($id)
-       unset idrowranges($id)
-       incr row
-       lappend rowidlist {}
-    }
 }
 
 proc insert_pad {row col npad} {
@@ -3092,7 +3087,7 @@ proc insert_pad {row col npad} {
 }
 
 proc optimize_rows {row col endrow} {
-    global rowidlist displayorder
+    global rowidlist displayorder curview children
 
     if {$row < 1} {
        set row 1
@@ -3131,8 +3126,9 @@ proc optimize_rows {row col endrow} {
                }
            }
            if {$z0 eq {}} {
-               set ranges [rowranges $id]
-               if {$ranges ne {} && $y0 > [lindex $ranges 0]} {
+               # if row y0 is the first child of $id then it's not an arrow
+               if {[lindex $children($curview,$id) 0] ne
+                   [lindex $displayorder $y0]} {
                    set isarrow 1
                }
            }
@@ -3195,11 +3191,10 @@ proc optimize_rows {row col endrow} {
                set x0 [lsearch -exact $previdlist $id]
                if {$x0 < 0} {
                    # check if this is the link to the first child
-                   set ranges [rowranges $id]
-                   if {$ranges ne {} && $row == [lindex $ranges 0]} {
+                   set kid [lindex $displayorder $y0]
+                   if {[lindex $children($curview,$id) 0] eq $kid} {
                        # it is, work out offset to child
-                       set id [lindex $displayorder $y0]
-                       set x0 [lsearch -exact $previdlist $id]
+                       set x0 [lsearch -exact $previdlist $kid]
                    }
                }
                if {$x0 <= $col} break
@@ -3236,24 +3231,59 @@ proc linewidth {id} {
 }
 
 proc rowranges {id} {
-    global phase idrowranges commitrow rowlaidout rowrangelist curview
+    global commitrow curview children uparrowlen downarrowlen
+    global rowidlist
 
-    set ranges {}
-    if {$phase eq {} ||
-       ([info exists commitrow($curview,$id)]
-        && $commitrow($curview,$id) < $rowlaidout)} {
-       set ranges [lindex $rowrangelist $commitrow($curview,$id)]
-    } elseif {[info exists idrowranges($id)]} {
-       set ranges $idrowranges($id)
-    }
-    set linenos {}
-    foreach rid $ranges {
-       lappend linenos $commitrow($curview,$rid)
+    set kids $children($curview,$id)
+    if {$kids eq {}} {
+       return {}
     }
-    if {$linenos ne {}} {
-       lset linenos 0 [expr {[lindex $linenos 0] + 1}]
+    set ret {}
+    lappend kids $id
+    foreach child $kids {
+       if {![info exists commitrow($curview,$child)]} break
+       set row $commitrow($curview,$child)
+       if {![info exists prev]} {
+           lappend ret [expr {$row + 1}]
+       } else {
+           if {$row <= $prevrow} {
+               puts "oops children out of order [shortids $id] $row < [shortids $prev] $prevrow"
+           }
+           # see if the line extends the whole way from prevrow to row
+           if {$row > $prevrow + $uparrowlen + $downarrowlen &&
+               [lsearch -exact [lindex $rowidlist \
+                           [expr {int(($row + $prevrow) / 2)}]] $id] < 0} {
+               # it doesn't, see where it ends
+               set r [expr {$prevrow + $downarrowlen}]
+               if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
+                   while {[incr r -1] > $prevrow &&
+                          [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
+               } else {
+                   while {[incr r] <= $row &&
+                          [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
+                   incr r -1
+               }
+               lappend ret $r
+               # see where it starts up again
+               set r [expr {$row - $uparrowlen}]
+               if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
+                   while {[incr r] < $row &&
+                          [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
+               } else {
+                   while {[incr r -1] >= $prevrow &&
+                          [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
+                   incr r
+               }
+               lappend ret $r
+           }
+       }
+       if {$child eq $id} {
+           lappend ret $row
+       }
+       set prev $id
+       set prevrow $row
     }
-    return $linenos
+    return $ret
 }
 
 proc drawlineseg {id row endrow arrowlow} {
@@ -3938,8 +3968,8 @@ proc show_status {msg} {
 proc insertrow {row newcmit} {
     global displayorder parentlist commitlisted children
     global commitrow curview rowidlist numcommits
-    global rowrangelist rowlaidout rowoptim numcommits
-    global selectedline rowchk commitidx
+    global rowlaidout rowoptim numcommits
+    global selectedline commitidx
 
     if {$row >= $numcommits} {
        puts "oops, inserting new row $row but only have $numcommits rows"
@@ -3970,20 +4000,6 @@ proc insertrow {row newcmit} {
     }
     set rowidlist [linsert $rowidlist $row $idlist]
 
-    set rowrangelist [linsert $rowrangelist $row {}]
-    if {[llength $kids] > 1} {
-       set rp1 [expr {$row + 1}]
-       set ranges [lindex $rowrangelist $rp1]
-       if {$ranges eq {}} {
-           set ranges [list $newcmit $p]
-       } elseif {[lindex $ranges end-1] eq $p} {
-           lset ranges end-1 $newcmit
-       }
-       lset rowrangelist $rp1 $ranges
-    }
-
-    catch {unset rowchk}
-
     incr rowlaidout
     incr rowoptim
     incr numcommits
@@ -3998,8 +4014,8 @@ proc insertrow {row newcmit} {
 proc removerow {row} {
     global displayorder parentlist commitlisted children
     global commitrow curview rowidlist numcommits
-    global rowrangelist idrowranges rowlaidout rowoptim numcommits
-    global linesegends selectedline rowchk commitidx
+    global rowlaidout rowoptim numcommits
+    global linesegends selectedline commitidx
 
     if {$row >= $numcommits} {
        puts "oops, removing row $row but only have $numcommits rows"
@@ -4026,17 +4042,6 @@ proc removerow {row} {
 
     set rowidlist [lreplace $rowidlist $row $row]
 
-    set rowrangelist [lreplace $rowrangelist $row $row]
-    if {[llength $kids] > 0} {
-       set ranges [lindex $rowrangelist $row]
-       if {[lindex $ranges end-1] eq $id} {
-           set ranges [lreplace $ranges end-1 end]
-           lset rowrangelist $row $ranges
-       }
-    }
-
-    catch {unset rowchk}
-
     incr rowlaidout -1
     incr rowoptim -1
     incr numcommits -1
@@ -4215,6 +4220,7 @@ proc findmorerev {} {
     set last 0
     for {} {$l > $lim} {incr l -1} {
        set id [lindex $displayorder $l]
+       if {![info exists commitdata($id)]} continue
        if {![doesmatch $commitdata($id)]} continue
        if {![info exists commitinfo($id)]} {
            getcommit $id
@@ -4324,7 +4330,7 @@ proc commit_descriptor {p} {
 # append some text to the ctext widget, and make any SHA1 ID
 # that we know about be a clickable link.
 proc appendwithlinks {text tags} {
-    global ctext commitrow linknum curview
+    global ctext commitrow linknum curview pendinglinks
 
     set start [$ctext index "end - 1c"]
     $ctext insert end $text $tags
@@ -4333,17 +4339,48 @@ proc appendwithlinks {text tags} {
        set s [lindex $l 0]
        set e [lindex $l 1]
        set linkid [string range $text $s $e]
-       if {![info exists commitrow($curview,$linkid)]} continue
        incr e
-       $ctext tag add link "$start + $s c" "$start + $e c"
        $ctext tag add link$linknum "$start + $s c" "$start + $e c"
-       $ctext tag bind link$linknum <1> \
-           [list selectline $commitrow($curview,$linkid) 1]
+       setlink $linkid link$linknum
        incr linknum
     }
-    $ctext tag conf link -foreground blue -underline 1
-    $ctext tag bind link <Enter> { %W configure -cursor hand2 }
-    $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+}
+
+proc setlink {id lk} {
+    global curview commitrow ctext pendinglinks commitinterest
+
+    if {[info exists commitrow($curview,$id)]} {
+       $ctext tag conf $lk -foreground blue -underline 1
+       $ctext tag bind $lk <1> [list selectline $commitrow($curview,$id) 1]
+       $ctext tag bind $lk <Enter> {linkcursor %W 1}
+       $ctext tag bind $lk <Leave> {linkcursor %W -1}
+    } else {
+       lappend pendinglinks($id) $lk
+       lappend commitinterest($id) {makelink %I}
+    }
+}
+
+proc makelink {id} {
+    global pendinglinks
+
+    if {![info exists pendinglinks($id)]} return
+    foreach lk $pendinglinks($id) {
+       setlink $id $lk
+    }
+    unset pendinglinks($id)
+}
+
+proc linkcursor {w inc} {
+    global linkentercount curtextcursor
+
+    if {[incr linkentercount $inc] > 0} {
+       $w configure -cursor hand2
+    } else {
+       $w configure -cursor $curtextcursor
+       if {$linkentercount < 0} {
+           set linkentercount 0
+       }
+    }
 }
 
 proc viewnextline {dir} {
@@ -4390,15 +4427,7 @@ proc appendrefs {pos ids var} {
            $ctext tag delete $lk
            $ctext insert $pos $sep
            $ctext insert $pos [lindex $ti 0] $lk
-           if {[info exists commitrow($curview,$id)]} {
-               $ctext tag conf $lk -foreground blue
-               $ctext tag bind $lk <1> \
-                   [list selectline $commitrow($curview,$id) 1]
-               $ctext tag conf $lk -underline 1
-               $ctext tag bind $lk <Enter> { %W configure -cursor hand2 }
-               $ctext tag bind $lk <Leave> \
-                   { %W configure -cursor $curtextcursor }
-           }
+           setlink $id $lk
            set sep ", "
        }
     }
@@ -5239,6 +5268,7 @@ proc nextfile {} {
 
 proc clear_ctext {{first 1.0}} {
     global ctext smarktop smarkbot
+    global pendinglinks
 
     set l [lindex [split $first .] 0]
     if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
@@ -5248,6 +5278,9 @@ proc clear_ctext {{first 1.0}} {
        set smarkbot $l
     }
     $ctext delete $first end
+    if {$first eq "1.0"} {
+       catch {unset pendinglinks}
+    }
 }
 
 proc incrsearch {name ix op} {
@@ -5611,12 +5644,9 @@ proc lineclick {x y id isnew} {
     # fill the details pane with info about this line
     $ctext conf -state normal
     clear_ctext
-    $ctext tag conf link -foreground blue -underline 1
-    $ctext tag bind link <Enter> { %W configure -cursor hand2 }
-    $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
     $ctext insert end "Parent:\t"
-    $ctext insert end $id [list link link0]
-    $ctext tag bind link0 <1> [list selbyid $id]
+    $ctext insert end $id link0
+    setlink $id link0
     set info $commitinfo($id)
     $ctext insert end "\n\t[lindex $info 0]\n"
     $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
@@ -5631,8 +5661,8 @@ proc lineclick {x y id isnew} {
            if {![info exists commitinfo($child)] && ![getcommit $child]} continue
            set info $commitinfo($child)
            $ctext insert end "\n\t"
-           $ctext insert end $child [list link link$i]
-           $ctext tag bind link$i <1> [list selbyid $child]
+           $ctext insert end $child link$i
+           setlink $child link$i
            $ctext insert end "\n\t[lindex $info 0]"
            $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
            set date [formatdate [lindex $info 2]]
@@ -5713,16 +5743,13 @@ proc doseldiff {oldid newid} {
     clear_ctext
     init_flist "Top"
     $ctext insert end "From "
-    $ctext tag conf link -foreground blue -underline 1
-    $ctext tag bind link <Enter> { %W configure -cursor hand2 }
-    $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
-    $ctext tag bind link0 <1> [list selbyid $oldid]
-    $ctext insert end $oldid [list link link0]
+    $ctext insert end $oldid link0
+    setlink $oldid link0
     $ctext insert end "\n     "
     $ctext insert end [lindex $commitinfo($oldid) 0]
     $ctext insert end "\n\nTo   "
-    $ctext tag bind link1 <1> [list selbyid $newid]
-    $ctext insert end $newid [list link link1]
+    $ctext insert end $newid link1
+    setlink $newid link1
     $ctext insert end "\n     "
     $ctext insert end [lindex $commitinfo($newid) 0]
     $ctext insert end "\n"
@@ -7894,6 +7921,7 @@ set boldrows {}
 set boldnamerows {}
 set diffelide {0 0}
 set markingmatches 0
+set linkentercount 0
 
 set optim_delay 16