diff --git a/gitk b/gitk
index 093213f24df..85f426ab224 100755
--- a/gitk
+++ b/gitk
@@ -80,6 +80,18 @@ proc start_rev_list {rlargs} {
     settextcursor watch
 }
 
+proc stop_rev_list {} {
+    global commfd
+
+    if {![info exists commfd]} return
+    catch {
+	set pid [pid $commfd]
+	exec kill $pid
+    }
+    catch {close $commfd}
+    unset commfd
+}
+
 proc getcommits {rargs} {
     global phase canv mainfont
 
@@ -173,6 +185,7 @@ proc getcommitlines {commfd}  {
 	lappend parentlist $olds
 	if {[info exists children($id)]} {
 	    lappend childlist $children($id)
+	    unset children($id)
 	} else {
 	    lappend childlist {}
 	}
@@ -217,8 +230,12 @@ proc readcommit {id} {
 }
 
 proc updatecommits {} {
-    global viewdata curview revtreeargs
+    global viewdata curview revtreeargs phase
 
+    if {$phase ne {}} {
+	stop_rev_list
+	set phase {}
+    }
     set n $curview
     set curview -1
     catch {unset viewdata($n)}
@@ -883,6 +900,25 @@ proc delview {} {
     showview 0
 }
 
+proc flatten {var} {
+    global $var
+
+    set ret {}
+    foreach i [array names $var] {
+	lappend ret $i [set $var\($i\)]
+    }
+    return $ret
+}
+
+proc unflatten {var l} {
+    global $var
+
+    catch {unset $var}
+    foreach {i v} $l {
+	set $var\($i\) $v
+    }
+}
+
 proc showview {n} {
     global curview viewdata viewfiles
     global displayorder parentlist childlist rowidlist rowoffsets
@@ -892,6 +928,8 @@ proc showview {n} {
     global matchinglines treediffs
     global parsed_args
     global pending_select phase
+    global commitidx rowlaidout rowoptim linesegends leftover
+    global commfd nextupdate
 
     if {$n == $curview} return
     set selid {}
@@ -911,10 +949,21 @@ proc showview {n} {
     unselectline
     normalline
     stopfindproc
-    if {$curview >= 0 && $phase eq {} && ![info exists viewdata($curview)]} {
-	set viewdata($curview) \
-	    [list $displayorder $parentlist $childlist $rowidlist \
-		 $rowoffsets $rowrangelist $commitlisted]
+    if {$curview >= 0} {
+	if {$phase ne {}} {
+	    set viewdata($curview) \
+		[list $phase $displayorder $parentlist $childlist $rowidlist \
+		     $rowoffsets $rowrangelist $commitlisted \
+		     [flatten children] [flatten idrowranges] \
+		     [flatten idinlist] \
+		     $commitidx $rowlaidout $rowoptim $numcommits \
+		     $linesegends $leftover $commfd]
+	    fileevent $commfd readable {}
+	} elseif {![info exists viewdata($curview)]} {
+	    set viewdata($curview) \
+		[list {} $displayorder $parentlist $childlist $rowidlist \
+		     $rowoffsets $rowrangelist $commitlisted]
+	}
     }
     catch {unset matchinglines}
     catch {unset treediffs}
@@ -933,18 +982,37 @@ proc showview {n} {
 	return
     }
 
-    set displayorder [lindex $viewdata($n) 0]
-    set parentlist [lindex $viewdata($n) 1]
-    set childlist [lindex $viewdata($n) 2]
-    set rowidlist [lindex $viewdata($n) 3]
-    set rowoffsets [lindex $viewdata($n) 4]
-    set rowrangelist [lindex $viewdata($n) 5]
-    set commitlisted [lindex $viewdata($n) 6]
-    set numcommits [llength $displayorder]
+    set v $viewdata($n)
+    set phase [lindex $v 0]
+    set displayorder [lindex $v 1]
+    set parentlist [lindex $v 2]
+    set childlist [lindex $v 3]
+    set rowidlist [lindex $v 4]
+    set rowoffsets [lindex $v 5]
+    set rowrangelist [lindex $v 6]
+    set commitlisted [lindex $v 7]
+    if {$phase eq {}} {
+	set numcommits [llength $displayorder]
+	catch {unset idrowranges}
+	catch {unset children}
+    } else {
+	unflatten children [lindex $v 8]
+	unflatten idrowranges [lindex $v 9]
+	unflatten idinlist [lindex $v 10]
+	set commitidx [lindex $v 11]
+	set rowlaidout [lindex $v 12]
+	set rowoptim [lindex $v 13]
+	set numcommits [lindex $v 14]
+	set linesegends [lindex $v 15]
+	set leftover [lindex $v 16]
+	set commfd [lindex $v 17]
+	fileevent $commfd readable [list getcommitlines $commfd]
+	set nextupdate [expr {[clock clicks -milliseconds] + 100}]
+    }
+
     catch {unset colormap}
     catch {unset rowtextx}
     catch {unset commitrow}
-    catch {unset idrowranges}
     set curview $n
     set row 0
     foreach id $displayorder {
@@ -1004,20 +1072,21 @@ proc ntimes {n o} {
 }
 
 proc usedinrange {id l1 l2} {
-    global children commitrow
+    global children commitrow childlist
 
     if {[info exists commitrow($id)]} {
 	set r $commitrow($id)
 	if {$l1 <= $r && $r <= $l2} {
 	    return [expr {$r - $l1 + 1}]
 	}
+	set kids [lindex $childlist $r]
+    } else {
+	set kids $children($id)
     }
-    foreach c $children($id) {
-	if {[info exists commitrow($c)]} {
-	    set r $commitrow($c)
-	    if {$l1 <= $r && $r <= $l2} {
-		return [expr {$r - $l1 + 1}]
-	    }
+    foreach c $kids {
+	set r $commitrow($c)
+	if {$l1 <= $r && $r <= $l2} {
+	    return [expr {$r - $l1 + 1}]
 	}
     }
     return 0
@@ -1112,7 +1181,7 @@ proc initlayout {} {
     catch {unset rowtextx}
     catch {unset commitrow}
     catch {unset idrowranges}
-    catch {unset linesegends}
+    set linesegends {}
 }
 
 proc setcanvscroll {} {
@@ -1177,16 +1246,14 @@ proc showstuff {canshow} {
     set r1 [lindex $rows 1]
     set selrow -1
     for {set r $row} {$r < $canshow} {incr r} {
-	if {[info exists linesegends($r)]} {
-	    foreach id $linesegends($r) {
-		set i -1
-		foreach {s e} $idrowranges($id) {
-		    incr i
-		    if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
-			&& ![info exists idrangedrawn($id,$i)]} {
-			drawlineseg $id $i
-			set idrangedrawn($id,$i) 1
-		    }
+	foreach id [lindex $linesegends [expr {$r+1}]] {
+	    set i -1
+	    foreach {s e} [rowranges $id] {
+		incr i
+		if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
+		    && ![info exists idrangedrawn($id,$i)]} {
+		    drawlineseg $id $i
+		    set idrangedrawn($id,$i) 1
 		}
 	    }
 	}
@@ -1229,6 +1296,7 @@ proc layoutrows {row endrow last} {
 		lappend oldolds $p
 	    }
 	}
+	set lse {}
 	set nev [expr {[llength $idlist] + [llength $newolds]
 		       + [llength $oldolds] - $maxwidth + 1}]
 	if {$nev > 0} {
@@ -1244,7 +1312,7 @@ proc layoutrows {row endrow last} {
 			set offs [incrange $offs $x 1]
 			set idinlist($i) 0
 			set rm1 [expr {$row - 1}]
-			lappend linesegends($rm1) $i
+			lappend lse $i
 			lappend idrowranges($i) $rm1
 			if {[incr nev -1] <= 0} break
 			continue
@@ -1255,6 +1323,7 @@ proc layoutrows {row endrow last} {
 	    lset rowidlist $row $idlist
 	    lset rowoffsets $row $offs
 	}
+	lappend linesegends $lse
 	set col [lsearch -exact $idlist $id]
 	if {$col < 0} {
 	    set col [llength $idlist]
@@ -1275,8 +1344,9 @@ proc layoutrows {row endrow last} {
 	}
 	set ranges {}
 	if {[info exists idrowranges($id)]} {
-	    lappend idrowranges($id) $row
 	    set ranges $idrowranges($id)
+	    lappend ranges $row
+	    unset idrowranges($id)
 	}
 	lappend rowrangelist $ranges
 	incr row
@@ -1331,6 +1401,7 @@ proc addextraid {id row} {
     }
     if {[info exists children($id)]} {
 	lappend childlist $children($id)
+	unset children($id)
     } else {
 	lappend childlist {}
     }
@@ -1349,6 +1420,7 @@ proc layouttail {} {
 	unset idinlist($id)
 	lappend idrowranges($id) $row
 	lappend rowrangelist $idrowranges($id)
+	unset idrowranges($id)
 	incr row
 	set offs [ntimes $col 0]
 	set idlist [lreplace $idlist $col $col]
@@ -1363,6 +1435,7 @@ proc layouttail {} {
 	makeuparrow $id 0 $row 0
 	lappend idrowranges($id) $row
 	lappend rowrangelist $idrowranges($id)
+	unset idrowranges($id)
 	incr row
 	lappend rowidlist {}
 	lappend rowoffsets {}
@@ -1398,8 +1471,8 @@ proc optimize_rows {row col endrow} {
 	    set z0 [lindex $rowoffsets $y0 $x0]
 	    if {$z0 eq {}} {
 		set id [lindex $idlist $col]
-		if {[info exists idrowranges($id)] &&
-		    $y0 > [lindex $idrowranges($id) 0]} {
+		set ranges [rowranges $id]
+		if {$ranges ne {} && $y0 > [lindex $ranges 0]} {
 		    set isarrow 1
 		}
 	    }
@@ -1457,8 +1530,8 @@ proc optimize_rows {row col endrow} {
 		if {$o eq {}} {
 		    # check if this is the link to the first child
 		    set id [lindex $idlist $col]
-		    if {[info exists idrowranges($id)] &&
-			$row == [lindex $idrowranges($id) 0]} {
+		    set ranges [rowranges $id]
+		    if {$ranges ne {} && $row == [lindex $ranges 0]} {
 			# it is, work out offset to child
 			set y0 [expr {$row - 1}]
 			set id [lindex $displayorder $y0]
@@ -1513,10 +1586,11 @@ proc linewidth {id} {
 }
 
 proc rowranges {id} {
-    global idrowranges commitrow numcommits rowrangelist
+    global phase idrowranges commitrow rowlaidout rowrangelist
 
     set ranges {}
-    if {[info exists commitrow($id)] && $commitrow($id) < $numcommits} {
+    if {$phase eq {} ||
+	([info exists commitrow($id)] && $commitrow($id) < $rowlaidout)} {
 	set ranges [lindex $rowrangelist $commitrow($id)]
     } elseif {[info exists idrowranges($id)]} {
 	set ranges $idrowranges($id)
@@ -1727,6 +1801,7 @@ proc drawcmitrow {row} {
 
     if {$row >= $numcommits} return
     foreach id [lindex $rowidlist $row] {
+	if {$id eq {}} continue
 	set i -1
 	foreach {s e} [rowranges $id] {
 	    incr i
@@ -3142,7 +3217,7 @@ proc incrfont {inc} {
     foreach e $entries {
 	$e conf -font $mainfont
     }
-    if {$phase == "getcommits"} {
+    if {$phase eq "getcommits"} {
 	$canv itemconf textitems -font $mainfont
     }
     redisplay