From 80dd7b44970dee7d82fa735d2e0b828051f80545 Mon Sep 17 00:00:00 2001 From: Gerrit Pape Date: Wed, 26 Mar 2008 18:45:26 +0000 Subject: gitk: Fix changing colors through Edit->Preferences With tcl/tk8.5 the lset command seems to behave differently. When changing the background color through Edit->Preferences, the changes are applied, but new dialogs, such as View->New view... barf with Error: unknown color name "{#ffffff}" Additionally when closing gitk, and starting it up again, a bad value has been saved to ~/.gitk, preventing gitk from running properly; it fails with Error in startup script: unknown color name "{#ffffff}" ... This commit fixes the problem by changing the color dialogs to pass the empty string {} as the list index to choosecolor. This causes the lset and lindex commands used by choosecolor to use and set the whole variable (bgcolor, fgcolor or selectbgcolor) rather than treating them as a 1-element list. Tested with tcl/tk8.4 and 8.5. Dmitry Potapov reported this problem through http://bugs.debian.org/472615 Signed-off-by: Gerrit Pape Signed-off-by: Paul Mackerras --- gitk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gitk') diff --git a/gitk b/gitk index 84ab02e15f..9a4d9c40cf 100755 --- a/gitk +++ b/gitk @@ -8045,11 +8045,11 @@ proc doprefs {} { grid $top.cdisp - -sticky w -pady 10 label $top.bg -padx 40 -relief sunk -background $bgcolor button $top.bgbut -text [mc "Background"] -font optionfont \ - -command [list choosecolor bgcolor 0 $top.bg background setbg] + -command [list choosecolor bgcolor {} $top.bg background setbg] grid x $top.bgbut $top.bg -sticky w label $top.fg -padx 40 -relief sunk -background $fgcolor button $top.fgbut -text [mc "Foreground"] -font optionfont \ - -command [list choosecolor fgcolor 0 $top.fg foreground setfg] + -command [list choosecolor fgcolor {} $top.fg foreground setfg] grid x $top.fgbut $top.fg -sticky w label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0] button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \ @@ -8069,7 +8069,7 @@ proc doprefs {} { grid x $top.hunksepbut $top.hunksep -sticky w label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor button $top.selbgbut -text [mc "Select bg"] -font optionfont \ - -command [list choosecolor selectbgcolor 0 $top.selbgsep background setselbg] + -command [list choosecolor selectbgcolor {} $top.selbgsep background setselbg] grid x $top.selbgbut $top.selbgsep -sticky w label $top.cfont -text [mc "Fonts: press to choose"] -- cgit v1.3 From f31fa2c0864ba8b1292119fbb3942cdbaa0fb807 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 28 Apr 2008 09:40:50 +1000 Subject: gitk: Fix handling of tree file list with special chars in names Alex Riesen pointed out that displaying a commit in 'tree' mode fails if some files have names with special characters such as '{' or '}' in them, due to the fact that we treat the line returned from git ls-tree as a Tcl list at one point. This fixes it by doing what I originally intended but didn't quite get right. We split the line from git ls-tree at the first tab and treat the part before the tab as a list (which is OK since it doesn't have special characters in it) and the part after the tab as the filename. Signed-off-by: Paul Mackerras --- gitk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gitk') diff --git a/gitk b/gitk index 9a4d9c40cf..da685aa63c 100755 --- a/gitk +++ b/gitk @@ -4992,11 +4992,12 @@ proc gettreeline {gtf id} { if {$diffids eq $nullid} { set fname $line } else { - if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue set i [string first "\t" $line] if {$i < 0} continue - set sha1 [lindex $line 2] set fname [string range $line [expr {$i+1}] end] + set line [string range $line 0 [expr {$i-1}]] + if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue + set sha1 [lindex $line 2] if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } -- cgit v1.3 From 5e3502dabb6e95e3d9420e010276f832cb68e396 Mon Sep 17 00:00:00 2001 From: Michele Ballabio Date: Fri, 2 May 2008 17:46:20 +0200 Subject: gitk: Disable "Reset %s branch to here" when on a detached head When we are on a detached head - since gitk does not display where we are - reset has no sense, so disable the relevant line on the context menu, and point out to the user that we are on a detached head. Otherwise, a reset from gitk when on a detached head returns the error: can't read "headids()": no such element in array can't read "headids()": no such element in array while executing "removehead $headids($name) $name" (procedure "movehead" line 4) invoked from within "movehead $newhead $mainhead" (procedure "readresetstat" line 20) invoked from within "readresetstat file4" ("eval" body line 1) invoked from within "eval $script" (procedure "dorunq" line 9) invoked from within "dorunq" ("after" script) [paulus@samba.org: changed menu item to "Detached head: can't reset"] Signed-off-by: Michele Ballabio Signed-off-by: Paul Mackerras --- gitk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'gitk') diff --git a/gitk b/gitk index da685aa63c..9e282e58ec 100755 --- a/gitk +++ b/gitk @@ -6016,7 +6016,11 @@ proc rowmenu {x y id} { } if {$id ne $nullid && $id ne $nullid2} { set menu $rowctxmenu - $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] + if {$mainhead ne {}} { + $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] + } else { + $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled + } } else { set menu $fakerowmenu } -- cgit v1.3 From f4c54b3cc4b1bbde34fe957ac03f9862ec970de3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 10 May 2008 13:15:36 +1000 Subject: gitk: Synchronize highlighting in file view for 'f' and 'b' commands This is based on a patch by Eric Raible , but does things a bit more simply. Previously, 'b', backspace, and delete all did the same thing. This changes 'b' to perform the inverse of 'f'. And both of them now highlight the filename of the currently diff. This makes it easier to review and navigate the diffs associated with a particular commit using only f, b, and space because the filename of the currently display diff will be dynamically highlighted. Signed-off-by: Paul Mackerras --- gitk | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'gitk') diff --git a/gitk b/gitk index 9e282e58ec..9ff25deb7c 100755 --- a/gitk +++ b/gitk @@ -1016,7 +1016,7 @@ proc makewindow {} { bindkey k "selnextline 1" bindkey j "goback" bindkey l "goforw" - bindkey b "$ctext yview scroll -1 pages" + bindkey b prevfile bindkey d "$ctext yview scroll 18 units" bindkey u "$ctext yview scroll -18 units" bindkey / {dofind 1 1} @@ -5479,26 +5479,44 @@ proc changediffdisp {} { $ctext tag conf d1 -elide [lindex $diffelide 1] } +proc highlightfile {loc cline} { + global ctext cflist cflist_top + + $ctext yview $loc + $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend" + $cflist tag add highlight $cline.0 "$cline.0 lineend" + $cflist see $cline.0 + set cflist_top $cline +} + proc prevfile {} { - global difffilestart ctext - set prev [lindex $difffilestart 0] + global difffilestart ctext cmitmode + + if {$cmitmode eq "tree"} return + set prev 0.0 + set prevline 1 set here [$ctext index @0,0] foreach loc $difffilestart { if {[$ctext compare $loc >= $here]} { - $ctext yview $prev + highlightfile $prev $prevline return } set prev $loc + incr prevline } - $ctext yview $prev + highlightfile $prev $prevline } proc nextfile {} { - global difffilestart ctext + global difffilestart ctext cmitmode + + if {$cmitmode eq "tree"} return set here [$ctext index @0,0] + set line 1 foreach loc $difffilestart { + incr line if {[$ctext compare $loc > $here]} { - $ctext yview $loc + highlightfile $loc $line return } } -- cgit v1.3 From 314f5de1a0b91d27cbbb8a400337dd41cf84d511 Mon Sep 17 00:00:00 2001 From: Thomas Arcila Date: Mon, 24 Mar 2008 12:55:36 +0100 Subject: gitk: Allow users to view diffs in external diff viewer This allows gitk to run an external diff viewer such as meld. Right-click on a file in the file list view gives "External diff" popup menu entry, which launches the selected external diff tool. The menu entry is only active in "Patch" mode, not in "Tree" mode. The program to run to display the diff is configurable through Edit/Preference/External diff tool. The program is run with two arguments, being the names of files containing the two versions to diff. Gitk will create temporary directories called .gitk-tmp./ to place these files in, and remove them when it's finished. If the file doesn't exist in one or other revision, gitk will supply /dev/null as the name of the file on that side of the diff. This may need to be adjusted for Windows or MacOS. [paulus@samba.org - cleaned up and rewrote some parts of the patch.] Signed-off-by: Thomas Arcila Signed-off-by: Paul Mackerras --- gitk | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 2 deletions(-) (limited to 'gitk') diff --git a/gitk b/gitk index 9ff25deb7c..a1eccfc6d2 100755 --- a/gitk +++ b/gitk @@ -1088,6 +1088,8 @@ proc makewindow {} { -command {flist_hl 0} $flist_menu add command -label [mc "Highlight this only"] \ -command {flist_hl 1} + $flist_menu add command -label [mc "External diff"] \ + -command {external_diff} } # Windows sends all mouse wheel events to the current focused window, not @@ -1192,7 +1194,7 @@ proc savestuff {w} { global viewname viewfiles viewargs viewargscmd viewperm nextviewnum global cmitmode wrapcomment datetimeformat limitdiffs global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor - global autoselect + global autoselect extdifftool if {$stuffsaved} return if {![winfo viewable .]} return @@ -1218,6 +1220,7 @@ proc savestuff {w} { puts $f [list set diffcolors $diffcolors] puts $f [list set diffcontext $diffcontext] puts $f [list set selectbgcolor $selectbgcolor] + puts $f [list set extdifftool $extdifftool] puts $f "set geometry(main) [wm geometry .]" puts $f "set geometry(topwidth) [winfo width .tf]" @@ -1768,6 +1771,12 @@ proc pop_flist_menu {w X Y x y} { set e [lindex $treediffs($diffids) [expr {$l-2}]] } set flist_menu_file $e + set xdiffstate "normal" + if {$cmitmode eq "tree"} { + set xdiffstate "disabled" + } + # Disable "External diff" item in tree mode + $flist_menu entryconf 2 -state $xdiffstate tk_popup $flist_menu $X $Y } @@ -1783,6 +1792,113 @@ proc flist_hl {only} { set gdttype [mc "touching paths:"] } +proc save_file_from_commit {filename output what} { + global nullfile + + if {[catch {exec git show $filename -- > $output} err]} { + if {[string match "fatal: bad revision *" $err]} { + return $nullfile + } + error_popup "Error getting \"$filename\" from $what: $err" + return {} + } + return $output +} + +proc external_diff_get_one_file {diffid filename diffdir} { + global nullid nullid2 nullfile + global gitdir + + if {$diffid == $nullid} { + set difffile [file join [file dirname $gitdir] $filename] + if {[file exists $difffile]} { + return $difffile + } + return $nullfile + } + if {$diffid == $nullid2} { + set difffile [file join $diffdir "\[index\] [file tail $filename]"] + return [save_file_from_commit :$filename $difffile index] + } + set difffile [file join $diffdir "\[$diffid\] [file tail $filename]"] + return [save_file_from_commit $diffid:$filename $difffile \ + "revision $diffid"] +} + +proc external_diff {} { + global gitktmpdir nullid nullid2 + global flist_menu_file + global diffids + global diffnum + global gitdir extdifftool + + if {[llength $diffids] == 1} { + # no reference commit given + set diffidto [lindex $diffids 0] + if {$diffidto eq $nullid} { + # diffing working copy with index + set diffidfrom $nullid2 + } elseif {$diffidto eq $nullid2} { + # diffing index with HEAD + set diffidfrom "HEAD" + } else { + # use first parent commit + global parentlist selectedline + set diffidfrom [lindex $parentlist $selectedline 0] + } + } else { + set diffidfrom [lindex $diffids 0] + set diffidto [lindex $diffids 1] + } + + # make sure that several diffs wont collide + if {![info exists gitktmpdir]} { + set gitktmpdir [file join [file dirname $gitdir] \ + [format ".gitk-tmp.%s" [pid]]] + if {[catch {file mkdir $gitktmpdir} err]} { + error_popup "Error creating temporary directory $gitktmpdir: $err" + unset gitktmpdir + return + } + set diffnum 0 + } + incr diffnum + set diffdir [file join $gitktmpdir $diffnum] + if {[catch {file mkdir $diffdir} err]} { + error_popup "Error creating temporary directory $diffdir: $err" + return + } + + # gather files to diff + set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir] + set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir] + + if {$difffromfile ne {} && $difftofile ne {}} { + set cmd [concat | [shellsplit $extdifftool] \ + [list $difffromfile $difftofile]] + if {[catch {set fl [open $cmd r]} err]} { + file delete -force $diffdir + error_popup [mc "$extdifftool: command failed: $err"] + } else { + fconfigure $fl -blocking 0 + filerun $fl [list delete_at_eof $fl $diffdir] + } + } +} + +# 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} {} + if {[eof $f]} { + if {[catch {close $f} err]} { + error_popup "External diff viewer failed: $err" + } + file delete -force $dir + return 0 + } + return 1 +} + # Functions for adding and removing shell-type quoting proc shellquote {str} { @@ -7881,9 +7997,15 @@ proc showtag {tag isnew} { proc doquit {} { global stopped + global gitktmpdir + set stopped 100 savestuff . destroy . + + if {[info exists gitktmpdir]} { + catch {file delete -force $gitktmpdir} + } } proc mkfontdisp {font top which} { @@ -8012,7 +8134,7 @@ proc doprefs {} { global maxwidth maxgraphpct global oldprefs prefstop showneartags showlocalchanges global bgcolor fgcolor ctext diffcolors selectbgcolor - global tabstop limitdiffs autoselect + global tabstop limitdiffs autoselect extdifftool set top .gitkprefs set prefstop $top @@ -8064,6 +8186,15 @@ proc doprefs {} { pack $top.ldiff.b $top.ldiff.l -side left grid x $top.ldiff -sticky w + entry $top.extdifft -textvariable extdifftool + frame $top.extdifff + label $top.extdifff.l -text [mc "External diff tool" ] -font optionfont \ + -padx 10 + button $top.extdifff.b -text [mc "Choose..."] -font optionfont \ + -command choose_extdiff + pack $top.extdifff.l $top.extdifff.b -side left + grid x $top.extdifff $top.extdifft -sticky w + label $top.cdisp -text [mc "Colors: press to choose"] grid $top.cdisp - -sticky w -pady 10 label $top.bg -padx 40 -relief sunk -background $bgcolor @@ -8111,6 +8242,15 @@ proc doprefs {} { bind $top "focus $top.buts.ok" } +proc choose_extdiff {} { + global extdifftool + + set prog [tk_getOpenFile -title "External diff tool" -multiple false] + if {$prog ne {}} { + set extdifftool $prog + } +} + proc choosecolor {v vi w x cmd} { global $v @@ -8539,6 +8679,8 @@ set limitdiffs 1 set datetimeformat "%Y-%m-%d %H:%M:%S" set autoselect 1 +set extdifftool "meld" + set colors {green red blue magenta darkgrey brown orange} set bgcolor white set fgcolor black @@ -8685,6 +8827,7 @@ if {$mergeonly} { set nullid "0000000000000000000000000000000000000000" set nullid2 "0000000000000000000000000000000000000001" +set nullfile "/dev/null" set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}] -- cgit v1.3