@@ -309,7 +309,7 @@ proc start_rev_list {view} {
309309 global viewargs viewargscmd viewfiles vfilelimit
310310 global showlocalchanges
311311 global viewactive viewinstances vmergeonly
312- global mainheadid
312+ global mainheadid viewmainheadid viewmainheadid_orig
313313 global vcanopt vflags vrevs vorigargs
314314
315315 set startmsecs [clock clicks -milliseconds]
@@ -367,8 +367,13 @@ proc start_rev_list {view} {
367367 }
368368 set i [reg_instance $fd ]
369369 set viewinstances($view ) [list $i ]
370- if {$showlocalchanges && $mainheadid ne {}} {
371- interestedin $mainheadid dodiffindex
370+ set viewmainheadid($view ) $mainheadid
371+ set viewmainheadid_orig($view ) $mainheadid
372+ if {$files ne {} && $mainheadid ne {}} {
373+ get_viewmainhead $view
374+ }
375+ if {$showlocalchanges && $viewmainheadid($view) ne {}} {
376+ interestedin $viewmainheadid($view) dodiffindex
372377 }
373378 fconfigure $fd -blocking 0 -translation lf -eofchar {}
374379 if {$tclencoding != {}} {
@@ -446,22 +451,26 @@ proc updatecommits {} {
446451 global curview vcanopt vorigargs vfilelimit viewinstances
447452 global viewactive viewcomplete tclencoding
448453 global startmsecs showneartags showlocalchanges
449- global mainheadid pending_select
454+ global mainheadid viewmainheadid viewmainheadid_orig pending_select
450455 global isworktree
451456 global varcid vposids vnegids vflags vrevs
452457
453458 set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == " true" }]
454- set oldmainid $mainheadid
455459 rereadrefs
456- if {$showlocalchanges } {
457- if {$mainheadid ne $oldmainid } {
460+ set view $curview
461+ if {$mainheadid ne $viewmainheadid_orig($view) } {
462+ if {$showlocalchanges } {
458463 dohidelocalchanges
459464 }
460- if {[commitinview $mainheadid $curview ]} {
461- dodiffindex
465+ set viewmainheadid($view ) $mainheadid
466+ set viewmainheadid_orig($view ) $mainheadid
467+ if {$vfilelimit($view) ne {}} {
468+ get_viewmainhead $view
462469 }
463470 }
464- set view $curview
471+ if {$showlocalchanges } {
472+ doshowlocalchanges
473+ }
465474 if {$vcanopt($view) } {
466475 set oldpos $vposids($view)
467476 set oldneg $vnegids($view)
@@ -4643,14 +4652,56 @@ proc layoutmore {} {
46434652 drawvisible
46444653}
46454654
4655+ # With path limiting, we mightn't get the actual HEAD commit,
4656+ # so ask git rev-list what is the first ancestor of HEAD that
4657+ # touches a file in the path limit.
4658+ proc get_viewmainhead {view} {
4659+ global viewmainheadid vfilelimit viewinstances mainheadid
4660+
4661+ catch {
4662+ set rfd [open [concat | git rev-list -1 $mainheadid \
4663+ -- $vfilelimit($view) ] r]
4664+ set j [reg_instance $rfd ]
4665+ lappend viewinstances($view ) $j
4666+ fconfigure $rfd -blocking 0
4667+ filerun $rfd [list getviewhead $rfd $j $view ]
4668+ set viewmainheadid($curview ) {}
4669+ }
4670+ }
4671+
4672+ # git rev-list should give us just 1 line to use as viewmainheadid($view)
4673+ proc getviewhead {fd inst view} {
4674+ global viewmainheadid commfd curview viewinstances showlocalchanges
4675+
4676+ set id {}
4677+ if {[gets $fd line] < 0} {
4678+ if {![eof $fd ]} {
4679+ return 1
4680+ }
4681+ } elseif {[string length $line ] == 40 && [string is xdigit $line ]} {
4682+ set id $line
4683+ }
4684+ set viewmainheadid($view ) $id
4685+ close $fd
4686+ unset commfd($inst )
4687+ set i [lsearch -exact $viewinstances($view) $inst ]
4688+ if {$i >= 0} {
4689+ set viewinstances($view ) [lreplace $viewinstances($view) $i $i ]
4690+ }
4691+ if {$showlocalchanges && $id ne {} && $view == $curview } {
4692+ doshowlocalchanges
4693+ }
4694+ return 0
4695+ }
4696+
46464697proc doshowlocalchanges {} {
4647- global curview mainheadid
4698+ global curview viewmainheadid
46484699
4649- if {$mainheadid eq {}} return
4650- if {[commitinview $mainheadid $curview ]} {
4700+ if {$viewmainheadid($curview) eq {}} return
4701+ if {[commitinview $viewmainheadid($curview) $curview ]} {
46514702 dodiffindex
46524703 } else {
4653- interestedin $mainheadid dodiffindex
4704+ interestedin $viewmainheadid($curview) dodiffindex
46544705 }
46554706}
46564707
@@ -4668,19 +4719,24 @@ proc dohidelocalchanges {} {
46684719
46694720# spawn off a process to do git diff-index --cached HEAD
46704721proc dodiffindex {} {
4671- global lserial showlocalchanges
4722+ global lserial showlocalchanges vfilelimit curview
46724723 global isworktree
46734724
46744725 if {!$showlocalchanges || !$isworktree } return
46754726 incr lserial
4676- set fd [open " |git diff-index --cached HEAD" r]
4727+ set cmd " |git diff-index --cached HEAD"
4728+ if {$vfilelimit($curview) ne {}} {
4729+ set cmd [concat $cmd -- $vfilelimit($curview) ]
4730+ }
4731+ set fd [open $cmd r]
46774732 fconfigure $fd -blocking 0
46784733 set i [reg_instance $fd ]
46794734 filerun $fd [list readdiffindex $fd $lserial $i ]
46804735}
46814736
46824737proc readdiffindex {fd serial inst} {
4683- global mainheadid nullid nullid2 curview commitinfo commitdata lserial
4738+ global viewmainheadid nullid nullid2 curview commitinfo commitdata lserial
4739+ global vfilelimit
46844740
46854741 set isdiff 1
46864742 if {[gets $fd line] < 0} {
@@ -4697,7 +4753,11 @@ proc readdiffindex {fd serial inst} {
46974753 }
46984754
46994755 # now see if there are any local changes not checked in to the index
4700- set fd [open " |git diff-files" r]
4756+ set cmd " |git diff-files"
4757+ if {$vfilelimit($curview) ne {}} {
4758+ set cmd [concat $cmd -- $vfilelimit($curview) ]
4759+ }
4760+ set fd [open $cmd r]
47014761 fconfigure $fd -blocking 0
47024762 set i [reg_instance $fd ]
47034763 filerun $fd [list readdifffiles $fd $serial $i ]
@@ -4710,15 +4770,18 @@ proc readdiffindex {fd serial inst} {
47104770 if {[commitinview $nullid $curview ]} {
47114771 removefakerow $nullid
47124772 }
4713- insertfakerow $nullid2 $mainheadid
4773+ insertfakerow $nullid2 $viewmainheadid($curview)
47144774 } elseif {!$isdiff && [commitinview $nullid2 $curview ]} {
4775+ if {[commitinview $nullid $curview ]} {
4776+ removefakerow $nullid
4777+ }
47154778 removefakerow $nullid2
47164779 }
47174780 return 0
47184781}
47194782
47204783proc readdifffiles {fd serial inst} {
4721- global mainheadid nullid nullid2 curview
4784+ global viewmainheadid nullid nullid2 curview
47224785 global commitinfo commitdata lserial
47234786
47244787 set isdiff 1
@@ -4743,7 +4806,7 @@ proc readdifffiles {fd serial inst} {
47434806 if {[commitinview $nullid2 $curview ]} {
47444807 set p $nullid2
47454808 } else {
4746- set p $mainheadid
4809+ set p $viewmainheadid($curview)
47474810 }
47484811 insertfakerow $nullid $p
47494812 } elseif {!$isdiff && [commitinview $nullid $curview ]} {
@@ -8341,6 +8404,7 @@ proc cherrypick {} {
83418404 }
83428405 addnewchild $newhead $oldhead
83438406 if {[commitinview $oldhead $curview ]} {
8407+ # XXX this isn't right if we have a path limit...
83448408 insertrow $newhead $oldhead $curview
83458409 if {$mainhead ne {}} {
83468410 movehead $newhead $mainhead
@@ -8448,7 +8512,7 @@ proc headmenu {x y id head} {
84488512
84498513proc cobranch {} {
84508514 global headmenuid headmenuhead headids
8451- global showlocalchanges mainheadid
8515+ global showlocalchanges
84528516
84538517 # check the tree is clean first??
84548518 nowbusy checkout [mc " Checking out" ]
@@ -8469,6 +8533,7 @@ proc cobranch {} {
84698533
84708534proc readcheckoutstat {fd newhead newheadid} {
84718535 global mainhead mainheadid headids showlocalchanges progresscoords
8536+ global viewmainheadid curview
84728537
84738538 if {[gets $fd line] >= 0} {
84748539 if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
@@ -8486,6 +8551,7 @@ proc readcheckoutstat {fd newhead newheadid} {
84868551 set oldmainid $mainheadid
84878552 set mainhead $newhead
84888553 set mainheadid $newheadid
8554+ set viewmainheadid($curview ) $newheadid
84898555 redrawtags $oldmainid
84908556 redrawtags $newheadid
84918557 selbyid $newheadid
0 commit comments