diff options
Diffstat (limited to 'gitk-git/gitk')
| -rw-r--r-- | gitk-git/gitk | 204 |
1 files changed, 147 insertions, 57 deletions
diff --git a/gitk-git/gitk b/gitk-git/gitk index fddcb45817..2eaa2ae7d6 100644 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -22,11 +22,11 @@ proc gitdir {} { # run before X event handlers, so reading from a fast source can # make the GUI completely unresponsive. proc run args { - global isonrunq runq + global isonrunq runq currunq set script $args if {[info exists isonrunq($script)]} return - if {$runq eq {}} { + if {$runq eq {} && ![info exists currunq]} { after idle dorunq } lappend runq [list {} $script] @@ -38,10 +38,10 @@ proc filerun {fd script} { } proc filereadable {fd script} { - global runq + global runq currunq fileevent $fd readable {} - if {$runq eq {}} { + if {$runq eq {} && ![info exists currunq]} { after idle dorunq } lappend runq [list $fd $script] @@ -60,17 +60,19 @@ proc nukefile {fd} { } proc dorunq {} { - global isonrunq runq + global isonrunq runq currunq set tstart [clock clicks -milliseconds] set t0 $tstart while {[llength $runq] > 0} { set fd [lindex $runq 0 0] set script [lindex $runq 0 1] + set currunq [lindex $runq 0] + set runq [lrange $runq 1 end] set repeat [eval $script] + unset currunq set t1 [clock clicks -milliseconds] set t [expr {$t1 - $t0}] - set runq [lrange $runq 1 end] if {$repeat ne {} && $repeat} { if {$fd eq {} || $repeat == 2} { # script returns 1 if it wants to be readded @@ -90,6 +92,15 @@ proc dorunq {} { } } +proc reg_instance {fd} { + global commfd leftover loginstance + + set i [incr loginstance] + set commfd($i) $fd + set leftover($i) {} + return $i +} + proc unmerged_files {files} { global nr_unmerged @@ -294,11 +305,11 @@ proc parseviewrevs {view revs} { # Start off a git log process and arrange to read its output proc start_rev_list {view} { global startmsecs commitidx viewcomplete curview - global commfd leftover tclencoding + global tclencoding global viewargs viewargscmd viewfiles vfilelimit global showlocalchanges commitinterest - global viewactive loginstance viewinstances vmergeonly - global pending_select mainheadid + global viewactive viewinstances vmergeonly + global mainheadid global vcanopt vflags vrevs vorigargs set startmsecs [clock clicks -milliseconds] @@ -354,10 +365,8 @@ proc start_rev_list {view} { error_popup "[mc "Error executing git log:"] $err" return 0 } - set i [incr loginstance] + set i [reg_instance $fd] set viewinstances($view) [list $i] - set commfd($i) $fd - set leftover($i) {} if {$showlocalchanges && $mainheadid ne {}} { lappend commitinterest($mainheadid) {dodiffindex} } @@ -367,36 +376,65 @@ proc start_rev_list {view} { } filerun $fd [list getcommitlines $fd $i $view 0] nowbusy $view [mc "Reading"] - if {$view == $curview} { - set pending_select $mainheadid - } set viewcomplete($view) 0 set viewactive($view) 1 return 1 } -proc stop_rev_list {view} { - global commfd viewinstances leftover +proc stop_instance {inst} { + global commfd leftover - foreach inst $viewinstances($view) { - set fd $commfd($inst) - catch { - set pid [pid $fd] + set fd $commfd($inst) + catch { + set pid [pid $fd] + + if {$::tcl_platform(platform) eq {windows}} { + exec kill -f $pid + } else { exec kill $pid } - catch {close $fd} - nukefile $fd - unset commfd($inst) - unset leftover($inst) + } + catch {close $fd} + nukefile $fd + unset commfd($inst) + unset leftover($inst) +} + +proc stop_backends {} { + global commfd + + foreach inst [array names commfd] { + stop_instance $inst + } +} + +proc stop_rev_list {view} { + global viewinstances + + foreach inst $viewinstances($view) { + stop_instance $inst } set viewinstances($view) {} } -proc getcommits {} { +proc reset_pending_select {selid} { + global pending_select mainheadid selectheadid + + if {$selid ne {}} { + set pending_select $selid + } elseif {$selectheadid ne {}} { + set pending_select $selectheadid + } else { + set pending_select $mainheadid + } +} + +proc getcommits {selid} { global canv curview need_redisplay viewactive initlayout if {[start_rev_list $curview]} { + reset_pending_select $selid show_status [mc "Reading commits..."] set need_redisplay 1 } else { @@ -406,8 +444,8 @@ proc getcommits {} { proc updatecommits {} { global curview vcanopt vorigargs vfilelimit viewinstances - global viewactive viewcomplete loginstance tclencoding - global startmsecs commfd showneartags showlocalchanges leftover + global viewactive viewcomplete tclencoding + global startmsecs showneartags showlocalchanges global mainheadid pending_select global isworktree global varcid vposids vnegids vflags vrevs @@ -468,10 +506,8 @@ proc updatecommits {} { if {$viewactive($view) == 0} { set startmsecs [clock clicks -milliseconds] } - set i [incr loginstance] + set i [reg_instance $fd] lappend viewinstances($view) $i - set commfd($i) $fd - set leftover($i) {} fconfigure $fd -blocking 0 -translation lf -eofchar {} if {$tclencoding != {}} { fconfigure $fd -encoding $tclencoding @@ -479,7 +515,7 @@ proc updatecommits {} { filerun $fd [list getcommitlines $fd $i $view 1] incr viewactive($view) set viewcomplete($view) 0 - set pending_select $mainheadid + reset_pending_select {} nowbusy $view "Reading" if {$showneartags} { getallcommits @@ -491,6 +527,11 @@ proc reloadcommits {} { global showneartags treediffs commitinterest cached_commitrow global targetid + set selid {} + if {$selectedline ne {}} { + set selid $currentid + } + if {!$viewcomplete($curview)} { stop_rev_list $curview } @@ -509,7 +550,7 @@ proc reloadcommits {} { catch {unset cached_commitrow} catch {unset targetid} setcanvscroll - getcommits + getcommits $selid return 0 } @@ -1469,8 +1510,15 @@ proc chewcommits {} { global numcommits startmsecs if {[info exists pending_select]} { - set row [first_real_row] - selectline $row 1 + update + reset_pending_select {} + + if {[commitinview $pending_select $curview]} { + selectline [rowofcommit $pending_select] 1 + } else { + set row [first_real_row] + selectline $row 1 + } } if {$commitidx($curview) > 0} { #set ms [expr {[clock clicks -milliseconds] - $startmsecs}] @@ -1563,6 +1611,7 @@ proc getcommit {id} { proc readrefs {} { global tagids idtags headids idheads tagobjid global otherrefids idotherrefs mainhead mainheadid + global selecthead selectheadid foreach v {tagids idtags headids idheads otherrefids idotherrefs} { catch {unset $v} @@ -1609,6 +1658,12 @@ proc readrefs {} { set mainhead [string range $thehead 11 end] } } + set selectheadid {} + if {$selecthead ne {}} { + catch { + set selectheadid [exec git rev-parse --verify $selecthead] + } + } } # skip over fake commits @@ -2103,6 +2158,7 @@ proc makewindow {} { bind . <$M1B-minus> {incrfont -1} bind . <$M1B-KP_Subtract> {incrfont -1} wm protocol . WM_DELETE_WINDOW doquit + bind . <Destroy> {stop_backends} bind . <Button-1> "click %W" bind $fstring <Key-Return> {dofind 1 1} bind $sha1entry <Key-Return> gotocommit @@ -2158,6 +2214,8 @@ proc makewindow {} { -command {flist_hl 1} $flist_menu add command -label [mc "External diff"] \ -command {external_diff} + $flist_menu add command -label [mc "Blame parent commit"] \ + -command {external_blame 1} } # Windows sends all mouse wheel events to the current focused window, not @@ -2965,6 +3023,27 @@ proc external_diff {} { } } +proc external_blame {parent_idx} { + global flist_menu_file + global nullid nullid2 + global parentlist selectedline currentid + + if {$parent_idx > 0} { + set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]] + } else { + set base_commit $currentid + } + + if {$base_commit eq {} || $base_commit eq $nullid || $base_commit eq $nullid2} { + error_popup [mc "No such commit"] + return + } + + if {[catch {exec git gui blame $base_commit $flist_menu_file &} err]} { + error_popup [mc "git gui blame: command failed: $err"] + } +} + # delete $dir when we see eof on $f (presumably because the child has exited) proc delete_at_eof {f dir} { while {[gets $f line] >= 0} {} @@ -3300,10 +3379,7 @@ proc showview {n} { run refill_reflist if {![info exists viewcomplete($n)]} { - if {$selid ne {}} { - set pending_select $selid - } - getcommits + getcommits $selid return } @@ -3337,18 +3413,18 @@ proc showview {n} { drawvisible if {$row ne {}} { selectline $row 0 - } elseif {$mainheadid ne {} && [commitinview $mainheadid $curview]} { - selectline [rowofcommit $mainheadid] 1 } elseif {!$viewcomplete($n)} { - if {$selid ne {}} { - set pending_select $selid - } else { - set pending_select $mainheadid - } + reset_pending_select $selid } else { - set row [first_real_row] - if {$row < $numcommits} { - selectline $row 0 + reset_pending_select {} + + if {[commitinview $pending_select $curview]} { + selectline [rowofcommit $pending_select] 1 + } else { + set row [first_real_row] + if {$row < $numcommits} { + selectline $row 0 + } } } if {!$viewcomplete($n)} { @@ -4011,6 +4087,7 @@ proc layoutmore {} { } if {[info exists pending_select] && [commitinview $pending_select $curview]} { + update selectline [rowofcommit $pending_select] 1 } drawvisible @@ -4048,10 +4125,11 @@ proc dodiffindex {} { incr lserial set fd [open "|git diff-index --cached HEAD" r] fconfigure $fd -blocking 0 - filerun $fd [list readdiffindex $fd $lserial] + set i [reg_instance $fd] + filerun $fd [list readdiffindex $fd $lserial $i] } -proc readdiffindex {fd serial} { +proc readdiffindex {fd serial inst} { global mainheadid nullid nullid2 curview commitinfo commitdata lserial set isdiff 1 @@ -4062,7 +4140,7 @@ proc readdiffindex {fd serial} { set isdiff 0 } # we only need to see one line and we don't really care what it says... - close $fd + stop_instance $inst if {$serial != $lserial} { return 0 @@ -4071,7 +4149,8 @@ proc readdiffindex {fd serial} { # now see if there are any local changes not checked in to the index set fd [open "|git diff-files" r] fconfigure $fd -blocking 0 - filerun $fd [list readdifffiles $fd $serial] + set i [reg_instance $fd] + filerun $fd [list readdifffiles $fd $serial $i] if {$isdiff && ![commitinview $nullid2 $curview]} { # add the line for the changes in the index to the graph @@ -4088,7 +4167,7 @@ proc readdiffindex {fd serial} { return 0 } -proc readdifffiles {fd serial} { +proc readdifffiles {fd serial inst} { global mainheadid nullid nullid2 curview global commitinfo commitdata lserial @@ -4100,7 +4179,7 @@ proc readdifffiles {fd serial} { set isdiff 0 } # we only need to see one line and we don't really care what it says... - close $fd + stop_instance $inst if {$serial != $lserial} { return 0 @@ -6430,9 +6509,10 @@ proc diffcmd {ids flags} { proc gettreediffs {ids} { global treediff treepending + if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return + set treepending $ids set treediff {} - if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return fconfigure $gdtf -blocking 0 filerun $gdtf [list gettreediffline $gdtf $ids] } @@ -9817,6 +9897,9 @@ if {![file isdirectory $gitdir]} { exit 1 } +set selecthead {} +set selectheadid {} + set revtreeargs {} set cmdline_files {} set i 0 @@ -9828,6 +9911,9 @@ foreach arg $argv { set cmdline_files [lrange $argv [expr {$i + 1}] end] break } + "--select-commit=*" { + set selecthead [string range $arg 16 end] + } "--argscmd=*" { set revtreeargscmd [string range $arg 10 end] } @@ -9838,6 +9924,10 @@ foreach arg $argv { incr i } +if {$selecthead eq "HEAD"} { + set selecthead {} +} + if {$i >= [llength $argv] && $revtreeargs ne {}} { # no -- on command line, but some arguments (other than --argscmd) if {[catch { @@ -9945,4 +10035,4 @@ if {[info exists permviews]} { addviewmenu $n } } -getcommits +getcommits {} |
