git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 1/2] gitk: alter the ordering for the "Tags and heads" view

From
Michael Rappazzo <rappazzo@gmail.com>
Date
Mar 27, 2016, 15:06 UTC
Message-ID
<1459091168-46908-2-git-send-email-rappazzo@gmail.com>
In-Reply-To
<1459091168-46908-1-git-send-email-rappazzo@gmail.com>

In the "Tags and heads" view, the list of refs is globally sorted. Because of this, the list of local refs (heads) can be interrupted by the list of remote refs. This change re-orders the view to be: local refs, remote refs tracked by local refs, remote refs, tags, and then other refs.

Signed-off-by: Michael Rappazzo <rappazzo@gmail.com>
---
 gitk | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/gitk b/gitk
index 805a1c7..3686370 100755
--- a/gitk
+++ b/gitk
@@ -1772,12 +1772,12 @@ proc longid {prefix} {
 }
 
 proc readrefs {} {
-    global tagids idtags headids idheads tagobjid
+    global tagids idtags headids idheads tagobjid localrefs_tracking_remotes
     global otherrefids idotherrefs mainhead mainheadid
     global selecthead selectheadid
     global hideremotes
 
-    foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
+    foreach v {tagids idtags headids idheads otherrefids idotherrefs localrefs_tracking_remotes} {
 	unset -nocomplain $v
     }
     set refd [open [list | git show-ref -d] r]
@@ -1828,6 +1828,21 @@ proc readrefs {} {
 	    set selectheadid [exec git rev-parse --verify $selecthead]
 	}
     }
+    #load the local_branch->upstream mapping
+    # the result of the for-each-ref command produces the local_branch NUL upstream
+    set locals_tracking [open [list | git for-each-ref {--format=%(refname:short)%00%(upstream)} refs/heads/] r]
+    while {[gets $locals_tracking local_tracking] >= 0} {
+	set line [split $local_tracking \0]
+	if {[lindex $line 1] ne {}} {
+	    set upstream_ref [string map {"refs/" ""} [lindex $line 1]];
+	    set upstream_exists {}
+	    catch {set upstream_exists [exec git rev-parse --verify $upstream_ref]}
+	    if {$upstream_exists ne ""} {
+		set localrefs_tracking_remotes([lindex $line 0]) $upstream_ref
+	    }
+	}
+    }
+    catch {close $locals_tracking}
 }
 
 # skip over fake commits
@@ -9929,39 +9944,66 @@ proc reflistfilter_change {n1 n2 op} {
 }
 
 proc refill_reflist {} {
-    global reflist reflistfilter showrefstop headids tagids otherrefids
+    global reflist reflistfilter showrefstop headids tagids otherrefids localrefs_tracking_remotes
     global curview
 
     if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
-    set refs {}
+    set localrefs {}
+    set remoterefs {}
+    set locally_tracked_remote_refs {}
+    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]} {
-		lappend refs [list $n H]
+		lappend localrefs [list $n H]
+		if {[info exists localrefs_tracking_remotes($n)]} {
+		    lappend locally_tracked_remote_refs [list $localrefs_tracking_remotes($n) H]
+		}
 	    } else {
 		interestedin $headids($n) {run refill_reflist}
 	    }
 	}
     }
+    set locally_tracked_remote_refs [lsort -index 0 $locally_tracked_remote_refs]
+    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]} {
+		if {[lsearch -exact $locally_tracked_remote_refs [list $n H]] < 0} {
+		    lappend remoterefs [list $n H]
+		}
+	    } 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]
+    lappend refs {*}$localrefs {*}$locally_tracked_remote_refs {*}$remoterefs {*}$tagrefs {*}$otherrefs
     if {$refs eq $reflist} return
 
     # Update the contents of $showrefstop.list according to the
-- 
2.7.4
Previous: Michael RappazzoNext: Paul Mackerras
Message 2 of 5 in “gitk: changes for the "Tags and heads" view”
  1. 0/2 gitk: changes for the "Tags and heads" viewMichael Rappazzo, Mar 27, 2016
  2. 1/2 gitk: alter the ordering for the "Tags and heads" viewMichael Rappazzo, Mar 27, 2016
  3. Paul MackerrasDec 11, 2016
  4. 2/2 gitk: add an option to enable sorting the "Tags and heads" view by ref typeMichael Rappazzo, Mar 27, 2016
  5. Mike RappazzoApr 28, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.