Code

gitk: Add a way to mark a commit, plus a "find descendant" command
authorPaul Mackerras <paulus@samba.org>
Wed, 8 Apr 2009 23:34:46 +0000 (09:34 +1000)
committerPaul Mackerras <paulus@samba.org>
Wed, 8 Apr 2009 23:34:46 +0000 (09:34 +1000)
This adds a context-menu command to put a mark on this commit.  There
is at most one marked commit at any time, and it is indicated by a box
drawn around the headline.  Once a commit is marked, two other
context-menu commands become available: one to select the marked commit,
and another to find the closest common descendant of this commit and
the marked commit.

The "find common descendant" command uses the displayed parent/child
relationships (i.e. the rewritten parent pointers produced by git log),
not the real parent/child relationships.  Currently the UI will be
unresponsive while gitk is working out the nearest common descendant;
this should be improved in future.

Signed-off-by: Paul Mackerras <paulus@samba.org>
gitk

diff --git a/gitk b/gitk
index a7294a14763062a3141150681a12f6fbb60a6c1a..628f6e5c5bbcf3b074d4c9e52e0b346614ed44f5 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -2359,6 +2359,9 @@ proc makewindow {} {
        {mc "Create new branch" command mkbranch}
        {mc "Cherry-pick this commit" command cherrypick}
        {mc "Reset HEAD branch to here" command resethead}
        {mc "Create new branch" command mkbranch}
        {mc "Cherry-pick this commit" command cherrypick}
        {mc "Reset HEAD branch to here" command resethead}
+       {mc "Mark this commit" command markhere}
+       {mc "Return to mark" command gotomark}
+       {mc "Find descendant of this and mark" command find_common_desc}
     }
     $rowctxmenu configure -tearoff 0
 
     }
     $rowctxmenu configure -tearoff 0
 
@@ -4074,7 +4077,7 @@ proc ishighlighted {id} {
 }
 
 proc bolden {id font} {
 }
 
 proc bolden {id font} {
-    global canv linehtag currentid boldids need_redisplay
+    global canv linehtag currentid boldids need_redisplay markedid
 
     # need_redisplay = 1 means the display is stale and about to be redrawn
     if {$need_redisplay} return
 
     # need_redisplay = 1 means the display is stale and about to be redrawn
     if {$need_redisplay} return
@@ -4087,6 +4090,9 @@ proc bolden {id font} {
                   -fill [$canv cget -selectbackground]]
        $canv lower $t
     }
                   -fill [$canv cget -selectbackground]]
        $canv lower $t
     }
+    if {[info exists markedid] && $id eq $markedid} {
+       make_idmark $id
+    }
 }
 
 proc bolden_name {id font} {
 }
 
 proc bolden_name {id font} {
@@ -5591,7 +5597,7 @@ proc drawcmittext {id row col} {
     global cmitlisted commitinfo rowidlist parentlist
     global rowtextx idpos idtags idheads idotherrefs
     global linehtag linentag linedtag selectedline
     global cmitlisted commitinfo rowidlist parentlist
     global rowtextx idpos idtags idheads idotherrefs
     global linehtag linentag linedtag selectedline
-    global canvxmax boldids boldnameids fgcolor
+    global canvxmax boldids boldnameids fgcolor markedid
     global mainheadid nullid nullid2 circleitem circlecolors ctxbut
 
     # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right
     global mainheadid nullid nullid2 circleitem circlecolors ctxbut
 
     # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right
@@ -5673,6 +5679,9 @@ proc drawcmittext {id row col} {
     if {$selectedline == $row} {
        make_secsel $id
     }
     if {$selectedline == $row} {
        make_secsel $id
     }
+    if {[info exists markedid] && $markedid eq $id} {
+       make_idmark $id
+    }
     set xr [expr {$xt + [font measure $font $headline]}]
     if {$xr > $canvxmax} {
        set canvxmax $xr
     set xr [expr {$xt + [font measure $font $headline]}]
     if {$xr > $canvxmax} {
        set canvxmax $xr
@@ -6614,6 +6623,16 @@ proc make_secsel {id} {
     $canv3 lower $t
 }
 
     $canv3 lower $t
 }
 
+proc make_idmark {id} {
+    global linehtag canv fgcolor
+
+    if {![info exists linehtag($id)]} return
+    $canv delete markid
+    set t [eval $canv create rect [$canv bbox $linehtag($id)] \
+              -tags markid -outline $fgcolor]
+    $canv raise $t
+}
+
 proc selectline {l isnew {desired_loc {}}} {
     global canv ctext commitinfo selectedline
     global canvy0 linespc parents children curview
 proc selectline {l isnew {desired_loc {}}} {
     global canv ctext commitinfo selectedline
     global canvy0 linespc parents children curview
@@ -7999,7 +8018,7 @@ proc mstime {} {
 
 proc rowmenu {x y id} {
     global rowctxmenu selectedline rowmenuid curview
 
 proc rowmenu {x y id} {
     global rowctxmenu selectedline rowmenuid curview
-    global nullid nullid2 fakerowmenu mainhead
+    global nullid nullid2 fakerowmenu mainhead markedid
 
     stopfinding
     set rowmenuid $id
 
     stopfinding
     set rowmenuid $id
@@ -8015,6 +8034,13 @@ proc rowmenu {x y id} {
        } else {
            $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
        }
        } else {
            $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
        }
+       if {[info exists markedid] && $markedid ne $id} {
+           $menu entryconfigure 9 -state normal
+           $menu entryconfigure 10 -state normal
+       } else {
+           $menu entryconfigure 9 -state disabled
+           $menu entryconfigure 10 -state disabled
+       }
     } else {
        set menu $fakerowmenu
     }
     } else {
        set menu $fakerowmenu
     }
@@ -8024,6 +8050,59 @@ proc rowmenu {x y id} {
     tk_popup $menu $x $y
 }
 
     tk_popup $menu $x $y
 }
 
+proc markhere {} {
+    global rowmenuid markedid canv
+
+    set markedid $rowmenuid
+    make_idmark $markedid
+}
+
+proc gotomark {} {
+    global markedid
+
+    if {[info exists markedid]} {
+       selbyid $markedid
+    }
+}
+
+proc replace_by_kids {l r} {
+    global curview children
+
+    set id [commitonrow $r]
+    set l [lreplace $l 0 0]
+    foreach kid $children($curview,$id) {
+       lappend l [rowofcommit $kid]
+    }
+    return [lsort -integer -decreasing -unique $l]
+}
+
+proc find_common_desc {} {
+    global markedid rowmenuid curview children
+
+    if {![info exists markedid]} return
+    if {![commitinview $markedid $curview] ||
+       ![commitinview $rowmenuid $curview]} return
+    #set t1 [clock clicks -milliseconds]
+    set l1 [list [rowofcommit $markedid]]
+    set l2 [list [rowofcommit $rowmenuid]]
+    while 1 {
+       set r1 [lindex $l1 0]
+       set r2 [lindex $l2 0]
+       if {$r1 eq {} || $r2 eq {}} break
+       if {$r1 == $r2} {
+           selectline $r1 1
+           break
+       }
+       if {$r1 > $r2} {
+           set l1 [replace_by_kids $l1 $r1]
+       } else {
+           set l2 [replace_by_kids $l2 $r2]
+       }
+    }
+    #set t2 [clock clicks -milliseconds]
+    #puts "took [expr {$t2-$t1}]ms"
+}
+
 proc diffvssel {dirn} {
     global rowmenuid selectedline
 
 proc diffvssel {dirn} {
     global rowmenuid selectedline
 
@@ -8218,7 +8297,7 @@ proc domktag {} {
 }
 
 proc redrawtags {id} {
 }
 
 proc redrawtags {id} {
-    global canv linehtag idpos currentid curview cmitlisted
+    global canv linehtag idpos currentid curview cmitlisted markedid
     global canvxmax iddrawn circleitem mainheadid circlecolors
 
     if {![commitinview $id $curview]} return
     global canvxmax iddrawn circleitem mainheadid circlecolors
 
     if {![commitinview $id $curview]} return
@@ -8243,6 +8322,9 @@ proc redrawtags {id} {
     if {[info exists currentid] && $currentid == $id} {
        make_secsel $id
     }
     if {[info exists currentid] && $currentid == $id} {
        make_secsel $id
     }
+    if {[info exists markedid] && $markedid eq $id} {
+       make_idmark $id
+    }
 }
 
 proc mktagcan {} {
 }
 
 proc mktagcan {} {
@@ -10269,6 +10351,7 @@ proc setfg {c} {
     }
     allcanvs itemconf text -fill $c
     $canv itemconf circle -outline $c
     }
     allcanvs itemconf text -fill $c
     $canv itemconf circle -outline $c
+    $canv itemconf markid -outline $c
 }
 
 proc prefscan {} {
 }
 
 proc prefscan {} {