gitk: separate upstream refs when using the sort-by-type option

Since the upstream refs of local refs may be of more significance in the context of the local refs, they are sorted after local refs and before the remainder of the remote refs. Signed-off-by: Michael Rappazzo <michael.rappazzo@infor.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Michael Rappazzo committed Jul 19, 2025 at 15:24 UTC c0fb4353c20d3abefa467f8bb880fec047206f63
1 file changed +23 -5
gitk
+23 -5
@@ -1971,13 +1971,13 @@ proc longid {prefix} {
1971 }
1972
1973 proc readrefs {} {
1974 - global tagids idtags headids idheads tagobjid
1974 + global tagids idtags headids idheads tagobjid upstreamofref
1975 global otherrefids idotherrefs mainhead mainheadid
1976 global selecthead selectheadid
1977 global hideremotes
1978 global tclencoding
1979
1980 - foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
1980 + foreach v {tagids idtags headids idheads otherrefids idotherrefs upstreamofref} {
1981 unset -nocomplain $v
1982 }
1983 set refd [safe_open_command [list git show-ref -d]]
@@ -2031,6 +2031,17 @@ proc readrefs {} {
2031 set selectheadid [safe_exec [list git rev-parse --verify $selecthead]]
2032 }
2033 }
2034 + #load the local_branch->upstream mapping
2035 + # the result of the for-each-ref command produces: local_branch NUL upstream
2036 + set refd [safe_open_command [list git for-each-ref {--format=%(refname:short)%00%(upstream)} refs/heads/]]
2037 + while {[gets $refd local_tracking] >= 0} {
2038 + set line [split $local_tracking \0]
2039 + if {[lindex $line 1] ne {}} {
2040 + set upstream_ref [string map {"refs/" ""} [lindex $line 1]]
2041 + set upstreamofref([lindex $line 0]) $upstream_ref
2042 + }
2043 + }
2044 + catch {close $refd}
2045 }
2046
2047 # skip over fake commits
@@ -10308,11 +10319,12 @@ proc reflistfilter_change {n1 n2 op} {
10319
10320 proc refill_reflist {} {
10321 global reflist reflistfilter showrefstop headids tagids otherrefids sortrefsbytype
10311 - global curview
10322 + global curview upstreamofref
10323
10324 if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
10325 set localrefs {}
10326 set remoterefs {}
10327 + set trackedremoterefs {}
10328 set tagrefs {}
10329 set otherrefs {}
10330
@@ -10320,17 +10332,23 @@ proc refill_reflist {} {
10332 if {![string match "remotes/*" $n] && [string match $reflistfilter $n]} {
10333 if {[commitinview $headids($n) $curview]} {
10334 lappend localrefs [list $n H]
10335 + if {[info exists upstreamofref($n)]} {
10336 + lappend trackedremoterefs [list $upstreamofref($n) R]
10337 + }
10338 } else {
10339 interestedin $headids($n) {run refill_reflist}
10340 }
10341 }
10342 }
10343 + set trackedremoterefs [lsort -index 0 $trackedremoterefs]
10344 set localrefs [lsort -index 0 $localrefs]
10345
10346 foreach n [array names headids] {
10347 if {[string match "remotes/*" $n] && [string match $reflistfilter $n]} {
10348 if {[commitinview $headids($n) $curview]} {
10333 - lappend remoterefs [list $n R]
10349 + if {[lsearch -exact $trackedremoterefs [list $n R]] < 0} {
10350 + lappend remoterefs [list $n R]
10351 + }
10352 } else {
10353 interestedin $headids($n) {run refill_reflist}
10354 }
@@ -10360,7 +10378,7 @@ proc refill_reflist {} {
10378 }
10379 set otherrefs [lsort -index 0 $otherrefs]
10380
10363 - set refs [concat $localrefs $remoterefs $tagrefs $otherrefs]
10381 + set refs [concat $localrefs $trackedremoterefs $remoterefs $tagrefs $otherrefs]
10382 if {!$sortrefsbytype} {
10383 set refs [lsort -index 0 $refs]
10384 }