gitk 18.6 KB
Newer Older
1 2 3 4 5 6 7 8 9
#!/bin/sh
# Tcl ignores the next line -*- tcl -*- \
exec wish "$0" -- "${1+$@}"

# Copyright (C) 2005 Paul Mackerras.  All rights reserved.
# This program is free software; it may be used, copied, modified
# and distributed under the terms of the GNU General Public Licence,
# either version 2, or (at your option) any later version.

10
# CVS $Revision: 1.6 $
P
Paul Mackerras 已提交
11

12 13 14
set datemode 0
set boldnames 0
set revtreeargs {}
15
set diffopts "-U 5 -p"
16

17 18
set mainfont {Helvetica 9}
set namefont $mainfont
19
set textfont {Courier 9}
20 21 22
if {$boldnames} {
    lappend namefont bold
}
23 24 25 26

set colors {green red blue magenta darkgrey brown orange}
set colorbycommitter false

27 28
catch {source ~/.gitk}

29 30 31 32
foreach arg $argv {
    switch -regexp -- $arg {
	"^$" { }
	"^-b" { set boldnames 1 }
33 34
	"^-c" { set colorbycommitter 1 }
	"^-d" { set datemode 1 }
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	"^-.*" {
	    puts stderr "unrecognized option $arg"
	    exit 1
	}
	default {
	    lappend revtreeargs $arg
	}
    }
}

proc getcommits {rargs} {
    global commits parents cdate nparents children nchildren
    if {$rargs == {}} {
	set rargs HEAD
    }
    set commits {}
    foreach c [split [eval exec git-rev-tree $rargs] "\n"] {
	set i 0
	set cid {}
	foreach f $c {
	    if {$i == 0} {
		set d $f
	    } else {
		set id [lindex [split $f :] 0]
		if {![info exists nchildren($id)]} {
		    set children($id) {}
		    set nchildren($id) 0
		}
		if {$i == 1} {
		    set cid $id
		    lappend commits $id
		    set parents($id) {}
		    set cdate($id) $d
		    set nparents($id) 0
		} else {
		    lappend parents($cid) $id
		    incr nparents($cid)
		    incr nchildren($id)
		    lappend children($id) $cid
		}
	    }
	    incr i
	}
    }
}

proc readcommit {id} {
82
    global commitinfo
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
    set inhdr 1
    set comment {}
    set headline {}
    set auname {}
    set audate {}
    set comname {}
    set comdate {}
    foreach line [split [exec git-cat-file commit $id] "\n"] {
	if {$inhdr} {
	    if {$line == {}} {
		set inhdr 0
	    } else {
		set tag [lindex $line 0]
		if {$tag == "author"} {
		    set x [expr {[llength $line] - 2}]
		    set audate [lindex $line $x]
		    set auname [lrange $line 1 [expr {$x - 1}]]
		} elseif {$tag == "committer"} {
		    set x [expr {[llength $line] - 2}]
		    set comdate [lindex $line $x]
		    set comname [lrange $line 1 [expr {$x - 1}]]
		}
	    }
	} else {
	    if {$comment == {}} {
		set headline $line
	    } else {
		append comment "\n"
	    }
	    append comment $line
	}
    }
    if {$audate != {}} {
	set audate [clock format $audate -format "%Y-%m-%d %H:%M:%S"]
    }
    if {$comdate != {}} {
	set comdate [clock format $comdate -format "%Y-%m-%d %H:%M:%S"]
    }
121 122
    set commitinfo($id) [list $headline $auname $audate \
			     $comname $comdate $comment]
123 124 125
}

proc makewindow {} {
126
    global canv canv2 canv3 linespc charspc ctext cflist textfont
P
Paul Mackerras 已提交
127
    panedwindow .ctop -orient vertical
128
    panedwindow .ctop.clist -orient horizontal -sashpad 0 -handlesize 4
P
Paul Mackerras 已提交
129
    .ctop add .ctop.clist
130 131
    set canv .ctop.clist.canv
    set cscroll .ctop.clist.dates.csb
132 133
    set height [expr 25 * $linespc + 4]
    canvas $canv -height $height -width [expr 45 * $charspc] \
134 135 136 137
	-bg white -bd 0 \
	-yscrollincr $linespc -yscrollcommand "$cscroll set"
    .ctop.clist add $canv
    set canv2 .ctop.clist.canv2
138
    canvas $canv2 -height $height -width [expr 30 * $charspc] \
139 140 141 142 143
	-bg white -bd 0 -yscrollincr $linespc
    .ctop.clist add $canv2
    frame .ctop.clist.dates
    .ctop.clist add .ctop.clist.dates
    set canv3 .ctop.clist.dates.canv3
144
    canvas $canv3 -height $height -width [expr 15 * $charspc] \
145 146 147 148 149
	-bg white -bd 0 -yscrollincr $linespc
    scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
    pack .ctop.clist.dates.csb -side right -fill y
    pack $canv3 -side left -fill both -expand 1

150 151
    panedwindow .ctop.cdet -orient horizontal
    .ctop add .ctop.cdet
152 153
    frame .ctop.cdet.left
    set ctext .ctop.cdet.left.ctext
154
    text $ctext -bg white -state disabled -font $textfont -height 32 \
155 156 157 158 159 160
	-yscrollcommand ".ctop.cdet.left.sb set"
    scrollbar .ctop.cdet.left.sb -command "$ctext yview"
    pack .ctop.cdet.left.sb -side right -fill y
    pack $ctext -side left -fill both -expand 1
    .ctop.cdet add .ctop.cdet.left

161 162 163 164 165
    $ctext tag conf filesep -font [concat $textfont bold]
    $ctext tag conf hunksep -back blue -fore white
    $ctext tag conf d0 -back "#ff8080"
    $ctext tag conf d1 -back green

166 167
    frame .ctop.cdet.right
    set cflist .ctop.cdet.right.cfiles
168
    listbox $cflist -width 30 -bg white -selectmode extended \
169 170 171 172 173 174
	-yscrollcommand ".ctop.cdet.right.sb set"
    scrollbar .ctop.cdet.right.sb -command "$cflist yview"
    pack .ctop.cdet.right.sb -side right -fill y
    pack $cflist -side left -fill both -expand 1
    .ctop.cdet add .ctop.cdet.right

P
Paul Mackerras 已提交
175
    pack .ctop -side top -fill both -expand 1
176

177 178 179 180 181 182
    bindall <1> {selcanvline %x %y}
    bindall <B1-Motion> {selcanvline %x %y}
    bindall <ButtonRelease-4> "allcanvs yview scroll -5 u"
    bindall <ButtonRelease-5> "allcanvs yview scroll 5 u"
    bindall <2> "allcanvs scan mark 0 %y"
    bindall <B2-Motion> "allcanvs scan dragto 0 %y"
183 184
    bind . <Key-Up> "selnextline -1"
    bind . <Key-Down> "selnextline 1"
185 186 187 188 189 190 191 192 193 194
    bind . p "selnextline -1"
    bind . n "selnextline 1"
    bind . <Key-Prior> "allcanvs yview scroll -1 p"
    bind . <Key-Next> "allcanvs yview scroll 1 p"
    bind . <Key-Delete> "$ctext yview scroll -1 p"
    bind . <Key-BackSpace> "$ctext yview scroll -1 p"
    bind . <Key-space> "$ctext yview scroll 1 p"
    bind . b "$ctext yview scroll -1 p"
    bind . d "$ctext yview scroll 18 u"
    bind . u "$ctext yview scroll -18 u"
195
    bind . Q "set stopped 1; destroy ."
196
    bind $cflist <<ListboxSelect>> listboxsel
197 198
}

199 200 201 202 203 204 205 206 207 208 209 210 211 212
proc allcanvs args {
    global canv canv2 canv3
    eval $canv $args
    eval $canv2 $args
    eval $canv3 $args
}

proc bindall {event action} {
    global canv canv2 canv3
    bind $canv $event $action
    bind $canv2 $event $action
    bind $canv3 $event $action
}

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
proc truncatetofit {str width font} {
    if {[font measure $font $str] <= $width} {
	return $str
    }
    set best 0
    set bad [string length $str]
    set tmp $str
    while {$best < $bad - 1} {
	set try [expr {int(($best + $bad) / 2)}]
	set tmp "[string range $str 0 [expr $try-1]]..."
	if {[font measure $font $tmp] <= $width} {
	    set best $try
	} else {
	    set bad $try
	}
    }
    return $tmp
}

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
proc assigncolor {id} {
    global commitinfo colormap commcolors colors nextcolor
    global colorbycommitter
    global parents nparents children nchildren
    if [info exists colormap($id)] return
    set ncolors [llength $colors]
    if {$colorbycommitter} {
	if {![info exists commitinfo($id)]} {
	    readcommit $id
	}
	set comm [lindex $commitinfo($id) 3]
	if {![info exists commcolors($comm)]} {
	    set commcolors($comm) [lindex $colors $nextcolor]
	    if {[incr nextcolor] >= $ncolors} {
		set nextcolor 0
	    }
	}
	set colormap($id) $commcolors($comm)
    } else {
	if {$nparents($id) == 1 && $nchildren($id) == 1} {
	    set child [lindex $children($id) 0]
	    if {[info exists colormap($child)]
		&& $nparents($child) == 1} {
		set colormap($id) $colormap($child)
		return
	    }
	}
	set badcolors {}
	foreach child $children($id) {
	    if {[info exists colormap($child)]
		&& [lsearch -exact $badcolors $colormap($child)] < 0} {
		lappend badcolors $colormap($child)
	    }
	    if {[info exists parents($child)]} {
		foreach p $parents($child) {
		    if {[info exists colormap($p)]
			&& [lsearch -exact $badcolors $colormap($p)] < 0} {
			lappend badcolors $colormap($p)
		    }
		}
	    }
	}
	if {[llength $badcolors] >= $ncolors} {
	    set badcolors {}
	}
	for {set i 0} {$i <= $ncolors} {incr i} {
	    set c [lindex $colors $nextcolor]
	    if {[incr nextcolor] >= $ncolors} {
		set nextcolor 0
	    }
	    if {[lsearch -exact $badcolors $c]} break
	}
	set colormap($id) $c
    }
}

288 289
proc drawgraph {start} {
    global parents children nparents nchildren commits
290
    global canv canv2 canv3 mainfont namefont canvx0 canvy0 canvy linespc
291
    global datemode cdate
292 293
    global lineid linehtag linentag linedtag commitinfo
    global nextcolor colormap
294 295

    set nextcolor 0
296
    assigncolor $start
297 298 299 300 301
    foreach id $commits {
	set ncleft($id) $nchildren($id)
    }
    set todo [list $start]
    set level 0
302 303
    set y2 $canvy0
    set linestarty(0) $canvy0
304 305 306
    set nullentry -1
    set lineno -1
    while 1 {
307 308 309
	set canvy $y2
	allcanvs conf -scrollregion [list 0 0 0 $canvy]
	update
310 311 312 313
	incr lineno
	set nlines [llength $todo]
	set id [lindex $todo $level]
	set lineid($lineno) $id
P
Paul Mackerras 已提交
314
	set actualparents {}
315
	foreach p $parents($id) {
P
Paul Mackerras 已提交
316 317 318 319 320
	    if {[info exists ncleft($p)]} {
		incr ncleft($p) -1
		lappend actualparents $p
	    }
	}
321
	if {![info exists commitinfo($id)]} {
P
Paul Mackerras 已提交
322
	    readcommit $id
323 324 325 326 327 328 329 330 331 332 333 334 335 336
	}
	set x [expr $canvx0 + $level * $linespc]
	set y2 [expr $canvy + $linespc]
	if {$linestarty($level) < $canvy} {
	    set t [$canv create line $x $linestarty($level) $x $canvy \
		       -width 2 -fill $colormap($id)]
	    $canv lower $t
	    set linestarty($level) $canvy
	}
	set t [$canv create oval [expr $x - 4] [expr $canvy - 4] \
		   [expr $x + 3] [expr $canvy + 3] \
		   -fill blue -outline black -width 1]
	$canv raise $t
	set xt [expr $canvx0 + $nlines * $linespc]
337 338 339
	set headline [lindex $commitinfo($id) 0]
	set name [lindex $commitinfo($id) 1]
	set date [lindex $commitinfo($id) 2]
340 341
	set linehtag($lineno) [$canv create text $xt $canvy -anchor w \
				   -text $headline -font $mainfont ]
342
	set linentag($lineno) [$canv2 create text 3 $canvy -anchor w \
343
				   -text $name -font $namefont]
344
	set linedtag($lineno) [$canv3 create text 3 $canvy -anchor w \
345
				 -text $date -font $mainfont]
P
Paul Mackerras 已提交
346 347
	if {!$datemode && [llength $actualparents] == 1} {
	    set p [lindex $actualparents 0]
348
	    if {$ncleft($p) == 0 && [lsearch -exact $todo $p] < 0} {
349
		assigncolor $p
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
		set todo [lreplace $todo $level $level $p]
		continue
	    }
	}

	set oldtodo $todo
	set oldlevel $level
	set lines {}
	for {set i 0} {$i < $nlines} {incr i} {
	    if {[lindex $todo $i] == {}} continue
	    set oldstarty($i) $linestarty($i)
	    if {$i != $level} {
		lappend lines [list $i [lindex $todo $i]]
	    }
	}
	unset linestarty
	if {$nullentry >= 0} {
	    set todo [lreplace $todo $nullentry $nullentry]
	    if {$nullentry < $level} {
		incr level -1
	    }
	}

	set todo [lreplace $todo $level $level]
	if {$nullentry > $level} {
	    incr nullentry -1
	}
	set i $level
P
Paul Mackerras 已提交
378
	foreach p $actualparents {
379 380
	    set k [lsearch -exact $todo $p]
	    if {$k < 0} {
381
		assigncolor $p
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
		set todo [linsert $todo $i $p]
		if {$nullentry >= $i} {
		    incr nullentry
		}
	    }
	    lappend lines [list $oldlevel $p]
	}

	# choose which one to do next time around
	set todol [llength $todo]
	set level -1
	set latest {}
	for {set k $todol} {[incr k -1] >= 0} {} {
	    set p [lindex $todo $k]
	    if {$p == {}} continue
	    if {$ncleft($p) == 0} {
		if {$datemode} {
		    if {$latest == {} || $cdate($p) > $latest} {
			set level $k
			set latest $cdate($p)
		    }
		} else {
		    set level $k
		    break
		}
	    }
	}
	if {$level < 0} {
	    if {$todo != {}} {
		puts "ERROR: none of the pending commits can be done yet:"
		foreach p $todo {
		    puts "  $p"
		}
	    }
	    break
	}

	# If we are reducing, put in a null entry
	if {$todol < $nlines} {
	    if {$nullentry >= 0} {
		set i $nullentry
		while {$i < $todol
		       && [lindex $oldtodo $i] == [lindex $todo $i]} {
		    incr i
		}
	    } else {
		set i $oldlevel
		if {$level >= $i} {
		    incr i
		}
	    }
	    if {$i >= $todol} {
		set nullentry -1
	    } else {
		set nullentry $i
		set todo [linsert $todo $nullentry {}]
		if {$level >= $i} {
		    incr level
		}
	    }
	} else {
	    set nullentry -1
	}

	foreach l $lines {
	    set i [lindex $l 0]
	    set dst [lindex $l 1]
	    set j [lsearch -exact $todo $dst]
	    if {$i == $j} {
		set linestarty($i) $oldstarty($i)
		continue
	    }
	    set xi [expr {$canvx0 + $i * $linespc}]
	    set xj [expr {$canvx0 + $j * $linespc}]
	    set coords {}
	    if {$oldstarty($i) < $canvy} {
		lappend coords $xi $oldstarty($i)
	    }
	    lappend coords $xi $canvy
	    if {$j < $i - 1} {
		lappend coords [expr $xj + $linespc] $canvy
	    } elseif {$j > $i + 1} {
		lappend coords [expr $xj - $linespc] $canvy
	    }
	    lappend coords $xj $y2
	    set t [$canv create line $coords -width 2 -fill $colormap($dst)]
	    $canv lower $t
	    if {![info exists linestarty($j)]} {
		set linestarty($j) $y2
	    }
	}
    }
}

proc selcanvline {x y} {
    global canv canvy0 ctext linespc selectedline
478
    global lineid linehtag linentag linedtag
479 480 481 482 483 484 485 486
    set ymax [lindex [$canv cget -scrollregion] 3]
    set yfrac [lindex [$canv yview] 0]
    set y [expr {$y + $yfrac * $ymax}]
    set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
    if {$l < 0} {
	set l 0
    }
    if {[info exists selectedline] && $selectedline == $l} return
487 488 489 490
    selectline $l
}

proc selectline {l} {
491 492 493 494
    global canv canv2 canv3 ctext commitinfo selectedline
    global lineid linehtag linentag linedtag
    global canvy canvy0 linespc nparents treepending
    global cflist treediffs currentid
495
    if {![info exists lineid($l)] || ![info exists linehtag($l)]} return
496 497 498 499 500 501 502 503 504 505 506 507
    $canv delete secsel
    set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
	       -tags secsel -fill [$canv cget -selectbackground]]
    $canv lower $t
    $canv2 delete secsel
    set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
	       -tags secsel -fill [$canv2 cget -selectbackground]]
    $canv2 lower $t
    $canv3 delete secsel
    set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
	       -tags secsel -fill [$canv3 cget -selectbackground]]
    $canv3 lower $t
508 509 510 511 512
    set y [expr {$canvy0 + $l * $linespc}]
    set ytop [expr {($y - $linespc / 2.0) / $canvy}]
    set ybot [expr {($y + $linespc / 2.0) / $canvy}]
    set wnow [$canv yview]
    if {$ytop < [lindex $wnow 0]} {
513
	allcanvs yview moveto $ytop
514 515
    } elseif {$ybot > [lindex $wnow 1]} {
	set wh [expr {[lindex $wnow 1] - [lindex $wnow 0]}]
516
	allcanvs yview moveto [expr {$ybot - $wh}]
517 518 519
    }
    set selectedline $l

520
    set id $lineid($l)
521
    $ctext conf -state normal
522 523
    $ctext delete 0.0 end
    set info $commitinfo($id)
524 525
    $ctext insert end "Author: [lindex $info 1]  [lindex $info 2]\n"
    $ctext insert end "Committer: [lindex $info 3]  [lindex $info 4]\n"
526
    $ctext insert end "\n"
527 528 529
    $ctext insert end [lindex $info 5]
    $ctext insert end "\n"
    $ctext tag delete Comments
530 531 532
    $ctext conf -state disabled

    $cflist delete 0 end
533
    set currentid $id
534 535
    if {$nparents($id) == 1} {
	if {![info exists treediffs($id)]} {
536 537 538 539 540
	    if {![info exists treepending]} {
		gettreediffs $id
	    }
	} else {
	    addtocflist $id
541 542
	}
    }
543
}
544

545 546 547 548 549
proc selnextline {dir} {
    global selectedline
    if {![info exists selectedline]} return
    set l [expr $selectedline + $dir]
    selectline $l
550 551
}

552 553 554 555 556 557
proc addtocflist {id} {
    global currentid treediffs cflist treepending
    if {$id != $currentid} {
	gettreediffs $currentid
	return
    }
558
    $cflist insert end "All files"
559 560 561
    foreach f $treediffs($currentid) {
	$cflist insert end $f
    }
562
    getblobdiffs $id
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591
}

proc gettreediffs {id} {
    global treediffs parents treepending
    set treepending $id
    set treediffs($id) {}
    set p [lindex $parents($id) 0]
    if [catch {set gdtf [open "|git-diff-tree -r $p $id" r]}] return
    fconfigure $gdtf -blocking 0
    fileevent $gdtf readable "gettreediffline $gdtf $id"
}

proc gettreediffline {gdtf id} {
    global treediffs treepending
    set n [gets $gdtf line]
    if {$n < 0} {
	if {![eof $gdtf]} return
	close $gdtf
	unset treepending
	addtocflist $id
	return
    }
    set type [lindex $line 1]
    set file [lindex $line 3]
    if {$type == "blob"} {
	lappend treediffs($id) $file
    }
}

592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
proc getblobdiffs {id} {
    global parents diffopts blobdifffd env curdifftag curtagstart
    set p [lindex $parents($id) 0]
    set env(GIT_DIFF_OPTS) $diffopts
    if [catch {set bdf [open "|git-diff-tree -r -p $p $id" r]} err] {
	puts "error getting diffs: $err"
	return
    }
    fconfigure $bdf -blocking 0
    set blobdifffd($id) $bdf
    set curdifftag Comments
    set curtagstart 0.0
    fileevent $bdf readable "getblobdiffline $bdf $id"
}

proc getblobdiffline {bdf id} {
    global currentid blobdifffd ctext curdifftag curtagstart
    set n [gets $bdf line]
    if {$n < 0} {
	if {[eof $bdf]} {
	    close $bdf
	    if {$id == $currentid && $bdf == $blobdifffd($id)} {
		$ctext tag add $curdifftag $curtagstart end
	    }
	}
	return
    }
    if {$id != $currentid || $bdf != $blobdifffd($id)} {
	return
    }
    $ctext conf -state normal
    if {[regexp {^---[ \t]+([^/])+/(.*)} $line match s1 fname]} {
	# start of a new file
	$ctext insert end "\n"
	$ctext tag add $curdifftag $curtagstart end
	set curtagstart [$ctext index "end - 1c"]
	set curdifftag "f:$fname"
	$ctext tag delete $curdifftag
	set l [expr {(78 - [string length $fname]) / 2}]
	set pad [string range "----------------------------------------" 1 $l]
	$ctext insert end "$pad $fname $pad\n" filesep
    } elseif {[string range $line 0 2] == "+++"} {
	# no need to do anything with this
    } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
		   $line match f1l f1c f2l f2c rest]} {
	$ctext insert end "\t" hunksep
	$ctext insert end "    $f1l    " d0 "    $f2l    " d1
	$ctext insert end "    $rest \n" hunksep
    } else {
	set x [string range $line 0 0]
	if {$x == "-" || $x == "+"} {
	    set tag [expr {$x == "+"}]
	    set line [string range $line 1 end]
	    $ctext insert end "$line\n" d$tag
	} elseif {$x == " "} {
	    set line [string range $line 1 end]
	    $ctext insert end "$line\n"
	} else {
	    # Something else we don't recognize
	    if {$curdifftag != "Comments"} {
		$ctext insert end "\n"
		$ctext tag add $curdifftag $curtagstart end
		set curtagstart [$ctext index "end - 1c"]
		set curdifftag Comments
	    }
	    $ctext insert end "$line\n" filesep
	}
    }
    $ctext conf -state disabled
}

proc listboxsel {} {
    global ctext cflist currentid treediffs
    set sel [$cflist curselection]
    if {$sel == {} || [lsearch -exact $sel 0] >= 0} {
	# show everything
	$ctext tag conf Comments -elide 0
	foreach f $treediffs($currentid) {
	    $ctext tag conf "f:$f" -elide 0
	}
    } else {
	# just show selected files
	$ctext tag conf Comments -elide 1
	set i 1
	foreach f $treediffs($currentid) {
	    set elide [expr {[lsearch -exact $sel $i] < 0}]
	    $ctext tag conf "f:$f" -elide $elide
	    incr i
	}
    }
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
}

getcommits $revtreeargs

set linespc [font metrics $mainfont -linespace]
set charspc [font measure $mainfont "m"]

set canvy0 [expr 3 + 0.5 * $linespc]
set canvx0 [expr 3 + 0.5 * $linespc]
set namex [expr 45 * $charspc]
set datex [expr 75 * $charspc]

makewindow

set start {}
foreach id $commits {
    if {$nchildren($id) == 0} {
	set start $id
	break
    }
}
if {$start != {}} {
    drawgraph $start
}