From aa1a3e09930012abcb3f6c41a612425e03384e4d Mon Sep 17 00:00:00 2001 From: Michael Rappazzo Date: Mon, 1 Jun 2015 11:05:25 -0400 Subject: [PATCH 1/3] gitk: sort by ref type on the 'tags and heads' view In the 'tags and heads' view, the list of refs was globally sorted, which caused the local ref list to be split around other ref list types. This change re-orders the view to be: local refs, remote refs, tags, and then other refs. Signed-off-by: Michael Rappazzo Signed-off-by: Johannes Sixt --- gitk | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/gitk b/gitk index 0df4eee733..911fa63089 100755 --- a/gitk +++ b/gitk @@ -10308,39 +10308,56 @@ proc refill_reflist {} { global curview if {![info exists showrefstop] || ![winfo exists $showrefstop]} return - set refs {} + set localrefs {} + set remoterefs {} + set tagrefs {} + set otherrefs {} + foreach n [array names headids] { - if {[string match $reflistfilter $n]} { + if {![string match "remotes/*" $n] && [string match $reflistfilter $n]} { if {[commitinview $headids($n) $curview]} { - if {[string match "remotes/*" $n]} { - lappend refs [list $n R] - } else { - lappend refs [list $n H] - } + lappend localrefs [list $n H] } else { interestedin $headids($n) {run refill_reflist} } } } + set localrefs [lsort -index 0 $localrefs] + + foreach n [array names headids] { + if {[string match "remotes/*" $n] && [string match $reflistfilter $n]} { + if {[commitinview $headids($n) $curview]} { + lappend remoterefs [list $n R] + } else { + interestedin $headids($n) {run refill_reflist} + } + } + } + set remoterefs [lsort -index 0 $remoterefs] + foreach n [array names tagids] { if {[string match $reflistfilter $n]} { if {[commitinview $tagids($n) $curview]} { - lappend refs [list $n T] + lappend tagrefs [list $n T] } else { interestedin $tagids($n) {run refill_reflist} } } } + set tagrefs [lsort -index 0 $tagrefs] + foreach n [array names otherrefids] { if {[string match $reflistfilter $n]} { if {[commitinview $otherrefids($n) $curview]} { - lappend refs [list $n o] + lappend otherrefs [list "$n" o] } else { interestedin $otherrefids($n) {run refill_reflist} } } } - set refs [lsort -index 0 $refs] + set otherrefs [lsort -index 0 $otherrefs] + set refs [concat $localrefs $remoterefs $tagrefs $otherrefs] + if {$refs eq $reflist} return # Update the contents of $showrefstop.list according to the From 9abe70db6cf916e32a4dbbb593cc361cfd67dd65 Mon Sep 17 00:00:00 2001 From: Michael Rappazzo Date: Fri, 18 Jul 2025 16:33:08 -0400 Subject: [PATCH 2/3] gitk: make 'sort-refs-by-type' optional and persistent On the 'tags and heads' view, add an option to enable or disable 'Sort refs by type'. This option is read from and written to the config file. Clicking on the option will update the refs in the view. Signed-off-by: Michael Rappazzo Signed-off-by: Johannes Sixt --- gitk | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gitk b/gitk index 911fa63089..a22b1bbfc6 100755 --- a/gitk +++ b/gitk @@ -10261,6 +10261,9 @@ proc showrefs {} { pack $top.f.e -side right -fill x -expand 1 pack $top.f.l -side left grid $top.f - -sticky ew -pady 2 + ${NS}::checkbutton $top.sort -text [mc "Sort refs by type"] \ + -variable sortrefsbytype -command {refill_reflist} + grid $top.sort - -sticky w -pady 2 ${NS}::button $top.close -command [list destroy $top] -text [mc "Close"] bind $top [list destroy $top] grid $top.close - @@ -10304,7 +10307,7 @@ proc reflistfilter_change {n1 n2 op} { } proc refill_reflist {} { - global reflist reflistfilter showrefstop headids tagids otherrefids + global reflist reflistfilter showrefstop headids tagids otherrefids sortrefsbytype global curview if {![info exists showrefstop] || ![winfo exists $showrefstop]} return @@ -10356,7 +10359,11 @@ proc refill_reflist {} { } } set otherrefs [lsort -index 0 $otherrefs] + set refs [concat $localrefs $remoterefs $tagrefs $otherrefs] + if {!$sortrefsbytype} { + set refs [lsort -index 0 $refs] + } if {$refs eq $reflist} return @@ -12618,6 +12625,7 @@ set wrapcomment "none" set wrapdefault "none" set showneartags 1 set hideremotes 0 +set sortrefsbytype 1 set maxrefs 20 set visiblerefs {"master"} set maxlinelen 200 @@ -12732,7 +12740,7 @@ set config_variables { filesepbgcolor filesepfgcolor linehoverbgcolor linehoverfgcolor linehoveroutlinecolor mainheadcirclecolor workingfilescirclecolor indexcirclecolor circlecolors linkfgcolor circleoutlinecolor diffbgcolors - web_browser + sortrefsbytype web_browser } foreach var $config_variables { config_init_trace $var From c0fb4353c20d3abefa467f8bb880fec047206f63 Mon Sep 17 00:00:00 2001 From: Michael Rappazzo Date: Sat, 19 Jul 2025 15:24:39 -0400 Subject: [PATCH 3/3] 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 Signed-off-by: Johannes Sixt --- gitk | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/gitk b/gitk index a22b1bbfc6..38c2c81a79 100755 --- a/gitk +++ b/gitk @@ -1971,13 +1971,13 @@ proc longid {prefix} { } proc readrefs {} { - global tagids idtags headids idheads tagobjid + global tagids idtags headids idheads tagobjid upstreamofref global otherrefids idotherrefs mainhead mainheadid global selecthead selectheadid global hideremotes global tclencoding - foreach v {tagids idtags headids idheads otherrefids idotherrefs} { + foreach v {tagids idtags headids idheads otherrefids idotherrefs upstreamofref} { unset -nocomplain $v } set refd [safe_open_command [list git show-ref -d]] @@ -2031,6 +2031,17 @@ proc readrefs {} { set selectheadid [safe_exec [list git rev-parse --verify $selecthead]] } } + #load the local_branch->upstream mapping + # the result of the for-each-ref command produces: local_branch NUL upstream + set refd [safe_open_command [list git for-each-ref {--format=%(refname:short)%00%(upstream)} refs/heads/]] + while {[gets $refd local_tracking] >= 0} { + set line [split $local_tracking \0] + if {[lindex $line 1] ne {}} { + set upstream_ref [string map {"refs/" ""} [lindex $line 1]] + set upstreamofref([lindex $line 0]) $upstream_ref + } + } + catch {close $refd} } # skip over fake commits @@ -10308,11 +10319,12 @@ proc reflistfilter_change {n1 n2 op} { proc refill_reflist {} { global reflist reflistfilter showrefstop headids tagids otherrefids sortrefsbytype - global curview + global curview upstreamofref if {![info exists showrefstop] || ![winfo exists $showrefstop]} return set localrefs {} set remoterefs {} + set trackedremoterefs {} set tagrefs {} set otherrefs {} @@ -10320,17 +10332,23 @@ proc refill_reflist {} { if {![string match "remotes/*" $n] && [string match $reflistfilter $n]} { if {[commitinview $headids($n) $curview]} { lappend localrefs [list $n H] + if {[info exists upstreamofref($n)]} { + lappend trackedremoterefs [list $upstreamofref($n) R] + } } else { interestedin $headids($n) {run refill_reflist} } } } + set trackedremoterefs [lsort -index 0 $trackedremoterefs] set localrefs [lsort -index 0 $localrefs] foreach n [array names headids] { if {[string match "remotes/*" $n] && [string match $reflistfilter $n]} { if {[commitinview $headids($n) $curview]} { - lappend remoterefs [list $n R] + if {[lsearch -exact $trackedremoterefs [list $n R]] < 0} { + lappend remoterefs [list $n R] + } } else { interestedin $headids($n) {run refill_reflist} } @@ -10360,7 +10378,7 @@ proc refill_reflist {} { } set otherrefs [lsort -index 0 $otherrefs] - set refs [concat $localrefs $remoterefs $tagrefs $otherrefs] + set refs [concat $localrefs $trackedremoterefs $remoterefs $tagrefs $otherrefs] if {!$sortrefsbytype} { set refs [lsort -index 0 $refs] }