gitk: Get rid of idinlist array
[gitweb.git] / gitk
diff --git a/gitk b/gitk
index d2f5eeeaaf81483a78a3d60a8f4d13203d4fded4..7b0b4cfade0a6c225a8fd37555eb4a8e554be6ec 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 rowchk
     global selectedline currentid canv canvy0
     global treediffs
     global pending_select phase
@@ -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}
@@ -1998,16 +2020,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]
+       set rowlaidout [lindex $v 2]
+       set rowoptim [lindex $v 3]
+       set numcommits [lindex $v 4]
        catch {unset rowchk}
     }
 
@@ -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,12 @@ 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 rowchk
     global numcommits canvxmax canv
     global nextcolor
     global parentlist
@@ -2695,17 +2714,14 @@ 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 +2755,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 +2785,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} {
@@ -2952,9 +2967,8 @@ 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
+    global rowchk
 
     set idlist [lindex $rowidlist $row]
     while {$row < $endrow} {
@@ -2969,9 +2983,6 @@ proc layoutrows {row endrow last} {
                               [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}]
@@ -2982,12 +2993,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 +3006,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 +3046,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 +3054,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 +3075,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 +3114,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 +3179,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 +3219,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,7 +3956,7 @@ proc show_status {msg} {
 proc insertrow {row newcmit} {
     global displayorder parentlist commitlisted children
     global commitrow curview rowidlist numcommits
-    global rowrangelist rowlaidout rowoptim numcommits
+    global rowlaidout rowoptim numcommits
     global selectedline rowchk commitidx
 
     if {$row >= $numcommits} {
@@ -3970,18 +3988,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
@@ -3998,7 +4004,7 @@ proc insertrow {row newcmit} {
 proc removerow {row} {
     global displayorder parentlist commitlisted children
     global commitrow curview rowidlist numcommits
-    global rowrangelist idrowranges rowlaidout rowoptim numcommits
+    global rowlaidout rowoptim numcommits
     global linesegends selectedline rowchk commitidx
 
     if {$row >= $numcommits} {
@@ -4026,15 +4032,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
@@ -4215,6 +4212,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