[PATCH] gitk : External diff viewer.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Right click on patched file list view gives "External diff" popup menu entry,
launching selected external diff tool.
The diff tool is configurable through Edit/Preference/External diff tool.

Signed-off-by: Thomas Arcila <tarcila@xxxxxx>
---

Hi,

Here is a patch to gitk that allows to run an external diff viewer.
It can be configured in Edit/Preferences/External diff tool.

To see the diff between two files:
- select revisions to diff
- right click on a file in the patched files list view
- choose "External diff"

Any feedback is welcome.
Thomas

 gitk |  132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/gitk b/gitk
index 5560e4d..6d727f4 100755
--- a/gitk
+++ b/gitk
@@ -1054,6 +1054,16 @@ 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}
+
+    global flist_menu_tree
+    set flist_menu_tree .flistctxmenutree
+    menu $flist_menu_tree -tearoff 0
+    $flist_menu_tree add command -label [mc "Highlight this too"] \
+	-command {flist_hl 0}
+    $flist_menu_tree add command -label [mc "Highlight this only"] \
+	-command {flist_hl 1}
 }
 
 # Windows sends all mouse wheel events to the current focused window, not
@@ -1157,7 +1167,7 @@ proc savestuff {w} {
     global maxwidth showneartags showlocalchanges
     global viewname viewfiles viewargs viewperm nextviewnum
     global cmitmode wrapcomment datetimeformat limitdiffs
-    global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
+    global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor extdifftool
 
     if {$stuffsaved} return
     if {![winfo viewable .]} return
@@ -1182,6 +1192,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]"
@@ -1719,7 +1730,7 @@ proc sel_flist {w x y} {
 }
 
 proc pop_flist_menu {w X Y x y} {
-    global ctext cflist cmitmode flist_menu flist_menu_file
+    global ctext cflist cmitmode flist_menu flist_menu_tree flist_menu_file
     global treediffs diffids
 
     stopfinding
@@ -1732,7 +1743,11 @@ proc pop_flist_menu {w X Y x y} {
 	set e [lindex $treediffs($diffids) [expr {$l-2}]]
     }
     set flist_menu_file $e
-    tk_popup $flist_menu $X $Y
+    if {$cmitmode eq "tree"} {
+      tk_popup $flist_menu_tree $X $Y
+    } else {
+      tk_popup $flist_menu $X $Y
+    }
 }
 
 proc flist_hl {only} {
@@ -1747,6 +1762,99 @@ proc flist_hl {only} {
     set gdttype [mc "touching paths:"]
 }
 
+proc external_diff {} {
+  global gitktmpdir nullid nullid2
+  global flist_menu_file
+  global diffids
+  global diffnum
+  global gitdir extdifftool
+
+  set diffidto [lindex $diffids 0]
+
+  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 parent commit
+      global allparents
+      set diffidfrom $allparents($diffidto)
+    }
+  } else {
+    set diffidfrom [lindex $diffids 0]
+    set diffidto [lindex $diffids 1]
+  }
+
+  if {! [info exists diffnum]} {
+    set diffnum 0
+  } else {
+    set diffnum [expr $diffnum + 1]
+  }
+
+
+  set diffdir [file join $gitktmpdir "$diffnum"]
+  set diffok "true"
+
+  file mkdir $diffdir
+  if {$diffidto eq $nullid} {
+    set difftofile [file join $gitdir ".." $flist_menu_file]
+  } elseif {$diffidto eq $nullid2} {
+    set difftofile [file join $diffdir "\[index\] [file tail $flist_menu_file]"]
+    if {[catch {exec git show :$flist_menu_file > $difftofile} err]} {
+      error_popup "\"$flist_menu_file\" [mc "cannot be found in index. \
+                  File has probably been created, deleted or renamed, \
+                  in a different commit."]"
+      set diffok "false"
+    }
+  } else {
+    set difftofile [file join $diffdir "\[$diffidto\] [file tail $flist_menu_file]"]
+    if {[catch {exec git show $diffidto:$flist_menu_file > $difftofile} err]} {
+      error_popup "\"$flist_menu_file\" [mc "cannot be found in revision"] \
+                  $diffidto. [mc "File has probably been created, \
+                  deleted or renamed, in a different commit."]"
+      set diffok "false"
+    }
+  }
+
+  if {$diffidfrom == $nullid} {
+    set difffromfile [file join $gitdir ".." $flist_menu_file]
+  } elseif {$diffidfrom == $nullid2} {
+    set difffromfile [file join $diffdir "\[index\] [file tail $flist_menu_file]"]
+    if {[catch {exec git show :$flist_menu_file > $difffromfile} err]} {
+      error_popup "\"$flist_menu_file\" [mc "cannot be found in index. \
+                  File has probably been created, deleted or renamed, \
+                  in a different commit."]"
+      set diffok "false"
+    }
+   } else {
+    set difffromfile [file join $diffdir "\[$diffidfrom\] [file tail $flist_menu_file]"]
+    if {[catch {exec git show $diffidfrom:$flist_menu_file > $difffromfile} err]} {
+      error_popup "\"$flist_menu_file\" [mc "cannot be found in revision"] \
+                  $diffidfrom. [mc "File has probably been created, \
+                  deleted or renamed, in a different commit."]"
+      set diffok "false"
+    }
+  }
+
+  if {$diffok} {
+    # here we don't use shellquote because \ and everything must be escaped and not enclosed between ''
+    set quotedextdifftool \"[string map {\" \\\" \\ \\\\ \  \\\ } $extdifftool]\"
+    set cmd [concat | $quotedextdifftool [shellarglist [list $difffromfile $difftofile]]]
+    if {[catch {set fl [open $cmd]} err]} {
+      file delete -force [ file join $gitktmpdir $diffnum ]
+      error_popup [mc "$extdifftool command failed: $err"]
+    } else {
+      fconfigure $fl -blocking 0
+      filerun $fl [list file delete -force [file join $gitktmpdir $diffnum]]
+    }
+  }
+}
+
 # Functions for adding and removing shell-type quoting
 
 proc shellquote {str} {
@@ -7802,9 +7910,13 @@ proc showtag {tag isnew} {
 
 proc doquit {} {
     global stopped
+    global gitktmpdir
+
     set stopped 100
     savestuff .
     destroy .
+
+    catch {file delete -force $gitktmpdir}
 }
 
 proc mkfontdisp {font top which} {
@@ -7933,7 +8045,7 @@ proc doprefs {} {
     global maxwidth maxgraphpct
     global oldprefs prefstop showneartags showlocalchanges
     global bgcolor fgcolor ctext diffcolors selectbgcolor
-    global tabstop limitdiffs
+    global tabstop limitdiffs extdifftool
 
     set top .gitkprefs
     set prefstop $top
@@ -7980,6 +8092,13 @@ proc doprefs {} {
     pack $top.ldiff.b $top.ldiff.l -side left
     grid x $top.ldiff -sticky w
 
+    entry $top.extdifft -textvariable extdifftool
+    button $top.extdiffb -text [mc "External diff tool" ] -font optionfont \
+  -command {set extdifftool [tk_getOpenFile -title "External diff tool" \
+  -multiple "false"]}
+    grid x $top.extdiffb $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
@@ -8454,6 +8573,8 @@ set showlocalchanges 1
 set limitdiffs 1
 set datetimeformat "%Y-%m-%d %H:%M:%S"
 
+set extdifftool "meld"
+
 set colors {green red blue magenta darkgrey brown orange}
 set bgcolor white
 set fgcolor black
@@ -8507,6 +8628,9 @@ if {![file isdirectory $gitdir]} {
     exit 1
 }
 
+set gitktmpdir [file normalize [file join $gitdir ".." [format ".gitk-tmp.%s" [pid]]]]
+file mkdir $gitktmpdir
+
 set mergeonly 0
 set revtreeargs {}
 set cmdline_files {}
-- 
1.5.3.8

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux