@ -1088,6 +1088,8 @@ proc makewindow {} {
@@ -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} {
@@ -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} {
@@ -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} {
@@ -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} {
@@ -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} {
@@ -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 {} {
@@ -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 {} {
@@ -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 {} {
@@ -8111,6 +8242,15 @@ proc doprefs {} {
bind $top <Visibility> "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
@@ -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} {
@@ -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}]