1088
-command {flist_hl 0}
1089
$flist_menu add command -label [mc "Highlight this only"] \
1090
-command {flist_hl 1}
1091
+ $flist_menu add command -label [mc "External diff"] \
1092
+ -command {external_diff}
1093
}
1094
1095
# Windows sends all mouse wheel events to the current focused window, not
1194
global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
1195
global cmitmode wrapcomment datetimeformat limitdiffs
1196
global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
1195
- global autoselect
1197
+ global autoselect extdifftool
1198
1199
if {$stuffsaved} return
1200
if {![winfo viewable .]} return
1220
puts $f [list set diffcolors $diffcolors]
1221
puts $f [list set diffcontext $diffcontext]
1222
puts $f [list set selectbgcolor $selectbgcolor]
1223
+ puts $f [list set extdifftool $extdifftool]
1224
1225
puts $f "set geometry(main) [wm geometry .]"
1226
puts $f "set geometry(topwidth) [winfo width .tf]"
1771
set e [lindex $treediffs($diffids) [expr {$l-2}]]
1772
}
1773
set flist_menu_file $e
1774
+ set xdiffstate "normal"
1775
+ if {$cmitmode eq "tree"} {
1776
+ set xdiffstate "disabled"
1777
+ }
1778
+ # Disable "External diff" item in tree mode
1779
+ $flist_menu entryconf 2 -state $xdiffstate
1780
tk_popup $flist_menu $X $Y
1781
}
1782
1792
set gdttype [mc "touching paths:"]
1793
}
1794
1795
+proc save_file_from_commit {filename output what} {
1796
+ global nullfile
1797
+
1798
+ if {[catch {exec git show $filename -- > $output} err]} {
1799
+ if {[string match "fatal: bad revision *" $err]} {
1800
+ return $nullfile
1801
+ }
1802
+ error_popup "Error getting \"$filename\" from $what: $err"
1803
+ return {}
1804
+ }
1805
+ return $output
1806
+}
1807
+
1808
+proc external_diff_get_one_file {diffid filename diffdir} {
1809
+ global nullid nullid2 nullfile
1810
+ global gitdir
1811
+
1812
+ if {$diffid == $nullid} {
1813
+ set difffile [file join [file dirname $gitdir] $filename]
1814
+ if {[file exists $difffile]} {
1815
+ return $difffile
1816
+ }
1817
+ return $nullfile
1818
+ }
1819
+ if {$diffid == $nullid2} {
1820
+ set difffile [file join $diffdir "\[index\] [file tail $filename]"]
1821
+ return [save_file_from_commit :$filename $difffile index]
1822
+ }
1823
+ set difffile [file join $diffdir "\[$diffid\] [file tail $filename]"]
1824
+ return [save_file_from_commit $diffid:$filename $difffile \
1825
+ "revision $diffid"]
1826
+}
1827
+
1828
+proc external_diff {} {
1829
+ global gitktmpdir nullid nullid2
1830
+ global flist_menu_file
1831
+ global diffids
1832
+ global diffnum
1833
+ global gitdir extdifftool
1834
+
1835
+ if {[llength $diffids] == 1} {
1836
+ # no reference commit given
1837
+ set diffidto [lindex $diffids 0]
1838
+ if {$diffidto eq $nullid} {
1839
+ # diffing working copy with index
1840
+ set diffidfrom $nullid2
1841
+ } elseif {$diffidto eq $nullid2} {
1842
+ # diffing index with HEAD
1843
+ set diffidfrom "HEAD"
1844
+ } else {
1845
+ # use first parent commit
1846
+ global parentlist selectedline
1847
+ set diffidfrom [lindex $parentlist $selectedline 0]
1848
+ }
1849
+ } else {
1850
+ set diffidfrom [lindex $diffids 0]
1851
+ set diffidto [lindex $diffids 1]
1852
+ }
1853
+
1854
+ # make sure that several diffs wont collide
1855
+ if {![info exists gitktmpdir]} {
1856
+ set gitktmpdir [file join [file dirname $gitdir] \
1857
+ [format ".gitk-tmp.%s" [pid]]]
1858
+ if {[catch {file mkdir $gitktmpdir} err]} {
1859
+ error_popup "Error creating temporary directory $gitktmpdir: $err"
1860
+ unset gitktmpdir
1861
+ return
1862
+ }
1863
+ set diffnum 0
1864
+ }
1865
+ incr diffnum
1866
+ set diffdir [file join $gitktmpdir $diffnum]
1867
+ if {[catch {file mkdir $diffdir} err]} {
1868
+ error_popup "Error creating temporary directory $diffdir: $err"
1869
+ return
1870
+ }
1871
+
1872
+ # gather files to diff
1873
+ set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
1874
+ set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir]
1875
+
1876
+ if {$difffromfile ne {} && $difftofile ne {}} {
1877
+ set cmd [concat | [shellsplit $extdifftool] \
1878
+ [list $difffromfile $difftofile]]
1879
+ if {[catch {set fl [open $cmd r]} err]} {
1880
+ file delete -force $diffdir
1881
+ error_popup [mc "$extdifftool: command failed: $err"]
1882
+ } else {
1883
+ fconfigure $fl -blocking 0
1884
+ filerun $fl [list delete_at_eof $fl $diffdir]
1885
+ }
1886
+ }
1887
+}
1888
+
1889
+# delete $dir when we see eof on $f (presumably because the child has exited)
1890
+proc delete_at_eof {f dir} {
1891
+ while {[gets $f line] >= 0} {}
1892
+ if {[eof $f]} {
1893
+ if {[catch {close $f} err]} {
1894
+ error_popup "External diff viewer failed: $err"
1895
+ }
1896
+ file delete -force $dir
1897
+ return 0
1898
+ }
1899
+ return 1
1900
+}
1901
+
1902
# Functions for adding and removing shell-type quoting
1903
1904
proc shellquote {str} {
7997
7998
proc doquit {} {
7999
global stopped
8000
+ global gitktmpdir
8001
+
8002
set stopped 100
8003
savestuff .
8004
destroy .
8005
+
8006
+ if {[info exists gitktmpdir]} {
8007
+ catch {file delete -force $gitktmpdir}
8008
+ }
8009
}
8010
8011
proc mkfontdisp {font top which} {
8134
global maxwidth maxgraphpct
8135
global oldprefs prefstop showneartags showlocalchanges
8136
global bgcolor fgcolor ctext diffcolors selectbgcolor
8015
- global tabstop limitdiffs autoselect
8137
+ global tabstop limitdiffs autoselect extdifftool
8138
8139
set top .gitkprefs
8140
set prefstop $top
8186
pack $top.ldiff.b $top.ldiff.l -side left
8187
grid x $top.ldiff -sticky w
8188
8189
+ entry $top.extdifft -textvariable extdifftool
8190
+ frame $top.extdifff
8191
+ label $top.extdifff.l -text [mc "External diff tool" ] -font optionfont \
8192
+ -padx 10
8193
+ button $top.extdifff.b -text [mc "Choose..."] -font optionfont \
8194
+ -command choose_extdiff
8195
+ pack $top.extdifff.l $top.extdifff.b -side left
8196
+ grid x $top.extdifff $top.extdifft -sticky w
8197
+
8198
label $top.cdisp -text [mc "Colors: press to choose"]
8199
grid $top.cdisp - -sticky w -pady 10
8200
label $top.bg -padx 40 -relief sunk -background $bgcolor
8242
bind $top <Visibility> "focus $top.buts.ok"
8243
}
8244
8245
+proc choose_extdiff {} {
8246
+ global extdifftool
8247
+
8248
+ set prog [tk_getOpenFile -title "External diff tool" -multiple false]
8249
+ if {$prog ne {}} {
8250
+ set extdifftool $prog
8251
+ }
8252
+}
8253
+
8254
proc choosecolor {v vi w x cmd} {
8255
global $v
8256
8679
set datetimeformat "%Y-%m-%d %H:%M:%S"
8680
set autoselect 1
8681
8682
+set extdifftool "meld"
8683
+
8684
set colors {green red blue magenta darkgrey brown orange}
8685
set bgcolor white
8686
set fgcolor black
8827
8828
set nullid "0000000000000000000000000000000000000000"
8829
set nullid2 "0000000000000000000000000000000000000001"
8830
+set nullfile "/dev/null"
8831
8832
set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
8833