1. Stefan Saasen
  2. git

Commits

Junio C Hamano  committed 39a76bd Merge

Merge git://git.kernel.org/pub/scm/gitk/gitk

* git://git.kernel.org/pub/scm/gitk/gitk:
gitk: Avoid handling the Return key twice in Add Branch
gitk: Show local changes properly when we have a path limit
gitk: Fix switch statement in parseviewargs
gitk: Index line[hnd]tag arrays by id rather than row number

  • Participants
  • Parent commits 363cfc1, 68149a7
  • Branches master

Comments (0)

Files changed (1)

File gitk-git/gitk

View file
  • Ignore whitespace
 		set origargs [lreplace $origargs $i $i]
 		incr i -1
 	    }
-	    # These request or affect diff output, which we don't want.
-	    # Some could be used to set our defaults for diff display.
 	    "-[puabwcrRBMC]" -
 	    "--no-renames" - "--full-index" - "--binary" - "--abbrev=*" -
 	    "--find-copies-harder" - "-l*" - "--ext-diff" - "--no-ext-diff" -
 	    "--src-prefix=*" - "--dst-prefix=*" - "--no-prefix" -
 	    "-O*" - "--text" - "--full-diff" - "--ignore-space-at-eol" -
 	    "--ignore-space-change" - "-U*" - "--unified=*" {
+		# These request or affect diff output, which we don't want.
+		# Some could be used to set our defaults for diff display.
 		lappend diffargs $arg
 	    }
-	    # These cause our parsing of git log's output to fail, or else
-	    # they're options we want to set ourselves, so ignore them.
 	    "--raw" - "--patch-with-raw" - "--patch-with-stat" -
 	    "--name-only" - "--name-status" - "--color" - "--color-words" -
 	    "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
 	    "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
 	    "--timestamp" - "relative-date" - "--date=*" - "--stdin" -
 	    "--objects" - "--objects-edge" - "--reverse" {
+		# These cause our parsing of git log's output to fail, or else
+		# they're options we want to set ourselves, so ignore them.
 	    }
-	    # These are harmless, and some are even useful
 	    "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
 	    "--check" - "--exit-code" - "--quiet" - "--topo-order" -
 	    "--full-history" - "--dense" - "--sparse" -
 	    "--follow" - "--left-right" - "--encoding=*" {
+		# These are harmless, and some are even useful
 		lappend glflags $arg
 	    }
-	    # These mean that we get a subset of the commits
 	    "--diff-filter=*" - "--no-merges" - "--unpacked" -
 	    "--max-count=*" - "--skip=*" - "--since=*" - "--after=*" -
 	    "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
 	    "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
 	    "--remove-empty" - "--first-parent" - "--cherry-pick" -
-	    "-S*" - "--pickaxe-all" - "--pickaxe-regex" - {
+	    "-S*" - "--pickaxe-all" - "--pickaxe-regex" {
+		# These mean that we get a subset of the commits
 		set filtered 1
 		lappend glflags $arg
 	    }
-	    # This appears to be the only one that has a value as a
-	    # separate word following it
 	    "-n" {
+		# This appears to be the only one that has a value as a
+		# separate word following it
 		set filtered 1
 		set nextisval 1
 		lappend glflags $arg
 		# git rev-parse doesn't understand --merge
 		lappend revargs --gitk-symmetric-diff-marker MERGE_HEAD...HEAD
 	    }
-	    # Other flag arguments including -<n>
 	    "-*" {
+		# Other flag arguments including -<n>
 		if {[string is digit -strict [string range $arg 1 end]]} {
 		    set filtered 1
 		} else {
 		}
 		lappend glflags $arg
 	    }
-	    # Non-flag arguments specify commits or ranges of commits
 	    default {
+		# Non-flag arguments specify commits or ranges of commits
 		if {[string match "*...*" $arg]} {
 		    lappend revargs --gitk-symmetric-diff-marker
 		}
     global viewargs viewargscmd viewfiles vfilelimit
     global showlocalchanges
     global viewactive viewinstances vmergeonly
-    global mainheadid
+    global mainheadid viewmainheadid viewmainheadid_orig
     global vcanopt vflags vrevs vorigargs
 
     set startmsecs [clock clicks -milliseconds]
     }
     set i [reg_instance $fd]
     set viewinstances($view) [list $i]
-    if {$showlocalchanges && $mainheadid ne {}} {
-	interestedin $mainheadid dodiffindex
+    set viewmainheadid($view) $mainheadid
+    set viewmainheadid_orig($view) $mainheadid
+    if {$files ne {} && $mainheadid ne {}} {
+	get_viewmainhead $view
+    }
+    if {$showlocalchanges && $viewmainheadid($view) ne {}} {
+	interestedin $viewmainheadid($view) dodiffindex
     }
     fconfigure $fd -blocking 0 -translation lf -eofchar {}
     if {$tclencoding != {}} {
     global curview vcanopt vorigargs vfilelimit viewinstances
     global viewactive viewcomplete tclencoding
     global startmsecs showneartags showlocalchanges
-    global mainheadid pending_select
+    global mainheadid viewmainheadid viewmainheadid_orig pending_select
     global isworktree
     global varcid vposids vnegids vflags vrevs
 
     set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
-    set oldmainid $mainheadid
     rereadrefs
-    if {$showlocalchanges} {
-	if {$mainheadid ne $oldmainid} {
+    set view $curview
+    if {$mainheadid ne $viewmainheadid_orig($view)} {
+	if {$showlocalchanges} {
 	    dohidelocalchanges
 	}
-	if {[commitinview $mainheadid $curview]} {
-	    dodiffindex
+	set viewmainheadid($view) $mainheadid
+	set viewmainheadid_orig($view) $mainheadid
+	if {$vfilelimit($view) ne {}} {
+	    get_viewmainhead $view
 	}
     }
-    set view $curview
+    if {$showlocalchanges} {
+	doshowlocalchanges
+    }
     if {$vcanopt($view)} {
 	set oldpos $vposids($view)
 	set oldneg $vnegids($view)
     return 0
 }
 
-proc bolden {row font} {
-    global canv linehtag selectedline boldrows need_redisplay
+proc bolden {id font} {
+    global canv linehtag currentid boldids need_redisplay
 
     # need_redisplay = 1 means the display is stale and about to be redrawn
     if {$need_redisplay} return
-    lappend boldrows $row
-    $canv itemconf $linehtag($row) -font $font
-    if {$row == $selectedline} {
+    lappend boldids $id
+    $canv itemconf $linehtag($id) -font $font
+    if {[info exists currentid] && $id eq $currentid} {
 	$canv delete secsel
-	set t [eval $canv create rect [$canv bbox $linehtag($row)] \
+	set t [eval $canv create rect [$canv bbox $linehtag($id)] \
 		   -outline {{}} -tags secsel \
 		   -fill [$canv cget -selectbackground]]
 	$canv lower $t
     }
 }
 
-proc bolden_name {row font} {
-    global canv2 linentag selectedline boldnamerows need_redisplay
+proc bolden_name {id font} {
+    global canv2 linentag currentid boldnameids need_redisplay
 
     if {$need_redisplay} return
-    lappend boldnamerows $row
-    $canv2 itemconf $linentag($row) -font $font
-    if {$row == $selectedline} {
+    lappend boldnameids $id
+    $canv2 itemconf $linentag($id) -font $font
+    if {[info exists currentid] && $id eq $currentid} {
 	$canv2 delete secsel
-	set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \
+	set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] \
 		   -outline {{}} -tags secsel \
 		   -fill [$canv2 cget -selectbackground]]
 	$canv2 lower $t
 }
 
 proc unbolden {} {
-    global boldrows
+    global boldids
 
     set stillbold {}
-    foreach row $boldrows {
-	if {![ishighlighted [commitonrow $row]]} {
-	    bolden $row mainfont
+    foreach id $boldids {
+	if {![ishighlighted $id]} {
+	    bolden $id mainfont
 	} else {
-	    lappend stillbold $row
+	    lappend stillbold $id
 	}
     }
-    set boldrows $stillbold
+    set boldids $stillbold
 }
 
 proc addvhighlight {n} {
 	    set row [rowofcommit $id]
 	    if {$r0 <= $row && $row <= $r1} {
 		if {![highlighted $row]} {
-		    bolden $row mainfontbold
+		    bolden $id mainfontbold
 		}
 		set vhighlights($id) 1
 	    }
 
     if {[commitinview $id $hlview]} {
 	if {[info exists iddrawn($id)] && ![ishighlighted $id]} {
-	    bolden $row mainfontbold
+	    bolden $id mainfontbold
 	}
 	set vhighlights($id) 1
     } else {
 }
 
 proc findcom_change args {
-    global nhighlights boldnamerows
+    global nhighlights boldnameids
     global findpattern findtype findstring gdttype
 
     stopfinding
     # delete previous highlights, if any
-    foreach row $boldnamerows {
-	bolden_name $row mainfont
+    foreach id $boldnameids {
+	bolden_name $id mainfont
     }
-    set boldnamerows {}
+    set boldnameids {}
     catch {unset nhighlights}
     unbolden
     unmarkmatches
 	set fhl_list [lrange $fhl_list [expr {$i+1}] end]
 	if {$line eq {}} continue
 	if {![commitinview $line $curview]} continue
-	set row [rowofcommit $line]
 	if {[info exists iddrawn($line)] && ![ishighlighted $line]} {
-	    bolden $row mainfontbold
+	    bolden $line mainfontbold
 	}
 	set fhighlights($line) 1
     }
     }
     if {$isbold && [info exists iddrawn($id)]} {
 	if {![ishighlighted $id]} {
-	    bolden $row mainfontbold
+	    bolden $id mainfontbold
 	    if {$isbold > 1} {
-		bolden_name $row mainfontbold
+		bolden_name $id mainfontbold
 	    }
 	}
 	if {$markingmatches} {
     if {$findloc eq [mc "All fields"] || $findloc eq [mc "Headline"]} {
 	set m [findmatches $headline]
 	if {$m ne {}} {
-	    markmatches $canv $row $headline $linehtag($row) $m \
-		[$canv itemcget $linehtag($row) -font] $row
+	    markmatches $canv $row $headline $linehtag($id) $m \
+		[$canv itemcget $linehtag($id) -font] $row
 	}
     }
     if {$findloc eq [mc "All fields"] || $findloc eq [mc "Author"]} {
 	set m [findmatches $author]
 	if {$m ne {}} {
-	    markmatches $canv2 $row $author $linentag($row) $m \
-		[$canv2 itemcget $linentag($row) -font] $row
+	    markmatches $canv2 $row $author $linentag($id) $m \
+		[$canv2 itemcget $linentag($id) -font] $row
 	}
     }
 }
     }
     if {[info exists iddrawn($id)]} {
 	if {$isbold && ![ishighlighted $id]} {
-	    bolden $row mainfontbold
+	    bolden $id mainfontbold
 	}
     }
     set rhighlights($id) $isbold
     drawvisible
 }
 
+# With path limiting, we mightn't get the actual HEAD commit,
+# so ask git rev-list what is the first ancestor of HEAD that
+# touches a file in the path limit.
+proc get_viewmainhead {view} {
+    global viewmainheadid vfilelimit viewinstances mainheadid
+
+    catch {
+	set rfd [open [concat | git rev-list -1 $mainheadid \
+			   -- $vfilelimit($view)] r]
+	set j [reg_instance $rfd]
+	lappend viewinstances($view) $j
+	fconfigure $rfd -blocking 0
+	filerun $rfd [list getviewhead $rfd $j $view]
+	set viewmainheadid($curview) {}
+    }
+}
+
+# git rev-list should give us just 1 line to use as viewmainheadid($view)
+proc getviewhead {fd inst view} {
+    global viewmainheadid commfd curview viewinstances showlocalchanges
+
+    set id {}
+    if {[gets $fd line] < 0} {
+	if {![eof $fd]} {
+	    return 1
+	}
+    } elseif {[string length $line] == 40 && [string is xdigit $line]} {
+	set id $line
+    }
+    set viewmainheadid($view) $id
+    close $fd
+    unset commfd($inst)
+    set i [lsearch -exact $viewinstances($view) $inst]
+    if {$i >= 0} {
+	set viewinstances($view) [lreplace $viewinstances($view) $i $i]
+    }
+    if {$showlocalchanges && $id ne {} && $view == $curview} {
+	doshowlocalchanges
+    }
+    return 0
+}
+
 proc doshowlocalchanges {} {
-    global curview mainheadid
+    global curview viewmainheadid
 
-    if {$mainheadid eq {}} return
-    if {[commitinview $mainheadid $curview]} {
+    if {$viewmainheadid($curview) eq {}} return
+    if {[commitinview $viewmainheadid($curview) $curview]} {
 	dodiffindex
     } else {
-	interestedin $mainheadid dodiffindex
+	interestedin $viewmainheadid($curview) dodiffindex
     }
 }
 
 
 # spawn off a process to do git diff-index --cached HEAD
 proc dodiffindex {} {
-    global lserial showlocalchanges
+    global lserial showlocalchanges vfilelimit curview
     global isworktree
 
     if {!$showlocalchanges || !$isworktree} return
     incr lserial
-    set fd [open "|git diff-index --cached HEAD" r]
+    set cmd "|git diff-index --cached HEAD"
+    if {$vfilelimit($curview) ne {}} {
+	set cmd [concat $cmd -- $vfilelimit($curview)]
+    }
+    set fd [open $cmd r]
     fconfigure $fd -blocking 0
     set i [reg_instance $fd]
     filerun $fd [list readdiffindex $fd $lserial $i]
 }
 
 proc readdiffindex {fd serial inst} {
-    global mainheadid nullid nullid2 curview commitinfo commitdata lserial
+    global viewmainheadid nullid nullid2 curview commitinfo commitdata lserial
+    global vfilelimit
 
     set isdiff 1
     if {[gets $fd line] < 0} {
     }
 
     # now see if there are any local changes not checked in to the index
-    set fd [open "|git diff-files" r]
+    set cmd "|git diff-files"
+    if {$vfilelimit($curview) ne {}} {
+	set cmd [concat $cmd -- $vfilelimit($curview)]
+    }
+    set fd [open $cmd r]
     fconfigure $fd -blocking 0
     set i [reg_instance $fd]
     filerun $fd [list readdifffiles $fd $serial $i]
 	if {[commitinview $nullid $curview]} {
 	    removefakerow $nullid
 	}
-	insertfakerow $nullid2 $mainheadid
+	insertfakerow $nullid2 $viewmainheadid($curview)
     } elseif {!$isdiff && [commitinview $nullid2 $curview]} {
+	if {[commitinview $nullid $curview]} {
+	    removefakerow $nullid
+	}
 	removefakerow $nullid2
     }
     return 0
 }
 
 proc readdifffiles {fd serial inst} {
-    global mainheadid nullid nullid2 curview
+    global viewmainheadid nullid nullid2 curview
     global commitinfo commitdata lserial
 
     set isdiff 1
 	if {[commitinview $nullid2 $curview]} {
 	    set p $nullid2
 	} else {
-	    set p $mainheadid
+	    set p $viewmainheadid($curview)
 	}
 	insertfakerow $nullid $p
     } elseif {!$isdiff && [commitinview $nullid $curview]} {
     global cmitlisted commitinfo rowidlist parentlist
     global rowtextx idpos idtags idheads idotherrefs
     global linehtag linentag linedtag selectedline
-    global canvxmax boldrows boldnamerows fgcolor
+    global canvxmax boldids boldnameids fgcolor
     global mainheadid nullid nullid2 circleitem circlecolors ctxbut
 
     # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right
     set nfont mainfont
     set isbold [ishighlighted $id]
     if {$isbold > 0} {
-	lappend boldrows $row
+	lappend boldids $id
 	set font mainfontbold
 	if {$isbold > 1} {
-	    lappend boldnamerows $row
+	    lappend boldnameids $id
 	    set nfont mainfontbold
 	}
     }
-    set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
-			    -text $headline -font $font -tags text]
-    $canv bind $linehtag($row) $ctxbut "rowmenu %X %Y $id"
-    set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
-			    -text $name -font $nfont -tags text]
-    set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
-			    -text $date -font mainfont -tags text]
+    set linehtag($id) [$canv create text $xt $y -anchor w -fill $fgcolor \
+			   -text $headline -font $font -tags text]
+    $canv bind $linehtag($id) $ctxbut "rowmenu %X %Y $id"
+    set linentag($id) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
+			   -text $name -font $nfont -tags text]
+    set linedtag($id) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
+			   -text $date -font mainfont -tags text]
     if {$selectedline == $row} {
-	make_secsel $row
+	make_secsel $id
     }
     set xr [expr {$xt + [font measure $font $headline]}]
     if {$xr > $canvxmax} {
 proc clear_display {} {
     global iddrawn linesegs need_redisplay nrows_drawn
     global vhighlights fhighlights nhighlights rhighlights
-    global linehtag linentag linedtag boldrows boldnamerows
+    global linehtag linentag linedtag boldids boldnameids
 
     allcanvs delete all
     catch {unset iddrawn}
     catch {unset linehtag}
     catch {unset linentag}
     catch {unset linedtag}
-    set boldrows {}
-    set boldnamerows {}
+    set boldids {}
+    set boldnameids {}
     catch {unset vhighlights}
     catch {unset fhighlights}
     catch {unset nhighlights}
     }
 }
 
-proc make_secsel {l} {
+proc make_secsel {id} {
     global linehtag linentag linedtag canv canv2 canv3
 
-    if {![info exists linehtag($l)]} return
+    if {![info exists linehtag($id)]} return
     $canv delete secsel
-    set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
+    set t [eval $canv create rect [$canv bbox $linehtag($id)] -outline {{}} \
 	       -tags secsel -fill [$canv cget -selectbackground]]
     $canv lower $t
     $canv2 delete secsel
-    set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
+    set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] -outline {{}} \
 	       -tags secsel -fill [$canv2 cget -selectbackground]]
     $canv2 lower $t
     $canv3 delete secsel
-    set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
+    set t [eval $canv3 create rect [$canv3 bbox $linedtag($id)] -outline {{}} \
 	       -tags secsel -fill [$canv3 cget -selectbackground]]
     $canv3 lower $t
 }
 	drawvisible
     }
 
-    make_secsel $l
+    make_secsel $id
 
     if {$isnew} {
 	addtohistory [list selbyid $id]
     $canv itemconf $circleitem($row) -fill $ofill
     $canv delete tag.$id
     set xt [eval drawtags $id $idpos($id)]
-    $canv coords $linehtag($row) $xt [lindex $idpos($id) 2]
-    set text [$canv itemcget $linehtag($row) -text]
-    set font [$canv itemcget $linehtag($row) -font]
+    $canv coords $linehtag($id) $xt [lindex $idpos($id) 2]
+    set text [$canv itemcget $linehtag($id) -text]
+    set font [$canv itemcget $linehtag($id) -font]
     set xr [expr {$xt + [font measure $font $text]}]
     if {$xr > $canvxmax} {
 	set canvxmax $xr
 	setcanvscroll
     }
     if {[info exists currentid] && $currentid == $id} {
-	make_secsel $row
+	make_secsel $id
     }
 }
 
     grid $top.id $top.sha1 -sticky w
     label $top.nlab -text [mc "Name:"]
     entry $top.name -width 40
-    bind $top.name <Key-Return> "[list mkbrgo $top]"
     grid $top.nlab $top.name -sticky w
     frame $top.buts
     button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top]
     }
     addnewchild $newhead $oldhead
     if {[commitinview $oldhead $curview]} {
+	# XXX this isn't right if we have a path limit...
 	insertrow $newhead $oldhead $curview
 	if {$mainhead ne {}} {
 	    movehead $newhead $mainhead
 
 proc cobranch {} {
     global headmenuid headmenuhead headids
-    global showlocalchanges mainheadid
+    global showlocalchanges
 
     # check the tree is clean first??
     nowbusy checkout [mc "Checking out"]
 
 proc readcheckoutstat {fd newhead newheadid} {
     global mainhead mainheadid headids showlocalchanges progresscoords
+    global viewmainheadid curview
 
     if {[gets $fd line] >= 0} {
 	if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
     set oldmainid $mainheadid
     set mainhead $newhead
     set mainheadid $newheadid
+    set viewmainheadid($curview) $newheadid
     redrawtags $oldmainid
     redrawtags $newheadid
     selbyid $newheadid
 set highlight_paths {}
 set findpattern {}
 set searchdirn -forwards
-set boldrows {}
-set boldnamerows {}
+set boldids {}
+set boldnameids {}
 set diffelide {0 0}
 set markingmatches 0
 set linkentercount 0