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 <pmdumuid@xxxxxxxxx> --- 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