X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=gitk;h=a9d37d9c73e5aae166fc748160df9a5a3ebbad4a;hb=c4c86f07d01bc4a05126b129f644e70dd9e244d0;hp=33abcc4a252ee00dcd437b85c478697266b48f3f;hpb=920b9d9256372d3061584c270795868a4c29d1b4;p=git.git diff --git a/gitk b/gitk index 33abcc4a..a9d37d9c 100755 --- a/gitk +++ b/gitk @@ -1,6 +1,6 @@ #!/bin/sh # Tcl ignores the next line -*- tcl -*- \ -exec wish "$0" -- "${1+$@}" +exec wish "$0" -- "$@" # Copyright (C) 2005 Paul Mackerras. All rights reserved. # This program is free software; it may be used, copied, modified @@ -238,7 +238,8 @@ proc parsecommit {id contents listed olds} { } proc readrefs {} { - global tagids idtags headids idheads + global tagids idtags headids idheads tagcontents + set tags [glob -nocomplain -types f [gitdir]/refs/tags/*] foreach f $tags { catch { @@ -248,7 +249,8 @@ proc readrefs {} { set direct [file tail $f] set tagids($direct) $id lappend idtags($id) $direct - set contents [split [exec git-cat-file tag $id] "\n"] + set tagblob [exec git-cat-file tag $id] + set contents [split $tagblob "\n"] set obj {} set type {} set tag {} @@ -263,6 +265,7 @@ proc readrefs {} { if {$obj != {} && $type == "commit" && $tag != {}} { set tagids($tag) $obj lappend idtags($obj) $tag + set tagcontents($tag) $tagblob } } close $fd @@ -281,6 +284,32 @@ proc readrefs {} { close $fd } } + readotherrefs refs {} {tags heads} +} + +proc readotherrefs {base dname excl} { + global otherrefids idotherrefs + + set git [gitdir] + set files [glob -nocomplain -types f [file join $git $base *]] + foreach f $files { + catch { + set fd [open $f r] + set line [read $fd 40] + if {[regexp {^[0-9a-f]{40}} $line id]} { + set name "$dname[file tail $f]" + set otherrefids($name) $id + lappend idotherrefs($id) $name + } + close $fd + } + } + set dirs [glob -nocomplain -types d [file join $git $base *]] + foreach d $dirs { + set dir [file tail $d] + if {[lsearch -exact $excl $dir] >= 0} continue + readotherrefs [file join $base $dir] "$dname$dir/" {} + } } proc error_popup msg { @@ -305,6 +334,7 @@ proc makewindow {} { menu .bar .bar add cascade -label "File" -menu .bar.file menu .bar.file + .bar.file add command -label "Reread references" -command rereadrefs .bar.file add command -label "Quit" -command doquit menu .bar.help .bar add cascade -label "Help" -menu .bar.help @@ -456,6 +486,8 @@ proc makewindow {} { bindall "allcanvs scan dragto 0 %y" bind . "selnextline -1" bind . "selnextline 1" + bind . "goforw" + bind . "goback" bind . "allcanvs yview scroll -1 pages" bind . "allcanvs yview scroll 1 pages" bindkey "$ctext yview scroll -1 pages" @@ -463,6 +495,12 @@ proc makewindow {} { bindkey "$ctext yview scroll 1 pages" bindkey p "selnextline -1" bindkey n "selnextline 1" + bindkey z "goback" + bindkey x "goforw" + bindkey i "selnextline -1" + bindkey k "selnextline 1" + bindkey j "goback" + bindkey l "goforw" bindkey b "$ctext yview scroll -1 pages" bindkey d "$ctext yview scroll 18 units" bindkey u "$ctext yview scroll -18 units" @@ -528,6 +566,7 @@ proc click {w} { proc savestuff {w} { global canv canv2 canv3 ctext cflist mainfont textfont global stuffsaved findmergefiles gaudydiff maxgraphpct + global maxwidth if {$stuffsaved} return if {![winfo viewable .]} return @@ -538,6 +577,7 @@ proc savestuff {w} { puts $f [list set findmergefiles $findmergefiles] puts $f [list set gaudydiff $gaudydiff] puts $f [list set maxgraphpct $maxgraphpct] + puts $f [list set maxwidth $maxwidth] puts $f "set geometry(width) [winfo width .ctop]" puts $f "set geometry(height) [winfo height .ctop]" puts $f "set geometry(canv1) [expr [winfo width $canv]-2]" @@ -743,13 +783,39 @@ proc bindline {t id} { $canv bind $t "lineclick %x %y $id 1" } +proc drawlines {id xtra} { + global mainline mainlinearrow sidelines lthickness colormap canv + + $canv delete lines.$id + if {[info exists mainline($id)]} { + set t [$canv create line $mainline($id) \ + -width [expr {($xtra + 1) * $lthickness}] \ + -fill $colormap($id) -tags lines.$id \ + -arrow $mainlinearrow($id)] + $canv lower $t + bindline $t $id + } + if {[info exists sidelines($id)]} { + foreach ls $sidelines($id) { + set coords [lindex $ls 0] + set thick [lindex $ls 1] + set arrow [lindex $ls 2] + set t [$canv create line $coords -fill $colormap($id) \ + -width [expr {($thick + $xtra) * $lthickness}] \ + -arrow $arrow -tags lines.$id] + $canv lower $t + bindline $t $id + } + } +} + # level here is an index in displist proc drawcommitline {level} { global parents children nparents displist global canv canv2 canv3 mainfont namefont canvy linespc global lineid linehtag linentag linedtag commitinfo global colormap numcommits currentparents dupparents - global idtags idline idheads + global idtags idline idheads idotherrefs global lineno lthickness mainline mainlinearrow sidelines global commitlisted rowtextx idpos lastuse displist global oldnlines olddlevel olddisplist @@ -791,23 +857,8 @@ proc drawcommitline {level} { if {$mainlinearrow($id) ne "none"} { set mainline($id) [trimdiagstart $mainline($id)] } - set t [$canv create line $mainline($id) \ - -width $lthickness -fill $colormap($id) \ - -arrow $mainlinearrow($id)] - $canv lower $t - bindline $t $id - } - if {[info exists sidelines($id)]} { - foreach ls $sidelines($id) { - set coords [lindex $ls 0] - set thick [lindex $ls 1] - set arrow [lindex $ls 2] - set t [$canv create line $coords -fill $colormap($id) \ - -width [expr {$thick * $lthickness}] -arrow $arrow] - $canv lower $t - bindline $t $id - } } + drawlines $id 0 set orad [expr {$linespc / 3}] set t [$canv create oval [expr $x - $orad] [expr $y1 - $orad] \ [expr $x + $orad - 1] [expr $y1 + $orad - 1] \ @@ -820,7 +871,8 @@ proc drawcommitline {level} { } set rowtextx($lineno) $xt set idpos($id) [list $x $xt $y1] - if {[info exists idtags($id)] || [info exists idheads($id)]} { + if {[info exists idtags($id)] || [info exists idheads($id)] + || [info exists idotherrefs($id)]} { set xt [drawtags $id $x $xt $y1] } set headline [lindex $commitinfo($id) 0] @@ -840,18 +892,23 @@ proc drawcommitline {level} { } proc drawtags {id x xt y1} { - global idtags idheads + global idtags idheads idotherrefs global linespc lthickness - global canv mainfont + global canv mainfont idline rowtextx set marks {} set ntags 0 + set nheads 0 if {[info exists idtags($id)]} { set marks $idtags($id) set ntags [llength $marks] } if {[info exists idheads($id)]} { set marks [concat $marks $idheads($id)] + set nheads [llength $idheads($id)] + } + if {[info exists idotherrefs($id)]} { + set marks [concat $marks $idotherrefs($id)] } if {$marks eq {}} { return $xt @@ -876,17 +933,27 @@ proc drawtags {id x xt y1} { set xr [expr $x + $delta + $wid + $lthickness] if {[incr ntags -1] >= 0} { # draw a tag - $canv create polygon $x [expr $yt + $delta] $xl $yt\ - $xr $yt $xr $yb $xl $yb $x [expr $yb - $delta] \ - -width 1 -outline black -fill yellow -tags tag.$id + set t [$canv create polygon $x [expr $yt + $delta] $xl $yt \ + $xr $yt $xr $yb $xl $yb $x [expr $yb - $delta] \ + -width 1 -outline black -fill yellow -tags tag.$id] + $canv bind $t <1> [list showtag $tag 1] + set rowtextx($idline($id)) [expr {$xr + $linespc}] } else { - # draw a head + # draw a head or other ref + if {[incr nheads -1] >= 0} { + set col green + } else { + set col "#ddddff" + } set xl [expr $xl - $delta/2] $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \ - -width 1 -outline black -fill green -tags tag.$id + -width 1 -outline black -fill $col -tags tag.$id + } + set t [$canv create text $xl $y1 -anchor w -text $tag \ + -font $mainfont -tags tag.$id] + if {$ntags >= 0} { + $canv bind $t <1> [list showtag $tag 1] } - $canv create text $xl $y1 -anchor w -text $tag \ - -font $mainfont -tags tag.$id } return $xt } @@ -1019,6 +1086,7 @@ proc drawslants {id needonscreen nohs} { } if {$onscreen($id) == 0} { lappend displist $id + set onscreen($id) 1 } # remove the null entry if present @@ -1186,15 +1254,10 @@ proc drawslants {id needonscreen nohs} { set j [lsearch -exact $displist $id] } if {$j != $i || $xspc1($lineno) != $xspc1($lj) - || ($olddlevel <= $i && $i <= $dlevel) - || ($dlevel <= $i && $i <= $olddlevel)} { + || ($olddlevel < $i && $i < $dlevel) + || ($dlevel < $i && $i < $olddlevel)} { set xj [xcoord $j $dlevel $lj] - set dx [expr {abs($xi - $xj)}] - set yb $y2 - if {0 && $dx < $linespc} { - set yb [expr {$y1 + $dx}] - } - lappend mainline($id) $xi $y1 $xj $yb + lappend mainline($id) $xi $y1 $xj $y2 } } } @@ -1460,7 +1523,7 @@ proc drawrest {} { global phase stopped redisplaying selectedline global datemode todo displayorder global numcommits ncmupdate - global nextupdate startmsecs idline + global nextupdate startmsecs set level [decidenext] if {$level >= 0} { @@ -1982,14 +2045,40 @@ proc commit_descriptor {p} { return "$p ($l)" } +# append some text to the ctext widget, and make any SHA1 ID +# that we know about be a clickable link. +proc appendwithlinks {text} { + global ctext idline linknum + + set start [$ctext index "end - 1c"] + $ctext insert end $text + $ctext insert end "\n" + set links [regexp -indices -all -inline {[0-9a-f]{40}} $text] + foreach l $links { + set s [lindex $l 0] + set e [lindex $l 1] + set linkid [string range $text $s $e] + if {![info exists idline($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 $idline($linkid) 1] + incr linknum + } + $ctext tag conf link -foreground blue -underline 1 + $ctext tag bind link { %W configure -cursor hand2 } + $ctext tag bind link { %W configure -cursor $curtextcursor } +} + proc selectline {l isnew} { global canv canv2 canv3 ctext commitinfo selectedline global lineid linehtag linentag linedtag global canvy0 linespc parents nparents children global cflist currentid sha1entry - global commentend idtags idline + global commentend idtags idline linknum $canv delete hover + normalline if {![info exists lineid($l)] || ![info exists linehtag($l)]} return $canv delete secsel set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \ @@ -2053,6 +2142,7 @@ proc selectline {l isnew} { $ctext conf -state normal $ctext delete 0.0 end + set linknum 0 $ctext mark set fmark.0 0.0 $ctext mark gravity fmark.0 left set info $commitinfo($id) @@ -2066,7 +2156,6 @@ proc selectline {l isnew} { $ctext insert end "\n" } - set commentstart [$ctext index "end - 1c"] set comment {} if {[info exists parents($id)]} { foreach p $parents($id) { @@ -2080,26 +2169,9 @@ proc selectline {l isnew} { } append comment "\n" append comment [lindex $info 5] - $ctext insert end $comment - $ctext insert end "\n" # make anything that looks like a SHA1 ID be a clickable link - set links [regexp -indices -all -inline {[0-9a-f]{40}} $comment] - set i 0 - foreach l $links { - set s [lindex $l 0] - set e [lindex $l 1] - set linkid [string range $comment $s $e] - if {![info exists idline($linkid)]} continue - incr e - $ctext tag add link "$commentstart + $s c" "$commentstart + $e c" - $ctext tag add link$i "$commentstart + $s c" "$commentstart + $e c" - $ctext tag bind link$i <1> [list selectline $idline($linkid) 1] - incr i - } - $ctext tag conf link -foreground blue -underline 1 - $ctext tag bind link { %W configure -cursor hand2 } - $ctext tag bind link { %W configure -cursor $curtextcursor } + appendwithlinks $comment $ctext tag delete Comments $ctext tag remove found 1.0 end @@ -2734,7 +2806,7 @@ proc gettreediffs {ids} { set treediff {} set id [lindex $ids 0] set p [lindex $ids 1] - if [catch {set gdtf [open "|git-diff-tree -r $p $id" r]}] return + if [catch {set gdtf [open "|git-diff-tree -r $id" r]}] return fconfigure $gdtf -blocking 0 fileevent $gdtf readable [list gettreediffline $gdtf $ids] } @@ -2770,7 +2842,7 @@ proc getblobdiffs {ids} { set id [lindex $ids 0] set p [lindex $ids 1] set env(GIT_DIFF_OPTS) $diffopts - set cmd [list | git-diff-tree -r -p -C $p $id] + set cmd [list | git-diff-tree -r -p -C $id] if {[catch {set bdf [open $cmd r]} err]} { puts "error getting diffs: $err" return @@ -3075,15 +3147,102 @@ proc linehover {} { $canv raise $t } +proc clickisonarrow {id y} { + global mainline mainlinearrow sidelines lthickness + + set thresh [expr {2 * $lthickness + 6}] + if {[info exists mainline($id)]} { + if {$mainlinearrow($id) ne "none"} { + if {abs([lindex $mainline($id) 1] - $y) < $thresh} { + return "up" + } + } + } + if {[info exists sidelines($id)]} { + foreach ls $sidelines($id) { + set coords [lindex $ls 0] + set arrow [lindex $ls 2] + if {$arrow eq "first" || $arrow eq "both"} { + if {abs([lindex $coords 1] - $y) < $thresh} { + return "up" + } + } + if {$arrow eq "last" || $arrow eq "both"} { + if {abs([lindex $coords end] - $y) < $thresh} { + return "down" + } + } + } + } + return {} +} + +proc arrowjump {id dirn y} { + global mainline sidelines canv + + set yt {} + if {$dirn eq "down"} { + if {[info exists mainline($id)]} { + set y1 [lindex $mainline($id) 1] + if {$y1 > $y} { + set yt $y1 + } + } + if {[info exists sidelines($id)]} { + foreach ls $sidelines($id) { + set y1 [lindex $ls 0 1] + if {$y1 > $y && ($yt eq {} || $y1 < $yt)} { + set yt $y1 + } + } + } + } else { + if {[info exists sidelines($id)]} { + foreach ls $sidelines($id) { + set y1 [lindex $ls 0 end] + if {$y1 < $y && ($yt eq {} || $y1 > $yt)} { + set yt $y1 + } + } + } + } + if {$yt eq {}} return + set ymax [lindex [$canv cget -scrollregion] 3] + if {$ymax eq {} || $ymax <= 0} return + set view [$canv yview] + set yspan [expr {[lindex $view 1] - [lindex $view 0]}] + set yfrac [expr {$yt / $ymax - $yspan / 2}] + if {$yfrac < 0} { + set yfrac 0 + } + $canv yview moveto $yfrac +} + proc lineclick {x y id isnew} { - global ctext commitinfo children cflist canv + global ctext commitinfo children cflist canv thickerline unmarkmatches unselectline + normalline + $canv delete hover + # draw this line thicker than normal + drawlines $id 1 + set thickerline $id if {$isnew} { - addtohistory [list lineclick $x $x $id 0] + set ymax [lindex [$canv cget -scrollregion] 3] + if {$ymax eq {}} return + set yfrac [lindex [$canv yview] 0] + set y [expr {$y + $yfrac * $ymax}] + } + set dirn [clickisonarrow $id $y] + if {$dirn ne {}} { + arrowjump $id $dirn $y + return + } + + if {$isnew} { + addtohistory [list lineclick $x $y $id 0] } - $canv delete hover # fill the details pane with info about this line $ctext conf -state normal $ctext delete 0.0 end @@ -3116,6 +3275,14 @@ proc lineclick {x y id isnew} { $cflist delete 0 end } +proc normalline {} { + global thickerline + if {[info exists thickerline]} { + drawlines $thickerline 0 + unset thickerline + } +} + proc selbyid {id} { global idline if {[info exists idline($id)]} { @@ -3309,7 +3476,6 @@ proc mktag {} { proc domktag {} { global mktagtop env tagids idtags - global idpos idline linehtag canv selectedline set id [$mktagtop.sha1 get] set tag [$mktagtop.tag get] @@ -3334,6 +3500,13 @@ proc domktag {} { set tagids($tag) $id lappend idtags($id) $tag + redrawtags $id +} + +proc redrawtags {id} { + global canv linehtag idline idpos selectedline + + if {![info exists idline($id)]} return $canv delete tag.$id set xt [eval drawtags $id $idpos($id)] $canv coords $linehtag($idline($id)) $xt [lindex $idpos($id) 2] @@ -3409,6 +3582,68 @@ proc wrcomcan {} { unset wrcomtop } +proc listrefs {id} { + global idtags idheads idotherrefs + + set x {} + if {[info exists idtags($id)]} { + set x $idtags($id) + } + set y {} + if {[info exists idheads($id)]} { + set y $idheads($id) + } + set z {} + if {[info exists idotherrefs($id)]} { + set z $idotherrefs($id) + } + return [list $x $y $z] +} + +proc rereadrefs {} { + global idtags idheads idotherrefs + global tagids headids otherrefids + + set refids [concat [array names idtags] \ + [array names idheads] [array names idotherrefs]] + foreach id $refids { + if {![info exists ref($id)]} { + set ref($id) [listrefs $id] + } + } + foreach v {tagids idtags headids idheads otherrefids idotherrefs} { + catch {unset $v} + } + readrefs + set refids [lsort -unique [concat $refids [array names idtags] \ + [array names idheads] [array names idotherrefs]]] + foreach id $refids { + set v [listrefs $id] + if {![info exists ref($id)] || $ref($id) != $v} { + redrawtags $id + } + } +} + +proc showtag {tag isnew} { + global ctext cflist tagcontents tagids linknum + + if {$isnew} { + addtohistory [list showtag $tag 0] + } + $ctext conf -state normal + $ctext delete 0.0 end + set linknum 0 + if {[info exists tagcontents($tag)]} { + set text $tagcontents($tag) + } else { + set text "Tag: $tag\nId: $tagids($tag)" + } + appendwithlinks $text + $ctext conf -state disabled + $cflist delete 0 end +} + proc doquit {} { global stopped set stopped 100