From: Paul Mackerras Date: Sun, 9 Nov 2008 11:05:50 +0000 (+1100) Subject: Merge branch 'dev' X-Git-Tag: v1.6.1-rc1~49^2~4 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/dbc4941facba9f43f1b95af254d667425d383d45?hp=48a81b7cda1e58d8cc4d9bcadce76bbf1680ab7d Merge branch 'dev' --- diff --git a/gitk b/gitk index bea5026f62..18d153e569 100755 --- a/gitk +++ b/gitk @@ -1746,22 +1746,24 @@ proc show_error {w top msg} { pack $w.ok -side bottom -fill x bind $top "grab $top; focus $top" bind $top "destroy $top" + bind $top "destroy $top" + bind $top "destroy $top" tkwait window $top } -proc error_popup msg { +proc error_popup {msg {owner .}} { set w .error toplevel $w - wm transient $w . + wm transient $w $owner show_error $w $w $msg } -proc confirm_popup msg { +proc confirm_popup {msg {owner .}} { global confirm_ok set confirm_ok 0 set w .confirm toplevel $w - wm transient $w . + wm transient $w $owner message $w.m -text $msg -justify center -aspect 400 pack $w.m -side top -fill x -padx 20 -pady 20 button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w" @@ -1769,6 +1771,9 @@ proc confirm_popup msg { button $w.cancel -text [mc Cancel] -command "destroy $w" pack $w.cancel -side right -fill x bind $w "grab $w; focus $w" + bind $w "set confirm_ok 1; destroy $w" + bind $w "set confirm_ok 1; destroy $w" + bind $w "destroy $w" tkwait window $w return $confirm_ok } @@ -2541,6 +2546,7 @@ proc about {} { } toplevel $w wm title $w [mc "About gitk"] + wm transient $w . message $w.m -text [mc " Gitk - a commit viewer for git @@ -2569,6 +2575,7 @@ proc keys {} { } toplevel $w wm title $w [mc "Gitk key bindings"] + wm transient $w . message $w.m -text " [mc "Gitk key bindings:"] @@ -2611,6 +2618,7 @@ proc keys {} { -justify left -bg white -border 2 -relief groove pack $w.m -side top -fill both -padx 2 -pady 2 button $w.ok -text [mc "Close"] -command "destroy $w" -default active + bind $w [list destroy $w] pack $w.ok -side bottom bind $w "focus $w.ok" bind $w "destroy $w" @@ -3517,8 +3525,8 @@ proc shellsplit {str} { # Code to implement multiple views proc newview {ishighlight} { - global nextviewnum newviewname newviewperm newishighlight - global newviewargs revtreeargs viewargscmd newviewargscmd curview + global nextviewnum newviewname newishighlight + global revtreeargs viewargscmd newviewopts curview set newishighlight $ishighlight set top .gitkview @@ -3527,58 +3535,173 @@ proc newview {ishighlight} { return } set newviewname($nextviewnum) "[mc "View"] $nextviewnum" - set newviewperm($nextviewnum) 0 - set newviewargs($nextviewnum) [shellarglist $revtreeargs] - set newviewargscmd($nextviewnum) $viewargscmd($curview) + set newviewopts($nextviewnum,perm) 0 + set newviewopts($nextviewnum,cmd) $viewargscmd($curview) + decode_view_opts $nextviewnum $revtreeargs vieweditor $top $nextviewnum [mc "Gitk view definition"] } +set known_view_options { + {perm b . {} {mc "Remember this view"}} + {args t50= + {} {mc "Commits to include (arguments to git log):"}} + {all b * "--all" {mc "Use all refs"}} + {dorder b . {"--date-order" "-d"} {mc "Strictly sort by date"}} + {lright b . "--left-right" {mc "Mark branch sides"}} + {since t15 + {"--since=*" "--after=*"} {mc "Since date:"}} + {until t15 . {"--until=*" "--before=*"} {mc "Until date:"}} + {limit t10 + "--max-count=*" {mc "Max count:"}} + {skip t10 . "--skip=*" {mc "Skip:"}} + {first b . "--first-parent" {mc "Limit to first parent"}} + {cmd t50= + {} {mc "Command to generate more commits to include:"}} + } + +proc encode_view_opts {n} { + global known_view_options newviewopts + + set rargs [list] + foreach opt $known_view_options { + set patterns [lindex $opt 3] + if {$patterns eq {}} continue + set pattern [lindex $patterns 0] + + set val $newviewopts($n,[lindex $opt 0]) + + if {[lindex $opt 1] eq "b"} { + if {$val} { + lappend rargs $pattern + } + } else { + set val [string trim $val] + if {$val ne {}} { + set pfix [string range $pattern 0 end-1] + lappend rargs $pfix$val + } + } + } + return [concat $rargs [shellsplit $newviewopts($n,args)]] +} + +proc decode_view_opts {n view_args} { + global known_view_options newviewopts + + foreach opt $known_view_options { + if {[lindex $opt 1] eq "b"} { + set val 0 + } else { + set val {} + } + set newviewopts($n,[lindex $opt 0]) $val + } + set oargs [list] + foreach arg $view_args { + if {[regexp -- {^-([0-9]+)$} $arg arg cnt] + && ![info exists found(limit)]} { + set newviewopts($n,limit) $cnt + set found(limit) 1 + continue + } + catch { unset val } + foreach opt $known_view_options { + set id [lindex $opt 0] + if {[info exists found($id)]} continue + foreach pattern [lindex $opt 3] { + if {![string match $pattern $arg]} continue + if {[lindex $opt 1] ne "b"} { + set size [string length $pattern] + set val [string range $arg [expr {$size-1}] end] + } else { + set val 1 + } + set newviewopts($n,$id) $val + set found($id) 1 + break + } + if {[info exists val]} break + } + if {[info exists val]} continue + lappend oargs $arg + } + set newviewopts($n,args) [shellarglist $oargs] +} + proc editview {} { global curview - global viewname viewperm newviewname newviewperm - global viewargs newviewargs viewargscmd newviewargscmd + global viewname viewperm newviewname newviewopts + global viewargs viewargscmd set top .gitkvedit-$curview if {[winfo exists $top]} { raise $top return } - set newviewname($curview) $viewname($curview) - set newviewperm($curview) $viewperm($curview) - set newviewargs($curview) [shellarglist $viewargs($curview)] - set newviewargscmd($curview) $viewargscmd($curview) + set newviewname($curview) $viewname($curview) + set newviewopts($curview,perm) $viewperm($curview) + set newviewopts($curview,cmd) $viewargscmd($curview) + decode_view_opts $curview $viewargs($curview) vieweditor $top $curview "Gitk: edit view $viewname($curview)" } proc vieweditor {top n title} { - global newviewname newviewperm viewfiles bgcolor + global newviewname newviewopts viewfiles bgcolor + global known_view_options toplevel $top wm title $top $title + wm transient $top . + + # View name + frame $top.nfr label $top.nl -text [mc "Name"] entry $top.name -width 20 -textvariable newviewname($n) - grid $top.nl $top.name -sticky w -pady 5 - checkbutton $top.perm -text [mc "Remember this view"] \ - -variable newviewperm($n) - grid $top.perm - -pady 5 -sticky w - message $top.al -aspect 1000 \ - -text [mc "Commits to include (arguments to git log):"] - grid $top.al - -sticky w -pady 5 - entry $top.args -width 50 -textvariable newviewargs($n) \ - -background $bgcolor - grid $top.args - -sticky ew -padx 5 - - message $top.ac -aspect 1000 \ - -text [mc "Command to generate more commits to include:"] - grid $top.ac - -sticky w -pady 5 - entry $top.argscmd -width 50 -textvariable newviewargscmd($n) \ - -background white - grid $top.argscmd - -sticky ew -padx 5 - - message $top.l -aspect 1000 \ + pack $top.nfr -in $top -fill x -pady 5 -padx 3 + pack $top.nl -in $top.nfr -side left -padx {0 30} + pack $top.name -in $top.nfr -side left + + # View options + set cframe $top.nfr + set cexpand 0 + set cnt 0 + foreach opt $known_view_options { + set id [lindex $opt 0] + set type [lindex $opt 1] + set flags [lindex $opt 2] + set title [eval [lindex $opt 4]] + set lxpad 0 + + if {$flags eq "+" || $flags eq "*"} { + set cframe $top.fr$cnt + incr cnt + frame $cframe + pack $cframe -in $top -fill x -pady 3 -padx 3 + set cexpand [expr {$flags eq "*"}] + } else { + set lxpad 5 + } + + if {$type eq "b"} { + checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id) + pack $cframe.c_$id -in $cframe -side left \ + -padx [list $lxpad 0] -expand $cexpand -anchor w + } elseif {[regexp {^t(\d+)$} $type type sz]} { + message $cframe.l_$id -aspect 1500 -text $title + entry $cframe.e_$id -width $sz -background $bgcolor \ + -textvariable newviewopts($n,$id) + pack $cframe.l_$id -in $cframe -side left -padx [list $lxpad 0] + pack $cframe.e_$id -in $cframe -side left -expand 1 -fill x + } elseif {[regexp {^t(\d+)=$} $type type sz]} { + message $cframe.l_$id -aspect 1500 -text $title + entry $cframe.e_$id -width $sz -background $bgcolor \ + -textvariable newviewopts($n,$id) + pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w + pack $cframe.e_$id -in $cframe -side top -fill x + } + } + + # Path list + message $top.l -aspect 1500 \ -text [mc "Enter files and directories to include, one per line:"] - grid $top.l - -sticky w - text $top.t -width 40 -height 10 -background $bgcolor -font uifont + pack $top.l -in $top -side top -pady [list 7 0] -anchor w -padx 3 + text $top.t -width 40 -height 5 -background $bgcolor -font uifont if {[info exists viewfiles($n)]} { foreach f $viewfiles($n) { $top.t insert end $f @@ -3587,14 +3710,19 @@ proc vieweditor {top n title} { $top.t delete {end - 1c} end $top.t mark set insert 0.0 } - grid $top.t - -sticky ew -padx 5 + pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3 frame $top.buts button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n] + button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1] button $top.buts.can -text [mc "Cancel"] -command [list destroy $top] - grid $top.buts.ok $top.buts.can + bind $top [list newviewok $top $n] + bind $top [list newviewok $top $n 1] + bind $top [list destroy $top] + grid $top.buts.ok $top.buts.apply $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a - grid $top.buts - -pady 10 -sticky ew + grid columnconfigure $top.buts 2 -weight 1 -uniform a + pack $top.buts -in $top -side top -fill x focus $top.t } @@ -3615,17 +3743,15 @@ proc allviewmenus {n op args} { # doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args } -proc newviewok {top n} { +proc newviewok {top n {apply 0}} { global nextviewnum newviewperm newviewname newishighlight global viewname viewfiles viewperm selectedview curview - global viewargs newviewargs viewargscmd newviewargscmd viewhlmenu + global viewargs viewargscmd newviewopts viewhlmenu if {[catch { - set newargs [shellsplit $newviewargs($n)] + set newargs [encode_view_opts $n] } err]} { - error_popup "[mc "Error in commit selection arguments:"] $err" - wm raise $top - focus $top + error_popup "[mc "Error in commit selection arguments:"] $err" $top return } set files {} @@ -3639,10 +3765,10 @@ proc newviewok {top n} { # creating a new view incr nextviewnum set viewname($n) $newviewname($n) - set viewperm($n) $newviewperm($n) + set viewperm($n) $newviewopts($n,perm) set viewfiles($n) $files set viewargs($n) $newargs - set viewargscmd($n) $newviewargscmd($n) + set viewargscmd($n) $newviewopts($n,cmd) addviewmenu $n if {!$newishighlight} { run showview $n @@ -3651,7 +3777,7 @@ proc newviewok {top n} { } } else { # editing an existing view - set viewperm($n) $newviewperm($n) + set viewperm($n) $newviewopts($n,perm) if {$newviewname($n) ne $viewname($n)} { set viewname($n) $newviewname($n) doviewmenu .bar.view 5 [list showview $n] \ @@ -3660,15 +3786,16 @@ proc newviewok {top n} { # entryconf [list -label $viewname($n) -value $viewname($n)] } if {$files ne $viewfiles($n) || $newargs ne $viewargs($n) || \ - $newviewargscmd($n) ne $viewargscmd($n)} { + $newviewopts($n,cmd) ne $viewargscmd($n)} { set viewfiles($n) $files set viewargs($n) $newargs - set viewargscmd($n) $newviewargscmd($n) + set viewargscmd($n) $newviewopts($n,cmd) if {$curview == $n} { run reloadcommits } } } + if {$apply} return catch {destroy $top} } @@ -7763,6 +7890,7 @@ proc mkpatch {} { set patchtop $top catch {destroy $top} toplevel $top + wm transient $top . label $top.title -text [mc "Generate patch"] grid $top.title - -pady 10 label $top.from -text [mc "From:"] @@ -7793,6 +7921,8 @@ proc mkpatch {} { frame $top.buts button $top.buts.gen -text [mc "Generate"] -command mkpatchgo button $top.buts.can -text [mc "Cancel"] -command mkpatchcan + bind $top mkpatchgo + bind $top mkpatchcan grid $top.buts.gen $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -7827,7 +7957,7 @@ proc mkpatchgo {} { set cmd [lrange $cmd 1 end] lappend cmd >$fname & if {[catch {eval exec $cmd} err]} { - error_popup "[mc "Error creating patch:"] $err" + error_popup "[mc "Error creating patch:"] $err" $patchtop } catch {destroy $patchtop} unset patchtop @@ -7847,6 +7977,7 @@ proc mktag {} { set mktagtop $top catch {destroy $top} toplevel $top + wm transient $top . label $top.title -text [mc "Create tag"] grid $top.title - -pady 10 label $top.id -text [mc "ID:"] @@ -7864,6 +7995,8 @@ proc mktag {} { frame $top.buts button $top.buts.gen -text [mc "Create"] -command mktaggo button $top.buts.can -text [mc "Cancel"] -command mktagcan + bind $top mktaggo + bind $top mktagcan grid $top.buts.gen $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -7877,18 +8010,18 @@ proc domktag {} { set id [$mktagtop.sha1 get] set tag [$mktagtop.tag get] if {$tag == {}} { - error_popup [mc "No tag name specified"] - return + error_popup [mc "No tag name specified"] $mktagtop + return 0 } if {[info exists tagids($tag)]} { - error_popup [mc "Tag \"%s\" already exists" $tag] - return + error_popup [mc "Tag \"%s\" already exists" $tag] $mktagtop + return 0 } if {[catch { exec git tag $tag $id } err]} { - error_popup "[mc "Error creating tag:"] $err" - return + error_popup "[mc "Error creating tag:"] $err" $mktagtop + return 0 } set tagids($tag) $id @@ -7897,6 +8030,7 @@ proc domktag {} { addedtag $id dispneartags 0 run refill_reflist + return 1 } proc redrawtags {id} { @@ -7935,7 +8069,7 @@ proc mktagcan {} { } proc mktaggo {} { - domktag + if {![domktag]} return mktagcan } @@ -7946,6 +8080,7 @@ proc writecommit {} { set wrcomtop $top catch {destroy $top} toplevel $top + wm transient $top . label $top.title -text [mc "Write commit to file"] grid $top.title - -pady 10 label $top.id -text [mc "ID:"] @@ -7967,6 +8102,8 @@ proc writecommit {} { frame $top.buts button $top.buts.gen -text [mc "Write"] -command wrcomgo button $top.buts.can -text [mc "Cancel"] -command wrcomcan + bind $top wrcomgo + bind $top wrcomcan grid $top.buts.gen $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -7981,7 +8118,7 @@ proc wrcomgo {} { set cmd "echo $id | [$wrcomtop.cmd get]" set fname [$wrcomtop.fname get] if {[catch {exec sh -c $cmd >$fname &} err]} { - error_popup "[mc "Error writing commit:"] $err" + error_popup "[mc "Error writing commit:"] $err" $wrcomtop } catch {destroy $wrcomtop} unset wrcomtop @@ -8000,6 +8137,7 @@ proc mkbranch {} { set top .makebranch catch {destroy $top} toplevel $top + wm transient $top . label $top.title -text [mc "Create new branch"] grid $top.title - -pady 10 label $top.id -text [mc "ID:"] @@ -8014,6 +8152,8 @@ proc mkbranch {} { frame $top.buts button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top] button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}" + bind $top [list mkbrgo $top] + bind $top "catch {destroy $top}" grid $top.buts.go $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -8029,12 +8169,12 @@ proc mkbrgo {top} { set cmdargs {} set old_id {} if {$name eq {}} { - error_popup [mc "Please specify a name for the new branch"] + error_popup [mc "Please specify a name for the new branch"] $top return } if {[info exists headids($name)]} { if {![confirm_popup [mc \ - "Branch '%s' already exists. Overwrite?" $name]]} { + "Branch '%s' already exists. Overwrite?" $name] $top]} { return } set old_id $headids($name) @@ -8067,6 +8207,32 @@ proc mkbrgo {top} { } } +proc exec_citool {tool_args {baseid {}}} { + global commitinfo env + + set save_env [array get env GIT_AUTHOR_*] + + if {$baseid ne {}} { + if {![info exists commitinfo($baseid)]} { + getcommit $baseid + } + set author [lindex $commitinfo($baseid) 1] + set date [lindex $commitinfo($baseid) 2] + if {[regexp {^\s*(\S.*\S|\S)\s*<(.*)>\s*$} \ + $author author name email] + && $date ne {}} { + set env(GIT_AUTHOR_NAME) $name + set env(GIT_AUTHOR_EMAIL) $email + set env(GIT_AUTHOR_DATE) $date + } + } + + eval exec git citool $tool_args & + + array unset env GIT_AUTHOR_* + array set env $save_env +} + proc cherrypick {} { global rowmenuid curview global mainhead mainheadid @@ -8085,7 +8251,26 @@ proc cherrypick {} { # no error occurs, and exec takes that as an indication of error... if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} { notbusy cherrypick - error_popup $err + if {[regexp -line \ + {Entry '(.*)' (would be overwritten by merge|not uptodate)} \ + $err msg fname]} { + error_popup [mc "Cherry-pick failed because of local changes\ + to file '%s'.\nPlease commit, reset or stash\ + your changes and try again." $fname] + } elseif {[regexp -line \ + {^(CONFLICT \(.*\):|Automatic cherry-pick failed)} \ + $err]} { + if {[confirm_popup [mc "Cherry-pick failed because of merge\ + conflict.\nDo you wish to run git citool to\ + resolve it?"]]} { + # Force citool to read MERGE_MSG + file delete [file join [gitdir] "GITGUI_MSG"] + exec_citool {} $rowmenuid + } + } else { + error_popup $err + } + run updatecommits return } set newhead [exec git rev-parse HEAD] @@ -8138,6 +8323,7 @@ proc resethead {} { button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w" pack $w.ok -side left -fill x -padx 20 -pady 20 button $w.cancel -text [mc Cancel] -command "destroy $w" + bind $w [list destroy $w] pack $w.cancel -side right -fill x -padx 20 -pady 20 bind $w "grab $w; focus $w" tkwait window $w @@ -8294,6 +8480,7 @@ proc showrefs {} { } toplevel $top wm title $top [mc "Tags and heads: %s" [file tail [pwd]]] + wm transient $top . text $top.list -background $bgcolor -foreground $fgcolor \ -selectbackground $selectbgcolor -font mainfont \ -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \ @@ -8315,6 +8502,7 @@ proc showrefs {} { pack $top.f.l -side left grid $top.f - -sticky ew -pady 2 button $top.close -command [list destroy $top] -text [mc "Close"] + bind $top [list destroy $top] grid $top.close - grid columnconfigure $top 0 -weight 1 grid rowconfigure $top 0 -weight 1 @@ -9620,6 +9808,7 @@ proc mkfontdisp {font top which} { proc choosefont {font which} { global fontparam fontlist fonttop fontattr + global prefstop set fontparam(which) $which set fontparam(font) $font @@ -9633,6 +9822,7 @@ proc choosefont {font which} { font create sample eval font config sample [font actual $font] toplevel $top + wm transient $top $prefstop wm title $top [mc "Gitk font chooser"] label $top.l -textvariable fontparam(which) pack $top.l -side top @@ -9666,6 +9856,8 @@ proc choosefont {font which} { frame $top.buts button $top.buts.ok -text [mc "OK"] -command fontok -default active button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal + bind $top fontok + bind $top fontcan grid $top.buts.ok $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -9747,6 +9939,7 @@ proc doprefs {} { } toplevel $top wm title $top [mc "Gitk preferences"] + wm transient $top . label $top.ldisp -text [mc "Commit list display options"] grid $top.ldisp - -sticky w -pady 10 label $top.spacer -text " " @@ -9845,6 +10038,8 @@ proc doprefs {} { frame $top.buts button $top.buts.ok -text [mc "OK"] -command prefsok -default active button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal + bind $top prefsok + bind $top prefscan grid $top.buts.ok $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a