It's a bit clunky but it works!!

Usage:
 - mark commit one (e.g. v45)
 - Select commit two.
 - Switch the gdttype to the option, "git-cherry between marked commit and:"

Signed-off-by: Pierre Dumuid <pmdum...@gmail.com>
---
 gitk | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 107 insertions(+), 3 deletions(-)

diff --git a/gitk b/gitk
index a14d7a1..50d1ef4 100755
--- a/gitk
+++ b/gitk
@@ -2319,7 +2319,9 @@ proc makewindow {} {
                [mc "containing:"] \
                [mc "touching paths:"] \
                [mc "adding/removing string:"] \
-               [mc "changing lines matching:"]]
+               [mc "changing lines matching:"] \
+               [mc "git-cherry between marked commit and:"] \
+              ]
     trace add variable gdttype write gdttype_change
     pack .tf.lbar.gdttype -side left -fill y
 
@@ -4707,6 +4709,18 @@ proc gdttype_change {name ix op} {
     global gdttype highlight_files findstring findpattern
 
     stopfinding
+
+    if {$gdttype eq [mc "git-cherry between marked commit and:"]} {
+       if {$highlight_files ne {}} {
+           set highlight_files {}
+           hfiles_change
+       }
+       findcom_change
+       update_gitcherrylist
+       drawvisible
+       return
+    }
+
     if {$findstring ne {}} {
        if {$gdttype eq [mc "containing:"]} {
            if {$highlight_files ne {}} {
@@ -4733,6 +4747,9 @@ proc find_change {name ix op} {
     stopfinding
     if {$gdttype eq [mc "containing:"]} {
        findcom_change
+    } elseif {$gdttype eq [mc "git-cherry between marked commit and:"]} {
+       findcom_change
+       update_gitcherrylist
     } else {
        if {$highlight_files ne $findstring} {
            set highlight_files $findstring
@@ -4742,6 +4759,54 @@ proc find_change {name ix op} {
     drawvisible
 }
 
+proc update_gitcherrylist {} {
+    global gitcherryids
+    global markedid
+    global findstring
+    global fstring
+    global currentid
+    global iddrawn
+
+    unset -nocomplain gitcherryids
+    set fs $findstring
+
+    if {$findstring eq {}} {
+       $fstring delete 0 end
+       $fstring insert 0 $currentid
+    }
+
+    if {![info exists markedid]} {
+       error_popup [mc "Please mark a git commit before using this find 
method!"]
+       return
+    }
+
+    #puts [join [list "Running cherry between: `" $markedid "` and `" 
$findstring "`"] ""]
+
+    if {[catch {set cherryOutput [exec git cherry $markedid $findstring]}]} {
+       puts "ERROR: An error occured running git-cherry!"
+       return
+    }
+
+    set cherryLines [split $cherryOutput "\n"]
+    foreach cherryLine $cherryLines {
+       set op [lindex [split $cherryLine " "] 0]
+       set gitSha [lindex [split $cherryLine " "] 1]
+
+       #puts [join [list "line is: `" $cherryLine "`, op:`" $op "`, gitSha:`" 
$gitSha "`"] ""]
+       if {$op eq "+"} {
+           set gitcherryids($gitSha) 1
+           if ([info exists iddrawn($gitSha)]) {
+               bolden $gitSha mainfontbold
+           }
+
+       }
+    }
+    # puts "list is as follows"
+    #foreach {gitsha setBold} [array get gitcherryids] {
+    #  puts [concat $gitsha = $setBold]
+    #}
+}
+
 proc findcom_change args {
     global nhighlights boldnameids
     global findpattern findtype findstring gdttype
@@ -4802,6 +4867,9 @@ proc do_file_hl {serial} {
        set gdtargs [list "-S$highlight_files"]
     } elseif {$gdttype eq [mc "changing lines matching:"]} {
        set gdtargs [list "-G$highlight_files"]
+    } elseif {$gdttype eq [mc "git-cherry between marked commit and:"]} {
+       # Skipping opening the file handle, filehighlight
+       return
     } else {
        # must be "containing:", i.e. we're searching commit info
        return
@@ -4882,6 +4950,17 @@ proc doesmatch {f} {
     }
 }
 
+proc askcherryhighlight {row id} {
+    global nhighlights gitcherryids
+
+    set isbold 0
+    if {[info exists gitcherryids($id)]} {
+       set isbold 1
+    }
+
+    set nhighlights($id) $isbold
+}
+
 proc askfindhighlight {row id} {
     global nhighlights commitinfo iddrawn
     global findloc
@@ -6216,6 +6295,7 @@ proc drawcmitrow {row} {
     global filehighlight fhighlights findpattern nhighlights
     global hlview vhighlights
     global highlight_related rhighlights
+    global gdttype
 
     if {$row >= $numcommits} return
 
@@ -6226,6 +6306,11 @@ proc drawcmitrow {row} {
     if {[info exists filehighlight] && ![info exists fhighlights($id)]} {
        askfilehighlight $row $id
     }
+
+    if {$gdttype eq [mc "git-cherry between marked commit and:"] && ![info 
exists nhighlights($id)]} {
+       askcherryhighlight $row $id
+    }
+
     if {$findpattern ne {} && ![info exists nhighlights($id)]} {
        askfindhighlight $row $id
     }
@@ -6776,7 +6861,9 @@ proc dofind {{dirn 1} {wrap 1}} {
     }
     set findcurline $findstartline
     nowbusy finding [mc "Searching"]
-    if {$gdttype ne [mc "containing:"] && ![info exists filehighlight]} {
+    if {$gdttype eq [mc "git-cherry between marked commit and:"]} {
+       # Don't do anything related to open do_file_hl since we'll just have a 
list
+    } elseif {$gdttype ne [mc "containing:"] && ![info exists filehighlight]} {
        after cancel do_file_hl $fh_serial
        do_file_hl $fh_serial
     }
@@ -6803,6 +6890,7 @@ proc findmore {} {
     global findstartline findcurline findallowwrap
     global find_dirn gdttype fhighlights fprogcoord
     global curview varcorder vrownum varccommits vrowmod
+    global gitcherryids
 
     if {![info exists find_dirn]} {
        return 0
@@ -6848,7 +6936,23 @@ proc findmore {} {
     set arow [lindex $vrownum($curview) $ai]
     set ids [lindex $varccommits($curview,$a)]
     set arowend [expr {$arow + [llength $ids]}]
-    if {$gdttype eq [mc "containing:"]} {
+
+    if {$gdttype eq [mc "git-cherry between marked commit and:"]} {
+       for {} {$n > 0} {incr n -1; incr l $find_dirn} {
+           if {$l < $arow || $l >= $arowend} {
+               incr ai $find_dirn
+               set a [lindex $varcorder($curview) $ai]
+               set arow [lindex $vrownum($curview) $ai]
+               set ids [lindex $varccommits($curview,$a)]
+               set arowend [expr {$arow + [llength $ids]}]
+           }
+           set id [lindex $ids [expr {$l - $arow}]]
+           if {[info exists gitcherryids($id)]} {
+               set found 1
+           }
+           if {$found} break
+       }
+    } elseif {$gdttype eq [mc "containing:"]} {
        for {} {$n > 0} {incr n -1; incr l $find_dirn} {
            if {$l < $arow || $l >= $arowend} {
                incr ai $find_dirn
-- 
2.10.2

Reply via email to